<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Samarth Jajoo</title>
    <description>The latest articles on DEV Community by Samarth Jajoo (@jajoosam).</description>
    <link>https://dev.to/jajoosam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F61654%2Fee480435-caaa-4afd-8852-616a18edabf4.jpg</url>
      <title>DEV Community: Samarth Jajoo</title>
      <link>https://dev.to/jajoosam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jajoosam"/>
    <language>en</language>
    <item>
      <title>Flappy Bird, in a new, super easy game framework 🐦</title>
      <dc:creator>Samarth Jajoo</dc:creator>
      <pubDate>Sat, 24 Aug 2019 08:04:20 +0000</pubDate>
      <link>https://dev.to/jajoosam/flappy-bird-in-a-new-super-easy-game-framework-2h15</link>
      <guid>https://dev.to/jajoosam/flappy-bird-in-a-new-super-easy-game-framework-2h15</guid>
      <description>&lt;h1&gt;
  
  
  Make flappy bird with Python Play
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Freplit%2Fimages%2F1566633312709_d7fd16ea4dac17d138efb5825222e7e4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Freplit%2Fimages%2F1566633312709_d7fd16ea4dac17d138efb5825222e7e4.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://repl.it/@jajoosam/flappy-bird" rel="noopener noreferrer"&gt;Demo and Code&lt;/a&gt; 👨‍💻&lt;/p&gt;

&lt;p&gt;Flappy bird is one of the classics - and as you'll see, super easy to create, especially when you use the &lt;a href="https://github.com/replit/play" rel="noopener noreferrer"&gt;Python Play&lt;/a&gt; library developed at &lt;a href="https://repl.it" rel="noopener noreferrer"&gt;repl.it&lt;/a&gt;! &lt;/p&gt;

&lt;p&gt;If you haven't played flappy bird before, try it out on &lt;a href="https://flappybird.io/" rel="noopener noreferrer"&gt;flappybird.io&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  🎓 So, how exactly does flappy bird work?
&lt;/h2&gt;

&lt;p&gt;There are two objects which matter in the game - the bird and the pipes. In the demo above, the bird is the yellow circle, while the pipes are the blue rectangles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The bird&lt;/strong&gt; remains in the same &lt;code&gt;x&lt;/code&gt; position for the entire game, but can move up when the player presses a key, and continues to fall due to gravity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The pipes&lt;/strong&gt; are two rectangles with a gap between them - the bird needs to get through the pipes without touching them.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛣️ Get started
&lt;/h2&gt;

&lt;p&gt;Let's begin by forking &lt;a href="https://repl.it/@jajoosam/play-start" rel="noopener noreferrer"&gt;repl.it/@jajoosam/play-start&lt;/a&gt; - Which is just a python environment with the &lt;code&gt;play&lt;/code&gt; dependency installed.&lt;/p&gt;

&lt;p&gt;Let's start off creating flappy bird by creating a yellow circle to represent the bird:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bird&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yellow&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Running that code will result in a &lt;code&gt;yellow&lt;/code&gt; circle, close to the &lt;code&gt;top&lt;/code&gt; &lt;code&gt;left&lt;/code&gt; corner of the screen with a radius of &lt;code&gt;30&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Freplit%2Fimages%2F1566633408040_02c2a37f0f00bccc75ba7bfabffe1e41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Freplit%2Fimages%2F1566633408040_02c2a37f0f00bccc75ba7bfabffe1e41.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🌎 Physics is... easy!
&lt;/h2&gt;

&lt;p&gt;We want our bird to be affected by gravity, and bounce back up when it falls to the bottom of the screen. So let's create a whole physics engine to do that!&lt;/p&gt;

&lt;p&gt;lol jk, just add this one line to your code: &lt;code&gt;bird.start_physics()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;yep, that's it. really!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3oKIPlifLxdigaD2Y8/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3oKIPlifLxdigaD2Y8/giphy.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you run your code now, you'd see a yellow circle falling down, and bouncing back up! We want to be able to make our bird flap though - make it jump when we want to.&lt;/p&gt;

&lt;p&gt;We can use &lt;code&gt;play.repeat_forever&lt;/code&gt; to run a function every frame of our game - and in this case, if the &lt;code&gt;up&lt;/code&gt; arrow key is pressed, our &lt;code&gt;bird&lt;/code&gt;'s &lt;code&gt;y&lt;/code&gt; coordinate increases by &lt;code&gt;7.5&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@play.repeat_forever&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key_is_pressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;up&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;bird&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;7.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  🚬 Let's roll the pipes
&lt;/h2&gt;

&lt;p&gt;We're going to create pipes in sets of two, for blocking our birds - and store all of them in a list.&lt;/p&gt;

&lt;p&gt;Near the top of your code, add a new line to create this empty list.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;boxes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We want the two pipes we generate each time to have different height, and a gap in the middle. We also want to generate the next pair of pipes after a random duration, to make the game more unpredictable.&lt;/p&gt;

&lt;p&gt;It'll be very useful for us to use python play's &lt;code&gt;random_number&lt;/code&gt; function here.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Returns a integer between 300 and 500
&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Returns a float between 1.0 and 3.0
&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Add this entire block of code, just before &lt;code&gt;play.start_program()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@play.repeat_forever&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;block&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="c1"&gt;# height of the top block
&lt;/span&gt;    &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# height of the bottom block
&lt;/span&gt;    &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lowest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;highest&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# creating the top box of width 50, emerging from behind the current screen
&lt;/span&gt;    &lt;span class="n"&gt;boxes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# creating the bottom box of width 50, emerging from behind the current screen
&lt;/span&gt;    &lt;span class="n"&gt;boxes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                              &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# creating the next box after a random duration between 1 and 4 seconds
&lt;/span&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seconds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This code is inside an &lt;code&gt;async&lt;/code&gt; function - which is why we can use the &lt;code&gt;await&lt;/code&gt; keyword to delay each call by a particular duration, with &lt;code&gt;play.timer&lt;/code&gt; - this lets us create new boxes at an interval! &lt;/p&gt;

&lt;p&gt;With &lt;code&gt;play.new_box&lt;/code&gt; - we create a new pipe and then append it to the &lt;code&gt;boxes&lt;/code&gt; list too. Try playing around with the parameters we supply to this function. they should be understandable!&lt;/p&gt;

&lt;p&gt;But if you run the code now, you'll notice that everything is the same as before 😕&lt;/p&gt;
&lt;h2&gt;
  
  
  🖥️ Bring the pipes to the screen
&lt;/h2&gt;

&lt;p&gt;Since all our pipes are in the same &lt;code&gt;boxes&lt;/code&gt; list, we can move all of them pretty easily, by looping over the list.&lt;/p&gt;

&lt;p&gt;Adding this block to your code, under &lt;code&gt;def do():&lt;/code&gt; makes the boxes move through the screen!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;boxes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# make the box move to the left
&lt;/span&gt;        &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is what you should see when you hit run!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Freplit%2Fimages%2F1566633365697_de64ae43d0249c4bf844465aef5aa4e9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstorage.googleapis.com%2Freplit%2Fimages%2F1566633365697_de64ae43d0249c4bf844465aef5aa4e9.gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🤔 But... when do you lose?!
&lt;/h2&gt;

