<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Jinay Patel on Medium]]></title>
        <description><![CDATA[Stories by Jinay Patel on Medium]]></description>
        <link>https://medium.com/@jinayunity22?source=rss-cb7fc161d364------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*kd2dfMaoc37dhne4WkA1vQ.png</url>
            <title>Stories by Jinay Patel on Medium</title>
            <link>https://medium.com/@jinayunity22?source=rss-cb7fc161d364------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 09 Apr 2026 11:16:22 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jinayunity22/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[How I Made my Own Programming Language — Verbosity]]></title>
            <link>https://medium.com/@jinayunity22/how-i-made-my-own-programming-language-verbosity-a567143fe4ef?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/a567143fe4ef</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[cpp]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[compilers]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Fri, 03 Apr 2026 00:05:00 GMT</pubDate>
            <atom:updated>2026-04-03T00:30:48.775Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ClynoSpVrvJQVjUJ8thC6g.png" /><figcaption>An abstract syntax tree of some code.</figcaption></figure><h3>How I Made my Own Programming Language — Verbosity</h3><p>An explanation of how my compiler compiles my own programming into C++.</p><p>If you’d like to follow along with the code then you can access it <a href="https://github.com/Github11200/Verbosity">here</a>.</p><h3>The Grammar</h3><p>My initial goal was to create a programming language that contained no characters like &lt;, &gt;, “, (, and other punctuation marks. This meant all these characters had to be replaced with words (making the language verbose and hence the name verbosity).</p><p>To start, I created a basic informal grammar for the language shown below:</p><pre>=========================<br>        Variables<br>=========================<br><br>let [name] of type [type] be [expression]<br><br><br>=========================<br>        Functions<br>=========================<br><br>define doSomething with [parameter name] of type [type] gives back [type] as<br>  give [expression] back<br>end<br><br>call doSomething stop<br><br><br>=========================<br>       Conditionals<br>=========================<br><br>if [inequality expression] then<br>  [code]<br>otherwise if [inequality expression] then<br>  [code]<br>otherwise<br>  [code]<br>end<br><br>=========================<br>          Loops<br>=========================<br><br>for [identifier name] [inequality expression] repeat<br>end</pre><p>With this basic grammar in place, I knew what I wanted the language to look like and I could move onto coding the actual compiler.</p><h3>The Lexer</h3><p>To do anything useful with the input code I need to first understand what each word in the input file means.</p><p>To do this, I first split up all the tokens based on certain delimiters like spaces and other keywords which signify the end of a statement or the start of a new code block.</p><p>With the input file split up into chunks, I could now go through and assign a TokenType to each string. Since I wanted to keep both the TokenType (which is an Enum with all the different types of elements) and string I created the following Token class:</p><pre>class Token {<br>public:<br>  TokenType tokenType;<br>  std::string tokenString;<br><br>  Token(const TokenType tokenType, std::string tokenString) : tokenType(tokenType), tokenString(std::move(tokenString)) {}<br>};</pre><p>With this place, I simply looped through all string that was split up and assigned a token type to everything. For instance, if I see the word “let” then I would use the following code to assign a type to it:</p><pre>token.tokenType = TokenType::LET;</pre><p>Doing this all the different strings then allows the program to easily parse what everything means in the file rather than just seeing if certain strings equal something else which can be very error prone.</p><h3>Constructing the Abstract Syntax Tree (AST)</h3><p>Now, the program knows that certain tokens exist everywhere, but it still can’t make sense of them. For instance, take the following arithmetic expression:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/894/1*M1FteYLO2RcNr4flmxKNmg.png" /></figure><p>So far the program knows what each part of this expression is:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UWsz7QitHx5pl4LDCN53Og.png" /></figure><p>However, it doesn’t know how to make sense of these tokens as there’s no structure to them. They’re just a list of strings and enums.</p><p>To give these tokens structure, we can create an Abstract Syntax Tree (AST). For an expression like 2 + 3, it could look like the image below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EqtHu699XXb9flBM3Iu7tw.png" /></figure><p>A great website that shows the ASTs that existing programming languages create is <a href="https://astexplorer.net/">https://astexplorer.net/</a>.</p><p>To create this tree, I started by creating a function called constructAST which would be called recursively every time I had to process another code block. Inside this function, I essentially check for the start of variable statements, function statements, if statements, etc.</p><p>This is done by simply checking what the current token is. For instance, if the token type is LET then it means it is the start of a variable statement which was defined in the grammar previously.</p><p>Let’s say the function finds a function statement as shown below by seeing that there’s a DEFINE keyword:</p><pre>define doSomething gives back integer as<br>  let x of type integer be 5 stop<br>  give x back<br>end</pre><p>The first thing it will do is extract the statement using a function called incrementToKeyword . The reason it’s given this name is because I have the function increment to the as keyword as that is the end of the statement and also the start of the actual code block inside the function. This means the code above gets split up as shown below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/991/1*ohiiQX1-XyS3OZf2LMi0pg.png" /></figure><p>The yellow box represents the statement, and the green box represents the code block. Now, to process the code block, all I have to do is recursively call constructAST and it’ll keep applying the same process and will return nodes for variables, if statements, etc.</p><p>This process of extracting the statement, and then processing the code block is essentially repeated for all the different types of statements that could exist like return statements, print statements, variable statements, etc.</p><p>Now, the last major part of constructing the AST was dealing with numerical expressions like 5 + 6 / 3. The way I did this was by using a technique called Pratt Parsing from this amazing <a href="https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html">article</a>. I also added support for inequalities by simply splitting the expression wherever the inequality sign was and evaluating both sides as shown in the code below:</p><pre>optional&lt;int&gt; inequalityIndex = isInequality(statement);<br>if (inequalityIndex.has_value()) {<br>  vector&lt;Token&gt; leftArray, rightArray;<br><br>  // Split the two sides of the inequality into their own arrays<br>  for (int j = 0; j &lt; inequalityIndex.value(); ++j)<br>    leftArray.push_back(statement[j]);<br>  for (int j = inequalityIndex.value() + 1; j &lt; statement.size(); ++j)<br>    rightArray.push_back(statement[j]);<br><br>  // Parse both sides<br>  int iCopy = i;<br>  variant&lt;TYPES&gt; left = evaluateExpression(leftArray, iCopy, 0);<br>  iCopy = i;<br>  variant&lt;TYPES&gt; right = evaluateExpression(rightArray, iCopy, 0);<br><br>  return BinaryExpression(statement[inequalityIndex.value()].tokenType, left, right);<br>}</pre><p>Once the constructAST function is done running it should create a tree like the one below for the following statement, let a of type integer be 5 plus 10 divide 2 stop:</p><pre>Variable Statement<br>|<br>|__ Identifier - &quot;a&quot;<br>|<br>|__ Variable type - Integer<br>|<br>|__ Value - Binary Expression<br>    |<br>    |__ Operator - Plus<br>    |<br>    |__ Left - Integer literal<br>        |<br>        |___ Value - 5<br>    |<br>    |__ Right - Binary Expression<br>        |<br>        |__ Operator - Divide<br>        |<br>        |__ Left - Integer Literal<br>            |<br>            |__ Value - 10<br>        |<br>        |__ Right - Integer Literal<br>            |<br>            |__ Value - 2</pre><p>You can see how this tree represents how the code is structure in a fairly recursive format as there’s binary expressions inside binary expressions.</p><h3>Code Generation</h3><p>Once the constructAST function is done running it returns a pointer to the Root node shown below:</p><pre>struct Root final : ASTNode {<br>  std::vector&lt;std::shared_ptr&lt;ASTNode&gt;&gt; nodes;<br><br>  std::string generateCode() override;<br>};</pre><p>All this node has is an array of other nodes, so all we have to do is simply loop through all of them and call generateCode . It doesn’t matter whether some specific node is a variable, function, if statement, etc, they are all derived from the abstract class ASTNode and thus have a method of generateCode (OOP is so cool 😀).</p><p>The core of the code for the code generation is shown below:</p><pre>for (Root *pointer = rootNode.get(); const auto &amp;node : pointer-&gt;nodes) {<br>  if (FunctionStatement *functionStatement = dynamic_cast&lt;FunctionStatement *&gt;(node.get()))<br>    functionCode += node-&gt;generateCode();<br>  else<br>    currentCode += node-&gt;generateCode();<br>}</pre><p>The reason I check for a function statement separately is because it has to be appended to a separate string since all the functions the user has been defined can’t put inside the main function in a C++ program.</p><p>Once the code is generated all that’s left is to write to a compiled.cpp file and boom the program is compiled!</p><h3>Conclusion</h3><p>Just like that, I can now compile my own programming language!</p><p>Now one thing to note is that I didn’t create methods like peek or consume to process tokens while constructing the AST. Typically, these are used to just look ahead by one index, or take the value of the next token and increment the index. However, I chose to just use raw indexes with arrays due to how I was processing the individual statements, but this isn’t really the standard way of doing it.</p><p>Other than that, if you have any questions, feedback, or other thoughts then please feel free to contact me!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a567143fe4ef" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Citrus — Tetris Written in C]]></title>
            <link>https://medium.com/@jinayunity22/creating-citrus-tetris-written-in-c-83df91a89103?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/83df91a89103</guid>
            <category><![CDATA[cli]]></category>
            <category><![CDATA[terminal]]></category>
            <category><![CDATA[c-programming-language]]></category>
            <category><![CDATA[tetris]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Mon, 21 Apr 2025 21:48:45 GMT</pubDate>
            <atom:updated>2025-04-21T21:59:28.684Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/721/1*ql7kMvUAwiNt4AdLLYxRsQ.png" /><figcaption>A little screenshot of the game.</figcaption></figure><h3>Creating Citrus🍋 — Tetris Written in C</h3><p>My short little journey of creating Tetris in the terminal using C and its standard library.</p><p>Here’s the <a href="https://github.com/Github11200/Citrus">GitHub</a> repository in case you want to try playing it or check out the code!</p><h3>A little primer on Citrus</h3><p>It’s really just a clone of Tetris that I made in the terminal using just C and its standard library. It’s got the barebone features of Tetris such as making a piece fall faster, moving it left or right, and rotating it. It’ll also destroy lines when they span the entire width of the playing grid.</p><h3>Why did I make it?</h3><p>I had nothing else to do in my Computer Programming class, so I was like, “well, making Tetris can’t be that bad, right?” I also wanted to just try making a project in C because I’ve always used C++ and only made stuff for robotics.</p><h3>The Process</h3><p>I knew the following things when I started:</p><ul><li>I wanted to make it in C</li><li>It had to run in the terminal</li><li>I can only use the standard library, so things like printf()</li></ul><p>Why did I put these constraints on myself? It’s pretty straightforward, web development got pretty annoying cause it was always like taking one library, taking another library, and smashing them both together. This is not always the case, but because I never went deep into working on the tooling itself (at least for now), like Deno or Hono, it got kind of annoying.</p><p>Now all I had to do was figure out how to print squares to the terminal.</p><p>It’s pretty simple, though, trust me:</p><ol><li>You create an empty string and just add \033[</li><li>After this you have a giant table to choose what you want your text to look like. You can find the table in this <a href="https://stackoverflow.com/questions/4842424/list-of-ansi-color-escape-sequences">Stack Overflow post</a> (big thank you to Richard for writing this post🙏).</li><li>You use this random character that I never knew existed, ▀, to create a perfect square because otherwise if you use any other character, it’ll be a rectangle. Quite unfortunate.</li><li>Then you put two of these things, ▀, together, and you get half a square, ▀▀.</li><li>To make it a full square, you set the foreground color, which changes the color of the square, and then the background color, which changes the color beneath the square. If they’re the same color, then you get a full square! It’s a little bit of a hack, but it works.</li></ol><p>To make my life easier, I made a few little preprocessor directives (kind of like a variable but not quite) to hold the different colors:</p><pre>#define DARK_BLUE &quot;\033[38;5;19;48;5;19m▀▀\033[0m&quot;<br>#define LIGHT_BLUE &quot;\033[38;5;14;48;5;14m▀▀\033[0m&quot;<br>#define ORANGE &quot;\033[38;5;208;48;5;208m▀▀\033[0m&quot;<br>#define PURPLE &quot;\033[38;5;57;48;5;57m▀▀\033[0m&quot;<br>#define YELLOW &quot;\033[38;5;226;48;5;226m▀▀\033[0m&quot;<br>#define RED &quot;\033[38;5;9;48;5;9m▀▀\033[0m&quot;<br>#define GREEN &quot;\033[38;5;82;48;5;82m▀▀\033[0m&quot;<br>#define WHITE &quot;\033[38;5;15;48;5;15m▀▀\033[0m&quot;</pre><p>Then I created a few abstractions and got the pieces printed to the screen.</p><p>To create the grid, I just had a function that kept on printing the grid out. Then, to create new pieces, there were functions to get the coordinates on the grid on which I have to add the piece and one to actually modify the grid (represented as a 2d array).</p><p>The rest of the code to get the pieces falling and all of that was pretty simple as well as I just used some of the abstractions I had created.</p><p>I only had to refactor the code like, seven times. Not that bad.</p><p>To get the input, I just simply created one thread that would detect for key presses and another that is constantly displaying the updated grid. There is a noticeable amount of lag because the two threads are updating the variables at the same time, and honestly, I didn’t really know how to fix this.</p><p>If anyone reading this article as any ideas, then feel free to put it down in the comments, I’d love to know!</p><h3>Other Random Stuff</h3><p><strong>Why did I choose C over C++?</strong></p><p>My hypothesis was that OOP is bad because I have to spend more time on creating the classes and all of that. My conclusion, it’s pretty bad.</p><p><strong>Why is everything in one file?</strong></p><p>This was just another one of those, “hmm, it can be that bad right?” moments. It’s also just a pretty small project, so I didn’t really see any point in having to split up the files.</p><p><strong>Why is it laggy?</strong></p><p>There are two threads, one for input and one for displaying. Additionally, they’re both writing to the data at the same time, so if you do something like hold the right arrow, then it’ll keep moving the piece even when you let go. If you have any ideas on how to fix this, please let me know!</p><p><strong>Why is it called Citrus?</strong></p><p>Tetris → Cetris → Citrus</p><p>Anyways, I hope you enjoyed reading this, feel free to comment your thoughts on the article, the writing, the game, or anything else down below!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=83df91a89103" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Range Queries, visualized (Part 3: Segment Trees)]]></title>
            <link>https://medium.com/@jinayunity22/range-queries-visualized-part-3-segment-trees-a8f0035d909a?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/a8f0035d909a</guid>
            <category><![CDATA[data-structures]]></category>
            <category><![CDATA[segment-tree]]></category>
            <category><![CDATA[range-query]]></category>
            <category><![CDATA[algorithms]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Fri, 30 Aug 2024 01:35:40 GMT</pubDate>
            <atom:updated>2024-08-30T01:35:40.713Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>Hello 🙋‍♂️, if you’re new here then welcome!</p><p>If you haven’t checked out my previous two articles on <a href="https://substack.com/home/post/p-148024599?source=queue">Static Queries</a> and <a href="https://substack.com/home/post/p-148249133?source=queue">Binary Indexed Trees</a> then I’d suggest you do so since they cover what Range Queries are and we’ll be making some comparisons to them as well</p><p>Anyways, time for the fun part, Segment Trees :)</p><h3>What are Segment Trees?</h3><p>Binary Indexed Trees were cool, but it only did sum queries :(</p><p>Segment Trees are meant to be able to do minimum, maximum, and sum queries which is pretty awesome</p><p>It also works in O(log n) time for queries and updating the array in between these queries just like Binary Indexed Trees</p><p>The downside though is it’ll require more memory, and it’s a little bit harder to implement</p><p>For me personally, while it is harder to implement, I found it much easier to understand than Binary Indexed Trees</p><h3>How a Segment Tree works</h3><p>A Segment Tree at it’s core is just a binary tree</p><p>Each parent, will have 2 child nodes or less, but for our implementation we’ll make sure they all have exactly 2 child nodes</p><p>In order to achieve this we have to make sure the length of the array is a power of 2, so it can be 1, 2, 4, 8, etc.</p><p>If it isn’t, and it has something like 6 elements, then we can just add 2 elements to the end with values of 0</p><p>Let’s use this array as an example: [5, 8, 6, 3, 2, 7, 2, 6]</p><p>Here’s how we’ll represent it as a tree:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Kjg1pzrO_Xe_dTQd.png" /></figure><p>Keep in mind that this tree is only meant for <strong>sum queries</strong> it won’t work for minimum or maximum queries, but we’ll see how to do those later</p><p>In the tree you’ll also see that the parent node is simply the sum of the two children nodes</p><p>Let’s say we want to get the sum from index 2 to index 7 (inclusive, and it’s 0 indexed):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/873/0*H-xqHTSnJ33e4Qcg.png" /></figure><p>Since we’ve computed the sums for both of the child nodes we can basically split up the array into ranges for which we’ve computed the values</p><p>In this example we’ split it up into the first range with 6 and 3 who’s sum is 9, and then the other range 2, 7, 2, and 6 who’s sum is 17</p><p>Since we know both of these sums we just add them together and get 26</p><p>Updating values is also quite simple</p><p>Let’s say we want to update the value at index 5 with value 7 to be a 10</p><p>We can first change that value:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KJKjPWdpFQhWsfUZ.png" /></figure><p>After that we can move up a level to update the parent node:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*PXCgpYqY-UtouWT6.png" /></figure><p>And so on until we reach the root node:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/986/0*zlPp6da_RYqaf_As.png" /></figure><p>Boom, we’ve updated the tree in O(log n) time!</p><p>Awesome stuff</p><p>Now, it’s time to implement it</p><h3>Implementing a Segment Tree</h3><h3>Sum Queries</h3><p>So far we’ve visually been looking at a tree, but from the code, it’ll all be represented as an array</p><p>Here’s what it would look like (let’s call this array tree):</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9GBGXiIGAHmNW7VV.png" /></figure><p>Notice that it’s one indexed, but in the code you can just add an empty element at index 0</p><p>The way the tree is represented here is that tree[1] is the root node, it’s child nodes are tree[2] and tree[3], then the child nodes of tree[2] are tree[4] and tree[5], and so on</p><p>Here are some important things for traversing the tree:</p><ul><li>Getting to the two child nodes — You can use tree[2n] and tree[2n + 1] where n is the index of the current element. Let’s say n is 2 with value 22, it’s children are then tree[4] and tree[5] which have values 13 and 9, which is the correct answer</li><li>Going up levels — To go from the current node to it’s parent node we can use tree[n / 2] where n is the index of the current element. If n is 8 with value 5 then tree[n / 2] is 4 with value 13 which is the parent</li></ul><p>Using this we can use the following code to get the sum within the range of a to b:</p><pre>int sum(int a, int b) {<br>    a += n; b += n;<br>    int s = 0;<br>    while (a &lt;= b) {<br>	if (a % 2 == 1) s += tree[a++];<br>	if (b % 2 == 0) s += tree[b--];<br>	a /= 2; b /= 2;<br>    }<br>    return s;<br>}</pre><p>Let’s go through it</p><p>We start off by doing a +=n and b +=n this is simply making this range start at the very last level</p><p>Let’s say we want to find the range from index 3 to 7, in that case a would become 11 and b would become 15 since the length of the array, n, is 8:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*w1qTh4kQDpRB346r.png" /></figure><p>We also have a variable s which contains the sum</p><p>Then we continue in the loop while the variable a is less than b because if the pointer a goes to the right of b it means we’ve reached the root node, and we’re done</p><p>Now, here’s the confusing part</p><p>The two if statements, we’re checking if a % 2 ==1 and if b % 2 == 0, and only then do we add the current node to the sum</p><p>Why these specific conditions?</p><p>Let’s go through the first iteration to see how it works</p><p>We’re checking if a % 2 == 1, and since a is 11, this condition is true</p><p>This means we select the current element 3</p><p>What if we didn’t select it though?</p><p>Well, which element would you select then?</p><p>The parent node, 9, is the sum of it’s two child nodes, but those aren’t a part of the range</p><p>If it’s still confusing then let’s look at b</p><p>The condition b % 2 == 0 will be false since b is 15, and that’s good!</p><p>If we did select the current element 6, then that’s wrong, because after that what would we have done?</p><p>Selected it’s parent node 8?</p><p>That would give us the wrong answer because if you do 8 + 6 you’re basically saying you want the range from 14 to 15, and also the element at 15</p><p>This means you’re basically adding a duplicate element, and that’s wrong</p><p>I hope this explains why we’re doing that modulo, we just want to check whether we should select the current node, or wait, and select some other parent node which contains the sum for the range we want</p><p>If we do go into the if statement then we also increment a and decrement b</p><p>This is because if we don’t then a might continue going to the left of the tree and that will be out of the range of our query, and therefore would have no meaning</p><p>This is why we’re basically “nudging” a to stay inside the range</p><p>The same logic applies to the variable b because it would also continue drifting off to the right, but if we decrement it then it’ll stay within the range</p><p>That’s quite a bit, but try debugging the code, that’s what helped me</p><p>The next lines of code are pretty simple, doing a /= 2 and b /=2 simply moves them up a level, and then we just return the sum s</p><h3>Minimum and maximum queries</h3><p>To do a minimum or maximum query we use the exact same code as before</p><p>The only thing we change is how the tree is constructed</p><p>For minimum queries here’s what the tree would look like using the original array:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/985/0*w9zJJXUD1LEx3v5S.png" /></figure><p>Now we simply just query it the same as before starting at the bottom, and updating the minimum value as we go up</p><h3>Updating values</h3><p>Here’s the code for updating a value k by x:</p><pre>void add(int k, int x) {<br>    k += n;<br>    tree[k] += x;<br>    for (k /= 2; k &gt;= 1; k /= 2) {<br>        tree[k] = tree[2*k]+tree[2*k+1];<br>    }<br>}</pre><p>This code is much simpler</p><p>We again start at the bottom of the tree by doing k += n</p><p>Then update the current value there by x</p><p>Now we just want to move up the tree while updating the values</p><p>To do that we first move up a level with k /= 2</p><p>Then update the value at tree[k] by adding it’s two children using the expressions we had seen before</p><p>We keep on doing this until we reach the top of the tree, and we’ve updated the tree in O(log n) time!</p><h3>Conclusion</h3><p>The code behind Segment Trees might be a little daunting at first, I personally found it very confusing to understand, but try debugging it line by line and creating diagrams, it’ll really help</p><p>If you have any questions, comments, or feedback then feel free to reach out to me on <a href="https://www.linkedin.com/in/jinay-patel-6369002b4/">LinkedIn</a>!</p><p>I also hope this entire series on Range Queries helped you, I’m also going to be releasing an article on Bit Manipulation soon!</p><p>Bye ✌️</p><h3>Bibliography</h3><p><a href="https://cses.fi/book/book.pdf">Competitive Programmer’s Handbook</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a8f0035d909a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Range Queries, visualized (Part 2: Binary Indexed Trees)]]></title>
            <link>https://medium.com/@jinayunity22/range-queries-visualized-part-2-binary-indexed-trees-7e2c75556812?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/7e2c75556812</guid>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[binary-indexed-tree]]></category>
            <category><![CDATA[range-query]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Thu, 29 Aug 2024 02:26:01 GMT</pubDate>
            <atom:updated>2024-08-29T02:26:01.816Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>Hey 👋, if you’re new here then read this <a href="https://substack.com/home/post/p-148024599?source=queue">article</a> that gives an introduction to range queries and static queries.</p><p>Other then that, let’s get started with binary indexed trees :)</p><h3>Binary Indexed Tree</h3><p>In the previous article the array we had was static, so it didn’t change in between queries</p><p>If it did, then we’d have to recompute all the values again which isn’t that efficient</p><p>This is why we have binary indexed trees, they allow us to do O(log n) time operations on an array when getting the sum or updating the array</p><p>We’ll be using this array as an example: [3, 2, -1, 6, 5, 4, -3, 3, 7, 2, 3]</p><p>Here’s the order of the indexes in the tree, actually represented as an array but we’ll see that later:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*zBADWO9SmTmL8K0y.png" /></figure><p>The numbers on the sides of this tree are actually the indexes from the array, I’ve left the boxes empty because we’ll be computing their values later</p><p>Let’s first look at how we actually got this particular order for the indexes</p><p>Let’s look at index 6, and why it’s there and not anywhere else in the tree</p><p>The binary form of 6 is 0110, and if we flip the rightmost <strong>one bit</strong> to a 0 then we get 0100 which is equal to 4, and that’s why 4 is the parent of index 6</p><p>Let’s look at 8 who’s binary form is 1000, if we flip the rightmost one bit to a 0 we get 0000 which is just equal to 0, which is 8’s parent in the tree!</p><p>To set the rightmost bit to a zero in the code we use x &amp; (x — 1)</p><p>If x = 8 then 8–1 = 7, who’s binary form is 0111, then if we do 1000 &amp; 0111 we will get 0000 which is the parent of 8!</p><p>Pretty cool stuff</p><p>Now, let’s compute the actual value in each of those boxes (called nodes)</p><p>The idea is that we can represent any number as powers of 2 (in binary form)</p><p>Let’s say we want to calculate the value at index 1 in the tree</p><p>Let’s convert it to powers of 2 first, so we will get 1 = 0 + 2⁰</p><p>What this is saying is we start at <strong>index 0 in the array</strong>, and we take <strong>one element</strong> from there</p><p>In the array we have the value 3 at index 0, and since we’re taking just one element, we simply put 3 into the node!</p><p>Let’s calculate the value at index 4 in the tree</p><p>If we convert 4 into powers of 2 we get 4 = 0 + 2²</p><p>Again, we will start at index 0 in the array, but this time we will get the sum of <strong>4 elements</strong> from there since two to the power of two is four</p><p>This means we get 3 + 2–1 + 6 = 10, and we put the number 10 into the node</p><p>Let’s look at one last example and index 7</p><p>If we represent 7 as powers of 2 we get 7 = 2² + 2¹ + 2⁰</p><p>If we sum up the first two numbers we get 6 which tells us to start at index 6 in the array, and select <strong>1 element</strong> from that index</p><p>This means we put the number -3 into that node</p><p>Here’s the full tree after all the values have been computed:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*lI0SEwl7JcgpJ8vH.png" /></figure><p>I also mentioned before that all of these values are actually stored in an <strong>array</strong> and we’re just using a tree here to make it easier to see visually</p><p>This means as an array it should look something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jT4TystKtQD6HCQH.png" /></figure><p>Now to get the sum we just need to figure out how to traverse the tree and go up levels</p><p>To do it we’ll use this, k — (k&amp; -k)</p><p>Let’s break it down when k = 5, and we know it needs to equal 4 if we go up a level because that’s the parent in the tree</p><p>First let’s take the two’s complement, which is what the negative sign is telling us to do</p><p>Here we flip all the bits, so 5’s bit representation is 0101, and flipping all of them we get 1010, and if we add one we get 1011</p><p>Finally we perform an and operation with the original number so we get 0101 &amp; 1011 = 0001 which is equal to 1</p><p>Finally we will subtract this from the original number, 5, so we get 5–1 = 4, and that is the parent node!</p><p>Let’s look at the code:</p><pre>int sum(int k) {<br>  int s = 0;<br>  while (k &gt;= 1) {<br>    s += tree[k];<br>    k -= k&amp;-k;<br>  }<br>  return s;<br>}</pre><p>All of this just for 6 lines of code 😭</p><p>Anyways, the function will compute a sum from index 1 up to index k</p><p>It’ll first check if k is greater than or equal to 1 because if it isn’t then it means we’ve reached the highest level in the tree and can return the sum</p><p>Inside the while loop it’ll first add the sum, and use the equal from before to move up a level to the parent node, then it’ll get it’s sum, and so on</p><p>If we want to get the sum from index 1 to index 7 then the tree would look something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*5L-sXqtz_IvEfqEs.png" /></figure><p>This gives us the correct sum of 16!</p><p>Just keep in mind that when you’re counting the values in the original array that they will be one indexed because the root node with value 0 at index 0 has no significance</p><p>Fun, now we can do a sum query in O(log n) time!</p><p>Updating the values is also quite simple, and we can do it in the same time complexity as well, O(log n)</p><p>To update a value at index k by x we start at the top of the tree instead of the bottom, and traverse it the same way we did before!</p><p>Here’s the code:</p><pre>void add(int k, int x) {<br>    while (k &lt;= n) {<br>	tree[k] += x;<br>        k += k&amp;-k;<br>    }<br>}</pre><p>Here we’re using the same equation as before, except now we’re <strong>adding</strong> that value to k instead of subtracting it, so the equation is just k + (k &amp; -k)</p><p>Here’s what it looks like when we’re traversing the tree if we wanted to update the value at index 7:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*g4fmkjQq-D890RRn.png" /></figure><p>That’s it!</p><p>We can now perform a sum query on an array, and update values in it even when the array changes!</p><h3>Conclusion</h3><p>I hope this helped, if you have questions or feedback feel free to reach out to me on <a href="https://www.linkedin.com/in/jinay-patel-6369002b4/">LinkedIn</a>!</p><p>In the next article we’ll be looking at a Segment Tree which is sort of like an alternative to a Binary Indexed Tree but it’s still just as interesting.</p><p>Alright, bye 👋, have fun coding!</p><h3>Bibliography</h3><p><a href="https://cses.fi/book/book.pdf">Competitive Programmer’s Handbook</a></p><p><a href="https://www.youtube.com/watch?v=CWDQJGaN1gY">Binary Indexed Tree video</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7e2c75556812" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Range Queries, visualized (Part 1: Static Queries)]]></title>
            <link>https://medium.com/@jinayunity22/range-queries-visualized-part-1-static-queries-1a847e8ed5ab?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/1a847e8ed5ab</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[range-query]]></category>
            <category><![CDATA[visualization]]></category>
            <category><![CDATA[data-structure-algorithm]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Fri, 23 Aug 2024 04:54:24 GMT</pubDate>
            <atom:updated>2026-03-21T03:41:19.624Z</atom:updated>
            <content:encoded><![CDATA[<h3>What are range queries?</h3><p>You’re given a subarray of an array, so if the original array is [1, 2, 3, 4, 5] you could be given [1, 2, 3] or [4, 5].</p><p>Your task is to perform one of the following operations:</p><ul><li>sum(a, b): Calculate the sum of values in range [a, b]</li><li>min(a, b): Find the minimum value in range [a, b]</li><li>max(a, b): Find the maximum value in range [a, b]</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Acdl3dSLhRdCg0Im.png" /></figure><p>Seems pretty simple right? Honestly, it is, if you want to do it in O(n) time. In order to optimize it you have to go a little bit more complex, but don’t worry, it’ll be pretty chill.</p><h3>Static array queries</h3><p>In a static array query the array just will not change in between queries.</p><p>This means if you’re given [1, 2, 3, 4, 5], and you find the sum of [1, 2, 3], then after that the array won’t have elements added, removed, or changes, it’ll just stay the same.</p><h3>Sum queries</h3><p>Let’s say we’re given the following array, [1, 3, 4, 8, 6, 1, 4, 2], and we want to perform a sum query on it, so we want to find the sum from let’s say [0, 3] which corresponds to the elements [1, 3, 4, 8], and their sum is 16.</p><p>We could of course just loop through the array in O(n) time, and we’ll have our answer, but we can also create a data structure in O(n) time, and when we go to do our queries it will only take O(1), constant time, to get the result!</p><p>The thing we’ll use to create the data structure is called a prefix sum array, here’s an example:</p><pre>original_array = [1, 3, 4, 8, 6, 1, 4, 2]<br>prefix_sum_array = [1, 4, 8, 16, 22, 23, 27, 29]</pre><p>Here we create a new array where each value is going to be the sum of all the values from the original array up to that point.</p><p>Now, it’s pretty simple, all we need to do to find the sum of [a, b] is find the value at index b in the prefix sum array, and subtract that from the value at index (a — 1) from the prefix sum array.</p><p>Let’s say we want to get the sum from [2, 5], this subarray is [4, 8, 6, 1]. We get the value from the prefix sum at index 5, which is 23, and subtract it from the value at index 1, which is 4, and so we get 23–4 = 19.</p><p>Here’s the generalized formula:</p><p>S[l, r] = PrefixSum[R] — PrefixSum[L — 1]</p><p>Boom, we can query it in O(1) time! 😀</p><h3>Minimum queries</h3><p>We’ll just be looking at just minimum queries since it’s basically the same concept for maximum queries.</p><p>Anyways, minimum queries are a little more complicated, but don’t worry, just read it all through, and you’ll get it!</p><p>Let’s say we’re given the same array as before again, [1, 3, 4, 8, 6, 1, 4, 2].</p><p>What we’re going to do to create the data structure is calculate the minimum values <strong>in subarrays where their lengths are powers of 2.</strong></p><p>You’ll see why this is important later on, but it’s really cool!</p><p>Here’s the values that will be calculated from the array:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*50YfU4jt-CI1rY74.png" /></figure><p>You can see the lengths, like from 0 to 3, are 4, or from 2 to 3 are 1 since they are both powers of 2.</p><p>This will take O(n log n) time since we go through all the elements in the array, and then calculate log(n) values since we are doing it by powers of 2.</p><p>Now how do we actually calculate the minimum values within these ranges? In the image of the table it mentions a function called minq(a, b), how does it work?</p><p>Let’s get to that.</p><p>Scary equation alert ⚠️😬</p><p>Well, that’s a lot, but don’t worry, once it clicks, it’ll stay with you forever.</p><p>Let’s break it down by what’s being passed into the parameters first.</p><p>The variables a and b are the range as we’ve see so far, so something like [2, 5].</p><p>In the first recursive call we are passing in the variable a, and then for the variable b we are passing in (a + w — 1).</p><p>Then if we move onto the second recursive call you’ll see we pass in (a + w) as the parameter for a.</p><p>Here the variable w is the following equation:</p><p>The top part of the equation is simply getting the <strong>length of the array</strong> and then we are just dividing it by 2 to get half of the length of the array.</p><p>Why is this the case though?</p><p>Well, we’re literally just splitting the array in half, and giving each function those halves.</p><p>If you’re familiar with merge sort this should be basically the same.</p><p>Words don’t always help though, let’s look at the function calls visually. In the image we are going to use a function called m to represent the minq function.</p><p>Here’s what the recursive function calls look like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Acdl3dSLhRdCg0Im.png" /></figure><p>Now let’s see what they all return.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nH2aPlMPK9ImFEkD.png" /></figure><p>I also put the array in as reference because the parameters are <strong>indexes of the array</strong>, just keep that in mind.</p><p>We can finally create the data structure now.</p><p>That’s right, that was only the data structure, only half way there 😭.</p><p>Scary equation alert ⚠️😬</p><p>Let’s dissect this one now, it’s meant to actually find the minimum value in the subarray.</p><p>Here’s the main idea behind getting the minimum value in a range [a, b].</p><p>Let’s say we want to find it in the range of [1, 6]:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/779/0*cikRKE0PwiAyu1kK.png" /></figure><p>Remember how we calculated the minimum values when the <strong>lengths were powers of 2?</strong></p><p>This is where that comes in, let’s split this range into 2 ranges each of length 4, <strong>which is a power of 2</strong>, which means we already have it calculated!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/718/0*bmtSVvnqnQv-s5B2.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/883/0*0LzFul8xPEoLTUUj.png" /></figure><p>Since we have the minimum values of each of the subarrays saved in the data structure we can just get the values from there, so the left range has a minimum value of 3, and the right range has a minimum value of 1.</p><p>Finally we just take the minimum of 3 and 1 and we have our answer! 🤯</p><p>That means in the range [1, 6] the minimum value is 1, and we calculated it in O(1) time!</p><p>Now let’s look at the equation.</p><p>You’ll see we are splitting the array again since we’re making two function calls.</p><p>Here the variable k is the <strong>largest power of 2 that doesn’t exceed the length of the subarray.</strong></p><p>Let’s say the length of the subarray were 8, then the largest power of 2 to the power of 3 which is 8!</p><p>In this example the length of the subarray was 6, sot he largest power of 2 was 4, because 8 would be too big.</p><p>Then for the left side of the array we simply go from a to (a + k), and in the example k was 4, so the length of the left subarray is 4.</p><p>Tt’s the same thing for the right subarray as well where we start from (b — k) and go up to b, again the resulting subarray will be of length 4.</p><p>There you have it! We can calculate the minimum value of a subarray in O(1) time after creating it’s data structure in O(n log n) time.</p><h3>Conclusion</h3><p>If you have any questions, comments, or feedback feel free to drop them in the comment section down below, or DM me on <a href="https://www.linkedin.com/in/jinay-patel-6369002b4/">LinkedIn</a>!</p><p>In the second part we’re going to be looking at binary trees, and then in the third part we’ll look at segment trees!</p><p>It’s really fun stuff, so stay tuned!</p><h3>Bibliography</h3><p><a href="https://cses.fi/book/book.pdf">Competitive Programmer’s Handbook</a></p><p>Thanks for reading! Subscribe for free to receive new posts and support my work.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a847e8ed5ab" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Javascript import/export and common problems/solutions]]></title>
            <link>https://medium.com/@jinayunity22/javascript-import-export-and-common-problems-solutions-7fd5da61f169?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/7fd5da61f169</guid>
            <category><![CDATA[solutions]]></category>
            <category><![CDATA[import]]></category>
            <category><![CDATA[export]]></category>
            <category><![CDATA[problems]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Sun, 17 Mar 2024 00:55:45 GMT</pubDate>
            <atom:updated>2024-03-17T00:55:45.352Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*o-q6HKXvlFA5nZJyWINY1g.png" /></figure><h3>Javascript import/export andcommon problems/solutions</h3><h3>Introduction</h3><p>Imports and exports in Javascript can be incredibly useful when trying to organize your code, because it lets you export a certain variable, function, or class from one file and import it in another allowing you to organize your code and keep it easy to maintain.</p><h3>Exporting</h3><p>Let’s say you have a variable, function, and class in one file that you want to export to another file and use it there:</p><pre>class Animal { ... }<br>function SomeFunction { ... }<br>let x = 1;</pre><p>Now all we have to do to export all of these is add in the export keyword before it:</p><pre>export class Animal { ... }<br>export function SomeFunction { ... }<br>export let x = 1;</pre><p>We can also add the default keyword after export if we are exporting only one component or if that component is the main one in the file:</p><pre>export default class Animal { ... }<br>export function SomeFunction { ... }<br>export let x = 1;</pre><p>In the example above we have exported the class as the default export. You can also export multiple things inside curly braces as shown below:</p><pre>let x = 1;<br>let y = 2;<br>export default {x, y};</pre><h3>Importing</h3><p>Importing items is also very simple, and can be done as shown below:</p><p>export.js:</p><pre>export default let x = 1;</pre><p>index.js:</p><pre>import x from &quot;./index.js&quot;</pre><p>Imports can also be done with the curly braces that we used before when exporting:</p><p>export.js:</p><pre>let x = 1;<br>let y = 1;<br>export default {x, y};</pre><p>index.js:</p><pre>import {x, y} from &quot;./export.js&quot;</pre><h3>Common Problems</h3><p>Let’s say you have a file name export.js containing the same code as before:</p><pre>let x = 1;<br>let y = 1;<br>export {x, y};</pre><p>Then we have another file called index.js which is importing x and y:</p><pre>import {x, y} from &quot;./export&quot;<br><br>/* Do stuff */</pre><p>Now in index.html we are using index.js:</p><pre>&lt;!doctype html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>    &lt;head&gt;<br>        ...<br>    &lt;/head&gt;<br>    &lt;body&gt;<br>        &lt;script src=&quot;./index.js&quot;&gt;&lt;/script&gt;<br>    &lt;/body&gt;<br>&lt;/html&gt;</pre><p>If we ran this code we would get the error below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Hg0bKMkp4uwn3XhAm5vHww.png" /><figcaption>Error shown inside the console</figcaption></figure><p>Now this is a simple fix because inside the HTML script tag we can just add type=&quot;module:</p><pre>&lt;script src=&quot;./index.js&quot; type=&quot;module&quot;&gt;&lt;/script&gt;</pre><p>This will take this error away, but another error may come up:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*w-GSfdCNb1RlIH0ASSpAGw.png" /><figcaption>The second error shown in the console</figcaption></figure><p>You may not have come across this problem if you noticed a small difference in how we imported export.js, but, for me personally, I didn’t when this error came up for me the first time and I spent a fair bit of time trying to solve it. Then I found out that literally all I was missing was .js after the file name in the import. This means we can change the code below to the update version:</p><pre>import {x, y} from &quot;./export&quot;; // Old code<br>import {x, y} from &quot;./export.js&quot;; // New code</pre><p>This will fix the problem, and now if we log out both x and y then you will see 1 be printed out twice. Below is the new code for all the files:</p><p>export.js:</p><pre>let x = 1;<br>let y = 1;<br>export {x, y};</pre><p>index.js:</p><pre>import {x, y} from &quot;./export.js&quot;<br><br>console.log(x);<br>console.log(y);</pre><p>index.html:</p><pre>&lt;!doctype html&gt;<br>&lt;html lang=&quot;en&quot;&gt;<br>    &lt;head&gt;<br>        ...<br>    &lt;/head&gt;<br>    &lt;body&gt;<br>        &lt;script src=&quot;./index.js&quot; type=&quot;module&quot;&gt;&lt;/script&gt;<br>    &lt;/body&gt;<br>&lt;/html&gt;</pre><h3>Conclusion</h3><p>I hope this article helped you learn about imports and exports in javascript and/or helped you solve some problem that you were facing. If there was any error in this article or if you think that something could be explained more clearly then please do let me know. Thank you for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7fd5da61f169" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Free PyTorch Courses/Books]]></title>
            <link>https://medium.com/@jinayunity22/free-pytorch-courses-books-2049602beda9?source=rss-cb7fc161d364------2</link>
            <guid isPermaLink="false">https://medium.com/p/2049602beda9</guid>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[resources]]></category>
            <category><![CDATA[books]]></category>
            <category><![CDATA[pytorch]]></category>
            <category><![CDATA[course]]></category>
            <dc:creator><![CDATA[Jinay Patel]]></dc:creator>
            <pubDate>Fri, 01 Mar 2024 05:28:44 GMT</pubDate>
            <atom:updated>2024-03-01T05:43:58.069Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lpcdiUFlOOR6SUUcW1dbbg.jpeg" /><figcaption>PyTorch text with logo</figcaption></figure><h3>Introduction</h3><p>Recently, I’ve been wanting to get into machine learning with PyTorch, and I looked for resources that were simple to understand with minimal math (I am still a high school student so I do not know very advanced math concepts, yet). Below is a list of some of the courses I have found so far, and am either planning to learn or am already using it to learn:</p><h3>1. PyTorch for Deep Learning &amp; Machine Learning — Full Course</h3><p>This is a course that I have currently been doing, and it has been amazing! The instructor can teach concepts in such a simple manner, and, while there may be a lot of repetiveness in the course, I have found it to be a really good thing because it helps me gain confidence when I go to write my own machine learning models. The course starts off with talking about the basics of PyTorch (and really all machine learning frameworks), tensors, and different manipulations that can be done on them. Then you will go onto building models such a simple linear regression model, binary classification, and multi-class classification. After this you will be working with computer vision and creating models to deal with images. The overall course is very engaging and fun, and I would highly recommend doing it.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FV_xro1bcAuA%3Fstart%3D47589%26feature%3Doembed%26start%3D47589&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DV_xro1bcAuA&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FV_xro1bcAuA%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/5b78c8b500cd18b45075709522a9a7b4/href">https://medium.com/media/5b78c8b500cd18b45075709522a9a7b4/href</a></iframe><h3>2. Deep Neural Networks with PyTorch</h3><p>I haven’t been doing this course, but might do it if I really want to get some more practice in. I’ve looked through the modules, and the things do seem quite similar to the first course, but there is not any computer vision. It seems like a good course if you don’t want to do compter vision, and do a bit deeper in some topics, but I wanted to learn computer vision as well so I chose the first course.</p><p><a href="https://www.coursera.org/learn/deep-neural-networks-with-pytorch?source=post_page-----a92fd1d718bd--------------------------------#about">Deep Neural Networks with PyTorch</a></p><h3>3. Deep Learning with PyTorch</h3><p>If you prefer reading instead of watching videos then this book might just be for you. It goes fairly deep into PyTorch and machine learning concepts, and has quite a bit of detail. This book is definetly quite long and also requires some more advanced math concepts such as vectors, matrices, and dot products (not too complicated though). A great thing about this book is that it goes a bit into how PyTorch works behind the scenes in part 1, and then in part 2 it uses a real life example of detecting lung cancer to teach you more concepts. If you are someone that wants to go really deep into PyTorch and machine learning then this book might be a good choice.</p><p><a href="https://isip.piconepress.com/courses/temple/ece_4822/resources/books/Deep-Learning-with-PyTorch.pdf">https://isip.piconepress.com/courses/temple/ece_4822/resources/books/Deep-Learning-with-PyTorch.pdf</a></p><h3>Conclusion</h3><p>I hope that you found some resources that you like from this page, and have fun learning!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2049602beda9" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>