&lt;p&gt;I'm really going to sell you on python play by explaining how we can detect collisions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bird.is_touching(box)&lt;/code&gt; - that's it. No cap 🧢&lt;/p&gt;

&lt;p&gt;In our same loop, where we're moving the pipes to the left, just add this condition block:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bird&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_touching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;red&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the bird ever touches the pipe, it's color shall be red!&lt;/p&gt;

&lt;p&gt;Also add this block in the loop:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;boxes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We're just preventing &lt;a href="https://en.wikipedia.org/wiki/Memory_leak" rel="noopener noreferrer"&gt;memory leaks&lt;/a&gt; with this - if our pipe is out of the screen, let's just remove it!&lt;/p&gt;
&lt;h2&gt;
  
  
  🔮 Things to hack on
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use pixel art of a bird instead of the yellow circle 👨‍🎨&lt;/li&gt;
&lt;li&gt;Restart the game when the bird touches the pipe ☠️&lt;/li&gt;
&lt;li&gt;Add power-ups to the game 💪&lt;/li&gt;
&lt;li&gt;Add a live score to the screen 💯&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Be sure to put down any questions or improvements down in the comments 💬 &lt;/p&gt;

&lt;p&gt;And here's all the code for you to go over again - I've annotated it for you too 😄&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@jajoosam/flappy-bird?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



</description>
      <category>gamedev</category>
      <category>python</category>
    </item>
    <item>
      <title>An ML app you can build with JS, and without the math 🙈</title>
      <dc:creator>Samarth Jajoo</dc:creator>
      <pubDate>Tue, 11 Jun 2019 22:26:33 +0000</pubDate>
      <link>https://dev.to/jajoosam/an-ml-app-you-can-build-with-js-and-without-the-math-3dbk</link>
      <guid>https://dev.to/jajoosam/an-ml-app-you-can-build-with-js-and-without-the-math-3dbk</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LLOC1cR---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/main.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LLOC1cR---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/main.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://feature-extractor--jajoosam.repl.co"&gt;Demo&lt;/a&gt; ⏯️   &lt;a href="https://repl.it/@jajoosam/feature-extractor"&gt;Code&lt;/a&gt; 👨‍💻 &lt;a href="https://ecstatic-rosalind-da34e4.netlify.com/feature-extractor-demo-compressed-3e7aac1a-1c37-4448-92ab-140b5dd84056.mp4"&gt;Video Walkthrough&lt;/a&gt; 🎦&lt;/p&gt;

&lt;p&gt;Machine Learning is a super cool way to build AI apps - but I won't lie, it is a lot of math. Luckily, thanks to &lt;a href="https://ml5js.org"&gt;ml5.js&lt;/a&gt; - we don't need to spend months understanding ML, we can apply it and develop some cool uses in our app within just a few hours 😄&lt;/p&gt;

&lt;p&gt;This is a guide to build a feature extractor - something that can get a video stream from your webcam and predict what it sees, once it is trained with a little bit of data - just like in the video above!&lt;/p&gt;

&lt;h2&gt;
  
  
  🍴  Forking the frontend
&lt;/h2&gt;

&lt;p&gt;I don't want to waste too much of your time with the frontend I used for this app - I think it'd be much better if I skipped right to the JavaScript, and logic.&lt;/p&gt;

&lt;p&gt;You should fork this repl - &lt;a href="https://repl.it/@jajoosam/feature-extractor-start"&gt;https://repl.it/@jajoosam/feature-extractor-start&lt;/a&gt; - so that you have the HTML already there! It's essentially just a few &lt;code&gt;div&lt;/code&gt;s for holding the video and some other text, along with some buttons to control our app!&lt;/p&gt;

&lt;p&gt;I've commented everything (except the CSS 😛) - so you should be able to go through the frontend and understand the basic layout of the app in a few minutes. Once you're done, head over to &lt;code&gt;script.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SAZZmHlW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/Untitled-8e918105-6ae0-4591-8362-7ed6e7068460.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SAZZmHlW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/Untitled-8e918105-6ae0-4591-8362-7ed6e7068460.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✏️ Declaring the variables
&lt;/h2&gt;

&lt;p&gt;We're going to have quite a few variables to declare, so the first thing we're going to do is create them.&lt;/p&gt;

&lt;p&gt;Our app is going to have a lot of functions, and it's important that all of them can access the variables - which is why we shall declare right at the start of our code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;featureExtractor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;redCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blueCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;redCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blueCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I'll give you an overview of what these are for, but you'll understand them much better as we continue building our app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;featureExtractor&lt;/code&gt; and &lt;code&gt;classifier&lt;/code&gt; are variables we're going to store and initialize machine learning models in.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;video&lt;/code&gt; is where we're storing the webcam stream, while &lt;code&gt;loss&lt;/code&gt; lets us know the progress of how far our on feature extractor has been trained.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;blueCount&lt;/code&gt; and &lt;code&gt;redCount&lt;/code&gt; are counters for how many images there are in each category - and we initalize both of them with a value of &lt;code&gt;0&lt;/code&gt;, in the next line.&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ The &lt;code&gt;setup()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;setup()&lt;/code&gt; is a function which shall fire up as soon as our code is ready to run. Bacause of using &lt;a href="https://p5js.org"&gt;p5.js&lt;/a&gt;, our code is pretty readable and easy to understand here.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Tells p5 to not automatically create a canvas element.&lt;/span&gt;
  &lt;span class="nx"&gt;noCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Starts capturing a video feed from the webcam&lt;/span&gt;
  &lt;span class="nx"&gt;video&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createCapture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VIDEO&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Puts the video stream into the div in our html, with ID `video`&lt;/span&gt;
  &lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;video&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="c1"&gt;// Initializes a feature extractor, yet to be trained - from ml5.js&lt;/span&gt;
  &lt;span class="nx"&gt;featureExtractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ml5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;featureExtractor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MobileNet&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;classifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;featureExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// What we're doing next - setting up buttons!&lt;/span&gt;
  &lt;span class="nx"&gt;setupButtons&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This code goes in your &lt;code&gt;script.js&lt;/code&gt; file right after you declare variables - essentially, it gets a video stream and displays it on our page, inside a &lt;code&gt;div&lt;/code&gt; with the ID &lt;code&gt;video&lt;/code&gt;.  We also make some functions using the ml5.js library here, and pass the captured video as a parameter - you'll see what we do with these soon, but there's still a little more setup left!&lt;/p&gt;

&lt;p&gt;As you can see, at the end of &lt;code&gt;setup()&lt;/code&gt;, we call &lt;code&gt;setupButtons()&lt;/code&gt; -  the function we're going to make next. Here, we're adding event listeners to buttons in our HTML - so we can run functions when they're clicked.&lt;/p&gt;

&lt;p&gt;Here's all the code we write for the &lt;code&gt;setupButtons()&lt;/code&gt; function 👇&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A function to create the buttons&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;setupButtons&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;buttonA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;buttonB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="err"&gt;​&lt;/span&gt;    
&lt;span class="err"&gt;​&lt;/span&gt;      &lt;span class="nx"&gt;buttonA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;         &lt;span class="nx"&gt;redCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;        &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;        &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#redCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;redCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;      &lt;span class="p"&gt;});&lt;/span&gt;


&lt;span class="err"&gt;​&lt;/span&gt;     
&lt;span class="err"&gt;​&lt;/span&gt;      &lt;span class="nx"&gt;buttonB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;         &lt;span class="nx"&gt;blueCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;        &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;        &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#blueCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blueCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;      &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;    
  &lt;span class="nx"&gt;train&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#train&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;train&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lossValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// This is where we're actually training our model&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lossValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lossValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loss: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Done Training! Final Loss: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#train&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#predict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Predict Button&lt;/span&gt;
  &lt;span class="nx"&gt;buttonPredict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#predict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;buttonPredict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That's the largest art of our app, and I'm going to break it up into several parts to make it easier to explain!&lt;/p&gt;
&lt;h2&gt;
  
  
  🧙‍♂️bUt wHaT Do tHeSe bUtToNs dO?!?!?!
&lt;/h2&gt;

&lt;p&gt;DON'T PANIC.&lt;/p&gt;

&lt;p&gt;Let's start off with this block:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;buttonA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;buttonB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    

&lt;span class="nx"&gt;buttonA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;redCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#redCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;redCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;buttonB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;blueCount&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#blueCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blueCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;buttonA&lt;/code&gt; and &lt;code&gt;buttonB&lt;/code&gt; are nothing but the two different buttons we have in our app!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LWTV4M3r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/Untitled-c85ebc09-ab40-4060-a9ce-98966a9fe021.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LWTV4M3r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/Untitled-c85ebc09-ab40-4060-a9ce-98966a9fe021.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With  &lt;code&gt;.mousePressed()&lt;/code&gt; we're defining what happens when any of these buttons are pressed - which is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Increase the count by 1, using the &lt;code&gt;++&lt;/code&gt; operator&lt;/li&gt;
&lt;li&gt;Capture the current frame from the webcam videom and add it to the classifier, with &lt;code&gt;classifier.addImage()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Update the count on our app by changing the button's text, with &lt;code&gt;.html()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next up, we have this whole block - where we train the classifer itself:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;train&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#train&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;train&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lossValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="c1"&gt;// This is where we're actually training our model&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lossValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lossValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loss: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#info&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Done Training! Final Loss: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#train&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#predict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;display&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;When the &lt;code&gt;Train 🚋&lt;/code&gt; button on our app is pressed, we call &lt;code&gt;classifier.train()&lt;/code&gt; - and with each iteration, the function we supply there is called - which is why we see the &lt;em&gt;&lt;a href="https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html"&gt;Loss&lt;/a&gt;&lt;/em&gt; value keep changing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RlzymA2q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/CleanShot-2019-01-26-at-18-6a9809c8-75a3-4b88-b1ee-3931aa15d08c.04.57.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RlzymA2q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/CleanShot-2019-01-26-at-18-6a9809c8-75a3-4b88-b1ee-3931aa15d08c.04.57.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the &lt;em&gt;Loss&lt;/em&gt; value is &lt;code&gt;0&lt;/code&gt;, then we hid the &lt;code&gt;Train 🚋&lt;/code&gt; button, and show the previously hidden &lt;code&gt;Predict 🔮&lt;/code&gt; button!&lt;/p&gt;

&lt;p&gt;The last 2 lines of the &lt;code&gt;setupButtons()&lt;/code&gt; function are about the predict button:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;buttonPredict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#predict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;buttonPredict&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mousePressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It seems like we're calling this &lt;code&gt;classify&lt;/code&gt; function - which is what we're going to build next!&lt;/p&gt;

&lt;p&gt;Keep going, we're almost done 💯&lt;/p&gt;
&lt;h2&gt;
  
  
  🔮 Predictions, and showing results
&lt;/h2&gt;

&lt;p&gt;Our &lt;code&gt;classifier()&lt;/code&gt; function is pretty straightforward - this is all we do:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;classifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gotResults&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;We're just telling the ml5 &lt;code&gt;classifier&lt;/code&gt; to classify the current frame in either of the categories (🔴 or 🔵), and send the results to the &lt;code&gt;gotResults&lt;/code&gt; function - which brings us to the final part of our app!&lt;/p&gt;

&lt;p&gt;As long as the classifier doesn't send us an error, we change the entire page's background color to either &lt;code&gt;red&lt;/code&gt; or &lt;code&gt;blue&lt;/code&gt; - and then call &lt;code&gt;classify()&lt;/code&gt; again, which keeps our code running forever, and the predictions keep coming!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;gotResults&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;That's all the code we have to write to build the example feature extractor. I highly recommend going through the final code so that you can see how everything fits together well - I know there are quite a few functions too keep track of, but I've commented everything to make it easier 😅&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@jajoosam/feature-extractor?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;Now go ahead, try it out! Here are some things I did to see if the feature extractor would work (it did!) 👇&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep my head in the left in 🔴, and right in 🔵&lt;/li&gt;
&lt;li&gt;Make a ✌️ in 🔴, and a ✋ in 🔵&lt;/li&gt;
&lt;li&gt;Wear different colored 👕s in 🔴 and 🔵&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know other cool things it worked with 👀  &lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ okay, but what do I &lt;strong&gt;MAKE&lt;/strong&gt; with this?
&lt;/h2&gt;

&lt;p&gt;There are SOOOOO MANY THINGS you could do! A feature extractor gives you the ability to add this whole other, mysterious way of controlling, and getting input in your app!&lt;/p&gt;

&lt;p&gt;Here are a few ideas 💡&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A gesture controlled game, right in the browser 🎮&lt;/li&gt;
&lt;li&gt;A mood tracker - leave the tab open all day, and train it with different face expressions 🤔&lt;/li&gt;
&lt;li&gt;Build your own &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=pqTntG1RXSY"&gt;hotdog or not&lt;/a&gt;&lt;/strong&gt; app 🌭&lt;/li&gt;
&lt;li&gt;Build an app which only lets you message others with gestures 💬&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  👨‍🏫 what else is there?
&lt;/h2&gt;

&lt;p&gt;ml5.js can do crazy things! You can integrate image classification into your own app &lt;a href="https://repl.it/talk/challenge/male-A-scavenger-hunt-with-image-classification/10185"&gt;like I did&lt;/a&gt;, find similar words which fit into a text, get a precise skeleton of human bodies and even transfer the styles in images - look at what my picture looks like, when composed with the style of a cool painting 🖌️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MMh-kFkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/mepaint.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MMh-kFkm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ecstatic-rosalind-da34e4.netlify.com/mepaint.png" alt="mepaint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should take a look at the many &lt;a href="https://ml5js.org/docs/quick-start"&gt;examples on the ml5.js website&lt;/a&gt; - or take a look at &lt;a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6YPSwT06y_AEYTqIwbeam3y"&gt;Dan Shiffman's videos on ml5.js&lt;/a&gt;, he covers loads of things you can do with it - and explains everything with a ton of energy. I highly recommend watching his videos on the &lt;a href="https://www.youtube.com/user/shiffman"&gt;Coding Train&lt;/a&gt; YouTube!&lt;/p&gt;

&lt;p&gt;If you have any questions, feel free to ping me on &lt;a href="https://twitter.com/jajoosam"&gt;twitter&lt;/a&gt;, or leave something in the comments :)&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Show DEV: colorSpace - smart background removal with canvas 🖼️</title>
      <dc:creator>Samarth Jajoo</dc:creator>
      <pubDate>Fri, 25 Jan 2019 17:28:16 +0000</pubDate>
      <link>https://dev.to/jajoosam/show-dev-colorspace---smart-background-removal-with-canvas--56cc</link>
      <guid>https://dev.to/jajoosam/show-dev-colorspace---smart-background-removal-with-canvas--56cc</guid>
      <description>&lt;p&gt;Hey all you DEVs!&lt;/p&gt;

&lt;p&gt;Just a couple weeks ago, I built &lt;a href="https://color.4ty2.fun?ref=dev" rel="noopener noreferrer"&gt;colorSpace&lt;/a&gt; in a few hours - It was a fun idea I wanted to explore, not even being sure if it was possible at all!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkcmzs76sovhr4y7q77n4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkcmzs76sovhr4y7q77n4.gif" alt="Demo gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It turned out to be possible, and actually even accurate!&lt;/p&gt;

&lt;p&gt;My idea was pretty straightforward - usually, an image with a background has one dominant color to remove. Because of shadows and lighting angles - this color won't remain the exact same across all its pixels, but maybe it'd be possible to measure color similarity somehow 🤔&lt;/p&gt;

&lt;p&gt;I googled it - and saw a few stack overflow posts asking the same question, and learned that it was fairly trivial to get the euclidian distance between colors, since they're usually represented in a three axis system eg. &lt;code&gt;R, G, B&lt;/code&gt;  &lt;code&gt;H, S, L&lt;/code&gt; &lt;br&gt;
 &lt;code&gt;Y, I, Q&lt;/code&gt; - there are some more listed &lt;a href="https://en.wikipedia.org/wiki/List_of_color_spaces_and_their_uses#Luma_plus_chroma/chrominance" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That means we can use the distance formula, representing a color as a co-ordinate in the &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt; &lt;em&gt;axes&lt;/em&gt; (I had to google &lt;code&gt;axis plural&lt;/code&gt; 😂)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpgi8ngtp80p3w3uml3fy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpgi8ngtp80p3w3uml3fy.gif" alt="An image of a 3D co-ordinate system"&gt;&lt;/a&gt; &lt;/p&gt;
From &lt;a href="https://brilliant.org/wiki/3d-coordinate-geometry-distance" rel="noopener noreferrer"&gt;Brilliant&lt;/a&gt;



&lt;p&gt;It comes down add up the squared difference, and finding its square root, i.e:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbytxs42ost1evrnkcr8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbytxs42ost1evrnkcr8w.png" alt="Image of the 3D distance formula"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It'd be pretty simple to do this with RGB colors - but the RGB colorspace wasn't designed keeping the &lt;code&gt;ΔE&lt;/code&gt; - or distance function in mind. This means that the euclidian distance between colors in the RGB space will not always correspond to the difference us humans see between the colors.&lt;/p&gt;

&lt;p&gt;I DIDN'T give up yet though 😅 Turns out &lt;a href="https://en.wikipedia.org/wiki/International_Commission_on_Illumination" rel="noopener noreferrer"&gt;CIE&lt;/a&gt; (the W3C of the color world) designed the &lt;a href="https://en.wikipedia.org/wiki/CIELAB_color_space" rel="noopener noreferrer"&gt;L*a*b&lt;/a&gt; colorspace to be perceptually uniform with human color vision - which means, an accurate and useful &lt;code&gt;ΔE&lt;/code&gt; function 🚀&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F08key4dxj1qnsram8iou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F08key4dxj1qnsram8iou.png" alt="Front view of the CIELAB colorspace"&gt;&lt;/a&gt;&lt;/p&gt;
This is what the L*a*b colorspace looks like from the front



&lt;p&gt;From here, it was just a bit of plug and play into JS! I reused the frontend from &lt;a href="https://santa.4ty2.fun" rel="noopener noreferrer"&gt;Santafy&lt;/a&gt; - a fun christmas project I'd built 🎅&lt;/p&gt;

&lt;p&gt;I found the &lt;a href="https://github.com/antimatter15/rgb-lab" rel="noopener noreferrer"&gt;rgb-lab&lt;/a&gt; library which let me convert RGB to LAB, and back. I could also use the &lt;code&gt;ΔE&lt;/code&gt; function right within this library!&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/emn178/color-sampler" rel="noopener noreferrer"&gt;color-sampler&lt;/a&gt; library needed me to add jquery to the project, but I have no complaints - it works very well, and has a nice UI for color selection 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flo5n90jolffpsdov9hdj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Flo5n90jolffpsdov9hdj.gif" alt="color-sampler demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To summarize the code I wrote - It takes an image from visitors, and loads it up into a canvas. From there, a pixel is selected using the color sampler - and all pixels in the canvas are converted to the &lt;code&gt;L*a*b&lt;/code&gt; colorspace, and compared to the selected pixel with the &lt;code&gt;ΔE&lt;/code&gt; function - if any pixel's color falls within the treshold, the transparency for it is set to 100%&lt;/p&gt;

&lt;p&gt;And &lt;em&gt;all&lt;/em&gt; that happens in the canvas, completely on the frontend!&lt;/p&gt;

&lt;p&gt;If you haven't already, you can try &lt;a href="https://color.4ty2.fun" rel="noopener noreferrer"&gt;colorSpace here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The code is fully open source, you can check it out and instantly fork it on this &lt;a href="https://repl.it/@jajoosam/colorspace" rel="noopener noreferrer"&gt;repl&lt;/a&gt; 👨‍💻&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@jajoosam/colorspace?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;That's it - I'd love to hear your thoughts and feedback 😄&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'm a 15 year old maker&lt;/em&gt; 👨‍💻  &lt;em&gt;For more cool things to make and to stay updated with my progress, sign up for &lt;a href="https://buttondown.email/jajoosam" rel="noopener noreferrer"&gt;my newsletter&lt;/a&gt;&lt;/em&gt; 📧&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>math</category>
      <category>canvas</category>
    </item>
    <item>
      <title>Build a WhatsApp Bot, fast ⚡</title>
      <dc:creator>Samarth Jajoo</dc:creator>
      <pubDate>Sat, 12 Jan 2019 04:34:35 +0000</pubDate>
      <link>https://dev.to/jajoosam/build-a-whatsapp-bot-fast--2hdc</link>
      <guid>https://dev.to/jajoosam/build-a-whatsapp-bot-fast--2hdc</guid>
      <description>&lt;p&gt;A few months ago, I'd started making chatbots on &lt;a href="https://t.me" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; - I'd seen some APIs for WhatsApp but they were unoffical and there was a chance for getting your number blocked 📱 ❌ &lt;/p&gt;

&lt;p&gt;A while ago, I saw that &lt;a href="https://twilio.com" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt; had an official WhatsApp API. 30 minutes later, I made a &lt;a href="https://wikibot.4ty2.fun" rel="noopener noreferrer"&gt;Wikipedia bot on WhatsApp&lt;/a&gt; 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3i0va2iwhdjjyuh1394z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3i0va2iwhdjjyuh1394z.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a tutorial to help you make a something like this, your own chatbots on WhatsApp - these bots are immediately available to over 2 billion users, and there are so many things possible 🎓&lt;/p&gt;

&lt;p&gt;I can't wait to see what you make! Now, let's get started 🏃‍♂️&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑  Accounts and Keys
&lt;/h2&gt;

&lt;p&gt;First, Sign up for &lt;a href="https://www.twilio.com/try-twilio" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt; - it's free and you won't need a credit card 💳&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbb54j7m5r7h8xfauy19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbb54j7m5r7h8xfauy19.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you're done verifying your phone number, select Procuts &amp;gt; Programmable SMS and then continue to name your project. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzkqoowxlkdf5bf0uzpv6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzkqoowxlkdf5bf0uzpv6.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to skip steps for adding teammates - you won't need that for now.&lt;/p&gt;

&lt;p&gt;You must now take note of some authentication keys you'll need for building the WhatsApp bot 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudl91c9oy856dwhybicf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudl91c9oy856dwhybicf.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step - setup your WhatsApp Sandbox &lt;a href="https://www.twilio.com/console/sms/whatsapp/sandbox" rel="noopener noreferrer"&gt;here&lt;/a&gt; - choose any number, and join your sandbox following instructions on the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhf3n6hza7nuh5vx1ij0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhf3n6hza7nuh5vx1ij0f.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aaaaaand you're done with credential setup! Don't worry, that was the toughest part of this tutorial 😛&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀  Getting Started
&lt;/h2&gt;

&lt;p&gt;So that we don't spend too much time on setup, I've created an environment (with &lt;a href="https://repl.it" rel="noopener noreferrer"&gt;repl.it&lt;/a&gt;!) you can use within your browser. Head over &lt;a href="https://repl.it/@jajoosam/wikibot-start" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and wait for a couple of seconds to fork it.&lt;/p&gt;

&lt;p&gt;Next, &lt;a href="https://repl.it/site/docs/repls/secret-keys" rel="noopener noreferrer"&gt;create a &lt;code&gt;.env&lt;/code&gt; file&lt;/a&gt; -  and put in your Account SID and Auth Token, on lines &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;SID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX &lt;span class="c"&gt;# Account SID&lt;/span&gt;
&lt;span class="nv"&gt;KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX &lt;span class="c"&gt;# Auth Token&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;You can see, this environment already has dependencies installed, and an &lt;code&gt;express&lt;/code&gt; server set up. We still need to give Twilio a URL to send incoming messages to, though 🔗&lt;/p&gt;

&lt;p&gt;Let's go back to the &lt;a href="https://www.twilio.com/console/sms/whatsapp/sandbox" rel="noopener noreferrer"&gt;WhatsApp Sandbox&lt;/a&gt;, and put in a webhook URL for incoming messages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkl3oksle8axgcvoxydwo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkl3oksle8axgcvoxydwo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This URL must be what you see on the preview panel of your &lt;a href="http://repl.it" rel="noopener noreferrer"&gt;repl.it&lt;/a&gt; project + &lt;code&gt;/incoming&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2dyem6smvvc03v0dmgq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy2dyem6smvvc03v0dmgq.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can now finally read messages that are sent to the bot. Navigate to &lt;code&gt;index.js&lt;/code&gt; and then add a simple &lt;code&gt;console.log()&lt;/code&gt; in your webhook handler 👇&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/incoming&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;When you send a message to your bot, you should be able to see something like this in your repl console 👨‍💻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvghtxy7mb9wb1ykgikcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvghtxy7mb9wb1ykgikcl.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building an echo bot would look something like this, using &lt;code&gt;twiml&lt;/code&gt; to write a message 👇&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/incoming&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;twiml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessagingResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;twiml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;twiml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;But, since we're actually trying to build a useful bot - let's use informative APIs!&lt;/p&gt;
&lt;h2&gt;
  
  
  🌐  Fetching Information
&lt;/h2&gt;

&lt;p&gt;DuckDuckGo has an amazing, free instant answer API. It takes in a query and returns back a summary from WikiPedia and more.&lt;/p&gt;

&lt;p&gt;A few examples 👉  &lt;a href="https://api.duckduckgo.com/?skip_disambig=1&amp;amp;format=json&amp;amp;pretty=1&amp;amp;q=WikiPedia" rel="noopener noreferrer"&gt;WikiPedia&lt;/a&gt;, &lt;a href="https://api.duckduckgo.com/?skip_disambig=1&amp;amp;format=json&amp;amp;pretty=1&amp;amp;q=MacBook%20Air" rel="noopener noreferrer"&gt;Macbook Air&lt;/a&gt;, &lt;a href="https://api.duckduckgo.com/?skip_disambig=1&amp;amp;format=json&amp;amp;pretty=1&amp;amp;q=Twilio" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I spent some time creating a decent parser which usually returns information from this API. Try pasting this code in your &lt;a href="http://repl.it" rel="noopener noreferrer"&gt;repl.it&lt;/a&gt; project, and your &lt;a href="https://dsh.re/f7477c" rel="noopener noreferrer"&gt;console&lt;/a&gt; should have stuff about Trump in it 😛&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.duckduckgo.com/?skip_disambig=1&amp;amp;format=json&amp;amp;pretty=1&amp;amp;q=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Donald Trump&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Abstract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Abstract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RelatedTopics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;   
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Abstract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Pretty straight forward, right? 😄&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️  Putting it all together
&lt;/h2&gt;

&lt;p&gt;To make our actual bot, all we need to do is get the query from our request - which we can get as &lt;code&gt;req.body.Body&lt;/code&gt; - and use &lt;code&gt;twmil&lt;/code&gt; to send across the data we collected in &lt;code&gt;msg&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/incoming&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;twiml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessagingResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.duckduckgo.com/?skip_disambig=1&amp;amp;format=json&amp;amp;pretty=1&amp;amp;q=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Abstract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Abstract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RelatedTopics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;   

        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;twiml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Abstract&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
            &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;twiml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;You now have a fully functionaing WhatsApp bot! Send anything you want to know about your bot 🤖  and you should see it respond super fast 💬 ⚡&lt;/p&gt;

&lt;p&gt;Adding welcome messages and a little formatting is quite simple, look at the final &lt;a href="https://repl.it/@jajoosam/wikibot" rel="noopener noreferrer"&gt;repl&lt;/a&gt; to see how I did it 👨‍💻&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@jajoosam/wikibot?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  🔗  Sharing the bot
&lt;/h2&gt;

&lt;p&gt;For others to use this bot, they'll need to join your sandbox first - and send a message just like you did earlier 👉  &lt;code&gt;join &amp;lt;two-words&amp;gt;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;You can create links with this text too - For example this link lets you join my bot 👇&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

https://wa.me/14155238886?text=join ultramarine-tapir


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;14155238886&lt;/code&gt; is my bot's number, while &lt;code&gt;ultramarine-tapir&lt;/code&gt; is the sandbox phrase.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚡ What's next?
&lt;/h2&gt;

&lt;p&gt;Now that you know how to build a bot on WhatsApp, try sending notifications to yourself, and building more useful tools! Twilio has loads of &lt;a href="https://www.twilio.com/channels" rel="noopener noreferrer"&gt;other mediums&lt;/a&gt; to message through too!&lt;/p&gt;

&lt;p&gt;All code for my WikiBot is on &lt;a href="https://github.com/jajoosam/wikibot" rel="noopener noreferrer"&gt;Github&lt;/a&gt; ⬇️&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jajoosam" rel="noopener noreferrer"&gt;
        jajoosam
      &lt;/a&gt; / &lt;a href="https://github.com/jajoosam/wikibot" rel="noopener noreferrer"&gt;
        wikibot
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A WikiPedia bot for WhatsApp
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;WhatsApp WikiBot&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Powered by Twilio WhatsApp API and DuckDuckGo Instant Search API 🤖&lt;/p&gt;

&lt;p&gt;\ ゜o゜)ノ&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jajoosam/wikibot" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;I'm a 15 year old maker 👨‍💻  For more cool things to make and to stay updated with my progress, sign up for &lt;a href="https://buttondown.email/jajoosam" rel="noopener noreferrer"&gt;my newsletter 📧&lt;/a&gt;&lt;/p&gt;

</description>
      <category>twilio</category>
      <category>replit</category>
      <category>whatsapp</category>
      <category>chatbot</category>
    </item>
    <item>
      <title>How I went from not knowing how to code to shipping 9 projects in 9 months — all before my 15th birthday</title>
      <dc:creator>Samarth Jajoo</dc:creator>
      <pubDate>Thu, 23 Aug 2018 14:30:57 +0000</pubDate>
      <link>https://dev.to/jajoosam/how-i-went-from-not-knowing-how-to-code-to-shipping-9-projects-in-9-monthsall-before-my-15th-birthday-go9</link>
      <guid>https://dev.to/jajoosam/how-i-went-from-not-knowing-how-to-code-to-shipping-9-projects-in-9-monthsall-before-my-15th-birthday-go9</guid>
      <description>&lt;p&gt;Hi dev community! I published this on the &lt;a href="https://medium.freecodecamp.org/how-i-went-from-not-knowing-how-to-code-to-shipping-9-projects-in-9-months-all-before-my-15th-7ec3666072c3"&gt;freecodecamp medium&lt;/a&gt; a few months ago, just joined thus community and am reposting!&lt;/p&gt;

&lt;p&gt;I’ve been making (a lot of) things for about a year now. Most of my time is spent hacking, building, and learning.&lt;/p&gt;

&lt;p&gt;This is the story of how I got started coding. I’ll share how I overcame the challenges of procrastinating and being lost, and how I built nine apps in nine months and discovered what I love doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How reading got me into tech
&lt;/h2&gt;

&lt;p&gt;It all started with reading books. I really enjoy reading, so I got my Dad to buy me a Kindle — and I loved it! I used it for about an hour every day for the first six months or so. I even wrote a review for it, which got published by a local newspaper 📰&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U3cCsZZ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ARfOBmArFTJyu3leW." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U3cCsZZ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ARfOBmArFTJyu3leW." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;11 year old&lt;/strong&gt; me had a few ideas to make the Kindle cooler, so I wrote an email to &lt;strong&gt;JEFF BEZOS&lt;/strong&gt;. THIS EMAIL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rYZyIal---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2132/0%2AxqhenVa_QfFpJJX7." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rYZyIal---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2132/0%2AxqhenVa_QfFpJJX7." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How did I know Jeff Bezos’ email? I didn’t. I just tried googling but wasn’t sure what it would be, so I put in all the combinations of jeff and bezos and his initials that I could think of.&lt;/p&gt;

&lt;p&gt;One of them must have gone through, because about two months later, my mom got a call asking for me. I had put her phone number in the email.&lt;/p&gt;

&lt;p&gt;This was the conversation I remember having:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Amazon Guy (A):&lt;/strong&gt; Hi, is this Samarth?&lt;br&gt;
&lt;strong&gt;Me:&lt;/strong&gt; Yes this is Samarth. Samarth is my name. You can also call me Sam.&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Great, I’m &lt;em&gt;name of amazon guy&lt;/em&gt;! Sam, you had written an email to Jeff Bezos a while ago, I’m calling to talk to you about that. We would love to hear your ideas about Amazon and Kindle — and it would be great to have you over to our Chennai Office, where we make Kindle and more devices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this point, I’m confused about if this is real or if someone is joking with me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Let me put you on hold for a minute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mutes phone, goes to parents. Tells them what happened. They say continue talking.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Wow that would be amazing! Can you give me a few more details?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Sure, we’re ready to have you and your parents over whenever you can come this month, and we will book your tickets and your stay. You’ll be coming over to our office, and you can look at some cool new stuff we’re building and even meet the team to share your ideas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now I’m sure this is fake, it couldn’t be real… right?!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; That sounds great! Can I talk this over with my parents and get back to you?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Sure — I’ve written an email to you, just reply back.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I spent the next 30 minutes googling the guy’s name. I looked at different LinkedIn profiles to check if he actually worked at Amazon and if this was actually real. After realizing he really was, I was crazy excited.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Two weeks later, my parents and I visited Amazon’s Chennai office.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hbGeJY3e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AgVwiWI1wD2YESe23." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hbGeJY3e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AgVwiWI1wD2YESe23." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I met their team and I saw people at their office who had hacker type screens and were typing some stuff. When I asked the person who was giving me the tour, she said, “It’s Programming” and that they were doing it to make an app for Kindle. I knew what apps were, since the games I played on my iPad were apps, too.&lt;/p&gt;

&lt;p&gt;That’s where I think it all started. I wanted to learn how to program to build my own apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Catching the programming bug
&lt;/h2&gt;

&lt;p&gt;When I went back home, I googled programming. I got a list of like a million Python tutorials and other stuff that seemed really complex for me to start with. So I forgot about it, and went back to reading.&lt;/p&gt;

&lt;p&gt;A year later, I realized that there were all these websites on the internet, and I wanted to make my own. So I googled how to do that, and went on to do a tutorial on &lt;a href="http://codecademy.com"&gt;codecademy.com&lt;/a&gt;. I built a small, quite ugly looking website. It was interesting — I had published something that I’d made, and the whole world could see it!&lt;/p&gt;

&lt;p&gt;But I wanted my website to actually do something, and not just be an ugly looking word document on the internet. It turns out I had to learn this thing called JavaScript to make my website “interactive.” So, I googled How to learn Javascript and took all the courses I could find. &lt;strong&gt;All of them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My dad probably spent thousands of rupees on these courses.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  &lt;em&gt;I learned loops and arrays and functions and recursions and scopes and loads of other concepts. But what I didn’t learn is what I actually took up coding for. — Making Something.&lt;/em&gt;
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think I got so obsessed with learning to code that I forgot why I took it up. When people asked me why I was learning to code, my reply was a terrible, boring because it's an important skill.&lt;/p&gt;

&lt;p&gt;It took me more than a year to realize what I was doing, and that happened because of the amazing people I met online in different communities. 🌐&lt;/p&gt;

&lt;h2&gt;
  
  
  Remembering my “why”
&lt;/h2&gt;

&lt;p&gt;The first community I joined was &lt;a href="https://hackclub.com/"&gt;&lt;strong&gt;Hack Club&lt;/strong&gt;&lt;/a&gt;— A group of high schoolers, just like me, who were coding! There were people in Hack Club who started their own coding clubs in schools to teach their peers how to code — but that’s not the part that really interested me.&lt;/p&gt;

&lt;p&gt;Hack Club introduced me to this thing called “&lt;strong&gt;Shipping&lt;/strong&gt;” — it means making something, and then sharing it for the world to see/use.Seems pretty straightforward, right? Lots of people in Hack club made their own small projects and then put them up on the #ship-it channel on Slack. They got great feedback and ideas about their apps. 👨‍💻&lt;/p&gt;

&lt;p&gt;I joined another amazing community called &lt;a href="https://feathrd.github.io/"&gt;&lt;strong&gt;Feathrd&lt;/strong&gt;&lt;/a&gt;. Again, it was a bunch of student makers who were making some crazy things while being in school! There were people who had 1000s of stars on their Github Repos ⭐ and who had earned actual money from their apps. Wow!&lt;/p&gt;

&lt;p&gt;I was super inspired — and then it hit me: I didn’t need to learn to code, what I needed to do was make something and ship it🛠️.&lt;/p&gt;

&lt;p&gt;So, I spent three hours doing nothing but trying to come up with ideas about what to make. But I wasn’t able to come up with anything. I was &lt;strong&gt;blank&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting some inspiration
&lt;/h3&gt;

&lt;p&gt;My first project came to me while I was looking to download a book and get some info about it . I wanted to build an interface to make it much easier and cleaner to do this.&lt;/p&gt;

&lt;p&gt;You’d think (at least I thought) that it would be super easy to do, because I’d been “learning to code” for about a year. But it wasn’t.&lt;/p&gt;

&lt;p&gt;I had no idea where to start. So I asked on the Slack channels of the communities I’d joined — HackClub and Feathrd. I learned that I needed to use this thing called an API to get data from book vendors, and that they would send me another thing called JSON.&lt;/p&gt;

&lt;p&gt;I was super confused (even after googling!). Even though I was a little embarrassed, I asked for a deeper explanation on what those terms meant. Fortunately, people were super nice and helped me understand.&lt;/p&gt;

&lt;p&gt;I’d just learned something really important: &lt;strong&gt;don’t be afraid to ask for help (once you’ve tried googling).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A week later, I had this &lt;a href="https://libert-cli.glitch.me/"&gt;terminal app&lt;/a&gt; ready, which downloaded a book to your computer! This was my first time shipping something 🚀 and I learned more in a week than I had learned in the entire past year! I had actually made something useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;TL;DR:&lt;/strong&gt; go make something instead of taking courses
&lt;/h2&gt;

&lt;p&gt;After my first ship, I built &lt;a href="https://jajoosam.tech/code/"&gt;a guide about to learning to code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I continued to work on my terminal app. In the span of three months, it evolved into an actual &lt;a href="https://libert.ml/"&gt;web app&lt;/a&gt;! And that was when I got addicted to shipping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After that, I shipped nine apps in the next nine months.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I never intended to make nine apps in nine months. There have been months where I haven’t made anything at all, and there have been weeks in which I’ve shipped multiple projects. That’s because I usually get my ideas by solving an immediate problem I have, or by looking at some cool tech that I quickly came up with a use case for (or both!).&lt;/p&gt;

&lt;p&gt;Take &lt;a href="https://chhota.ga"&gt;Chhota&lt;/a&gt; for example — a URL shortener I made in a weekend. I wanted to shorten URLs with my own domain, but didn’t want to have to set up a whole server, or pay $99 to &lt;a href="http://bit.ly"&gt;bit.ly&lt;/a&gt;. Chhota is a JS script that would fit in a tweet (even before 280 characters!) and shortens URLs by redirecting them to Google’s URL shortener.&lt;/p&gt;

&lt;p&gt;For example: &lt;a href="http://jajoosam.tech/#%24mR2d"&gt;jajoosam.tech/#$mR2d&lt;/a&gt; becomes &lt;a href="http://goo.gl/mR2d"&gt;goo.gl/mR2d&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I built my apps during weekends, or in the little free time I got after school. It wasn’t that hard to get ideas — I had no threshold for working on an idea.&lt;/p&gt;

&lt;p&gt;My workflow was:&lt;/p&gt;

&lt;p&gt;Get idea ⇒ Share Idea ⇒ Get Ideas about building idea ⇒ Build ⇒ Ship 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  Work in Progress
&lt;/h3&gt;

&lt;p&gt;What actually helped me ship consistently was being a part of this community called &lt;a href="https://wip.chat"&gt;WIP — Work in Progress&lt;/a&gt; 🚧. WIP is a community with some really, really cool makers and bootstrappers — who talk on a telegram group 💬 and keep track of their ship goals publicly.&lt;/p&gt;

&lt;p&gt;I became active in WIP after I saw a request for an app from Pieter Levels (!!!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hIaAdiHT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2216/0%2ACLcyHdWjRRpx7Grl." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hIaAdiHT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2216/0%2ACLcyHdWjRRpx7Grl." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Woof Wooferson = Pieter Levels&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My response was to create &lt;a href="https://www.producthunt.com/posts/syncr"&gt;an app built in 24 hours&lt;/a&gt; called Syncr.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--516ljz5C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2222/0%2A_KAGKRrdqV7UycRx." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--516ljz5C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2222/0%2A_KAGKRrdqV7UycRx." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To date, &lt;a href="https://www.producthunt.com/posts/syncr"&gt;Syncr&lt;/a&gt; has gotten me almost a hundred dollars — thanks for the idea &lt;a class="comment-mentioned-user" href="https://dev.to/levelsio"&gt;@levelsio&lt;/a&gt;
 😄&lt;/p&gt;

&lt;h3&gt;
  
  
  Making it all public
&lt;/h3&gt;

&lt;p&gt;I launched everything on &lt;a href="https://www.producthunt.com"&gt;&lt;strong&gt;Product Hunt&lt;/strong&gt;&lt;/a&gt;,where I got some great feedback and usually quite a few upvotes. I’ve even reached the top five products a couple of times!&lt;/p&gt;

&lt;p&gt;Getting shout-outs on Product Hunt was super motivating, as was being on top of Hacker News (which has happened twice 😉 )!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3gNBKZ73--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2456/0%2AakQDq_cz4GeT1DE8." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3gNBKZ73--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2456/0%2AakQDq_cz4GeT1DE8." alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It feels really cool to build something that people like using — and even pay me for! But I create mostly for the fun of it. It feels like an achievement being on the front pages of Hacker News and Product Hunt, and there’s this great dopamine rush every time I &lt;a href="https://wip.chat/@jajoosam/"&gt;ship on WIP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And then the CEO of Fog Creek and &lt;a href="https://glitch.com"&gt;glitch&lt;/a&gt; (!! — an amazing tool I’ve used to build almost all of my apps) tweeted at me:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--kgjQyJgw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1002676604739481601/lY0U3L2z_normal.jpg" alt="Anil Dash profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Anil Dash
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @anildash
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B8bbACBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-99c56e7c338b4d5c17d78f658882ddf18b0bbde5b3f42f84e7964689e7e8fb15.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      This kid is killing it with his @Glitch apps. So fun to watch! &lt;a href="https://t.co/KIExGeToJn"&gt;twitter.com/jajoosam/statu…&lt;/a&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      10:59 AM - 04 May 2018
    &lt;/div&gt;

      &lt;div class="ltag__twitter-tweet__quote"&gt;
        &lt;div class="ltag__twitter-tweet__quote__header"&gt;
          &lt;span class="ltag__twitter-tweet__quote__header__name"&gt;
            Samarth Jajoo
          &lt;/span&gt;
          @jajoosam
        &lt;/div&gt;
        My 10th project on @ProductHunt, And 5th on the frontpage of Show HN!

https://t.co/cifbPY2WrZ

Wrish is a quick autosaving notepad ✏️⚡ which was built in 3 days.

🚧 Progress: https://t.co/9ldLDOuGuT
👨‍💻 Code at: https://t.co/eCnSt00m8i

Hosted @glitch 🐟
      &lt;/div&gt;

    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=992357976639004672" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=992357976639004672" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      4
      &lt;a href="https://twitter.com/intent/like?tweet_id=992357976639004672" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      35
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;As did NameCheap’s CEO:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--_8fKO-g---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/612960681734877184/q8FUEt5T_normal.jpg" alt="Richard Kirkendall profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Richard Kirkendall
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @namecheapceo
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B8bbACBj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-99c56e7c338b4d5c17d78f658882ddf18b0bbde5b3f42f84e7964689e7e8fb15.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      &lt;a href="https://twitter.com/yesnoornext"&gt;@yesnoornext&lt;/a&gt; &lt;a href="https://twitter.com/jajoosam"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/jajoosam"&gt;@jajoosam&lt;/a&gt; &lt;a href="https://twitter.com/jajoosam"&gt;&lt;/a&gt;&lt;a href="https://twitter.com/jajoosam"&gt;@jajoosam&lt;/a&gt; do you need a job? ;)
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      13:59 PM - 04 May 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=992403229005811712" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=992403229005811712" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      0
      &lt;a href="https://twitter.com/intent/like?tweet_id=992403229005811712" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      13
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;That was really exciting!&lt;/p&gt;

&lt;p&gt;I’ve had a little more than 80k users/visitors according to Google Analytics. The fact that 80,000 people across the world have seen something I’ve made makes me really happy :)&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’ve learned
&lt;/h2&gt;

&lt;p&gt;I’ve never worked on a project for too long — I’ve always built everything within three months, and most of my apps were built in a weekend or two. I was able to ship super quick because I was always &lt;strong&gt;working my way around&lt;/strong&gt; problems, instead of really trying to address them. I’m a legit Hacker.&lt;/p&gt;

&lt;p&gt;The database for all my projects (at this point) is a text file that I read from and write to. That’s what I knew how to do, and I’ve never had any proper sort of authentication on my apps. On the one hand, this is great. It allows me to hack my way around to ship super quickly and build an MVP to see what people think.&lt;/p&gt;

&lt;p&gt;But that’s the thing — none of my projects have really moved beyond an MVP. There are two reasons for this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I’m not patient, and am pretty addicted to shipping something new as soon as I can&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I’m using an old toolbox, and I don’t solve problems but only temporarily work around them&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Moving forward
&lt;/h3&gt;

&lt;p&gt;I want to change this and build a real, finished &lt;strong&gt;product.&lt;/strong&gt; I’m going to do that by continuing to make loads of MVPs while remaining focused on building a great product. I want it to be something for which I solve the problems and upgrade my toolbox of tech when I need to.&lt;/p&gt;

&lt;p&gt;Some cool things I want to do in the future (soon!) are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Build native mobile apps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build a smart contract and see what the hype is about&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build hardware projects (I already have a few ideas!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build apps that look good 👀&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monetize, and get some nice MRR! 💵&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lessons learned
&lt;/h3&gt;

&lt;p&gt;These are some of the key points I’ve learned (so far!) on this crazy coding journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Don’t forget the reason you’re doing something. For me, this was forgetting why I was learning to code. This is probably the reason there’s a two year gap between when I learned to code and when I started building things.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Courses don’t always work (for me at least — &lt;a href="https://jajoosam.tech/code"&gt;jajoosam.tech/code&lt;/a&gt;) I think the best way to learn is by making. Learn something by doing it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a community which motivates and helps you, and in which you motivate + help others (WIP + feathrd + hackclub for me)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document what you do &lt;a href="https://WIP.chat/@jajoosam"&gt;WIP.chat/@jajoosam&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not everything has to be structured and well built. It’s okay to hack something together and work around problems to build something quickly. (Not for everything though)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So here are the 9 projects!
&lt;/h2&gt;

&lt;p&gt;In chronological order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🦕 &lt;a href="https://www.producthunt.com/posts/urbansaurus"&gt;Urbansaurus — Urban Vocabulary in Google&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔗 &lt;a href="https://www.producthunt.com/posts/chhota"&gt;Chhota — A front end URL shortener without a database&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📜 &lt;a href="https://www.producthunt.com/posts/pagiga"&gt;Pagiga — Dead simple markdown blogging with google forms&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;💵 &lt;a href="https://www.producthunt.com/posts/ernr"&gt;Ernr — Get donations without people paying&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🎧 &lt;a href="https://www.producthunt.com/posts/syncr"&gt;Syncr — Build a podcast out of youtube videos&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔔 &lt;a href="https://www.producthunt.com/posts/pingr"&gt;Pingr — Get notified when it’s important&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📝 &lt;a href="https://www.producthunt.com/posts/writt"&gt;Writt — Make rich, shareable notes within telegram&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📊 &lt;a href="https://www.producthunt.com/posts/polltime"&gt;Polltime — Textable polls that work everywhere&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✏️ &lt;a href="https://www.producthunt.com/posts/wrish"&gt;Wrish — A quick autosaving notepad in the browser&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’d like to hear from me when I launch a new project, write a new story, or some other cool thing ;) — sign up here 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://buttondown.email/jajoosam"&gt;https://buttondown.email/jajoosam&lt;/a&gt; ✉️&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks &lt;a href="https://twitter.com/justvidyadhar"&gt;Vidyadhar Sharma&lt;/a&gt; for reading drafts, and helping edit this story.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>teenmaker</category>
      <category>entreprenaurship</category>
      <category>lifelessons</category>
    </item>
  </channel>
</rss>
