<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Code Blogs]]></title><description><![CDATA[Code Blogs]]></description><link>https://blogs.learnin60seconds.com</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 19:33:16 GMT</lastBuildDate><atom:link href="https://blogs.learnin60seconds.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Avoiding common errors during SageMaker deployment]]></title><description><![CDATA[Disclaimer: Consistent with the honor code, no solutions are provided here, only hints to help troubleshoot two common errors
While working on the Deep Learning capstone “Deploying a Sentiment Analysis Model” project, most of my time was spent troubl...]]></description><link>https://blogs.learnin60seconds.com/avoiding-common-errors-during-sagemaker-deployment-598453e81cb1</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/avoiding-common-errors-during-sagemaker-deployment-598453e81cb1</guid><category><![CDATA[AWS]]></category><category><![CDATA[backend]]></category><category><![CDATA[hosting]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Sun, 07 Jun 2020 16:02:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771900144/rc_wmDbuV.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Disclaimer: Consistent with the honor code, no solutions are provided here, only hints to help troubleshoot two common errors</p>
<p>While working on the Deep Learning capstone “Deploying a Sentiment Analysis Model” project, most of my time was spent troubleshooting two common errors. They were <em>ResourceLimitExceeded </em>error and a CORS error of <em>CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.</em></p>
<h2 id="resource-limit-error">Resource Limit Error</h2>
<p>The error I got was <em>“ResourceLimitExceeded: An error occurred (ResourceLimitExceeded) when calling the CreateTrainingJob operation: The account-level service limit ‘ml.p2.xlarge for training job usage”</em></p>
<p><strong>Fix</strong></p>
<p>You need to apply for a separate instance for training and deployment. <a target="_blank" href="https://udacity.zendesk.com/hc/en-us/articles/360037696812-How-do-I-request-a-limit-increase-for-my-p2-xlarge-instance-">This</a> Udacity resource suggests it does not matter whether you choose SageMaker Training or SageMaker Deployment</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771895420/_SGmK9GPi.png" alt /></p>
<p>It DOES matter. If you are doing the Udacity exercise for training (as below) you need to request the SageMaker Training Resource Type and not SageMaker Hosting.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771896873/rQTR7vaj9.png" alt /></p>
<p>The training and hosting(deployment) instances have to be requested separately even if it’s the same instance, for example, ml.m4.xlarge, you need to request twice and specify training and hosting.</p>
<p>My own error occurred because I had requested SageMaker Hosting and was trying to use it for training. After contacting AWS and consulting <a target="_blank" href="https://github.com/awslabs/amazon-sagemaker-examples/issues/307">online resources</a> I was able to resolve it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771898804/bRvXM_RVS.png" alt /></p>
<h2 id="cors-error">CORS error</h2>
<p>The error I got was <em>AWS sagemaker error has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. </em>However the error is NOT because we need to change a CORS setting</p>
<p><strong>Potential Fixes and hints:</strong></p>
<ol>
<li><p>For <em>Step 7 (again): Use the model for the web app </em>complete <em>all</em> the steps at one go, as many of the steps that follow interdependent</p>
</li>
<li><p>The endpoint needs to be deployed and running, if it is not running or not deployed, it will not work</p>
</li>
<li><p>The method used to execute the Lambda function is the endpoint created using API Gateway. This endpoint will be a URL that listens for data to be sent to it. So if the URL provided is not correct, an error is generated. Make sure you have the right endpoint in the lambda code. This was what was causing my error.</p>
</li>
</ol>
<h2 id="additional-resources">Additional Resources</h2>
<ul>
<li><p><a target="_blank" href="http://francescopochetti.com/is-this-movie-a-thrillerinvoking-a-sagemaker-deep-learning-model-in-an-end-to-end-serverless-web-application/">Is this movie a thriller</a>? Exposing a SageMaker Deep Learning Model in an end to end serverless web application</p>
</li>
<li><p><a target="_blank" href="https://github.com/awslabs/amazon-sagemaker-examples/issues/307">Resource limit when deploying</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[A super simple progressive SPA using IndexedDB and Cache API that anyone can build in a few hours]]></title><description><![CDATA[Over the past several months, I’ve had the fortune to develop Apps for Google Chromestore and one app that has more than half a million users (here’s my story, and be selected for Udacity’s Grow with Google.
As a part of this scholarship I got the ch...]]></description><link>https://blogs.learnin60seconds.com/a-super-simple-progressive-spa-using-indexeddb-and-cache-api-that-anyone-can-build-in-a-few-hours-85bcb3f6e0ed</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/a-super-simple-progressive-spa-using-indexeddb-and-cache-api-that-anyone-can-build-in-a-few-hours-85bcb3f6e0ed</guid><category><![CDATA[spa]]></category><category><![CDATA[progressive web apps]]></category><category><![CDATA[Databases]]></category><category><![CDATA[app development]]></category><category><![CDATA[APIs]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Sun, 25 Mar 2018 20:34:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771966916/vbX4yhqaf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Over the past several months, I’ve had the fortune to develop Apps for Google Chromestore and one app that has more than half a million users (here’s <a target="_blank" href="https://medium.com/@tanyagupta/i-dropped-my-cs-major-because-i-couldnt-do-a-bubble-sort-126e1242d86e">my story</a>, and be selected for <a target="_blank" href="https://medium.com/the-n00b-code-chronicles/my-udacity-experience-and-the-wonderful-strange-world-of-open-source-3301464e7ec7">Udacity’s Grow with Google</a>.</p>
<p>As a part of this scholarship I got the chance to work on open source group projects. I also developed an app that reflected my own history (as a former immigrant, and now a proud US citizen) and was a small attempt towards helping aspiring immigrants.</p>
<p>There are 100 civics questions on the naturalization test. During the naturalization interview, applicants are asked up to 10 questions from the list of 100 questions in English. You must answer correctly six (6) of the 10 questions to pass the civics test in English. This can be very hard for many immigrants. Some may know the answers but just getting up to speed on English. Others may want an interface that is more helpful than just the booklet.</p>
<p>So I used some of the code I had been developing earlier (you can see an early version <a target="_blank" href="https://myamerica.life">here</a> under citizenship test and completely revamped it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771964382/eBSxcR5L1.png" alt /></p>
<p>The questions are shown, but not the answers, at least not until you click “show answer” . Some questions are dependent on location and for those you need to select a state. For instance the screenshot here shows the Senator for the state of California.</p>
<p>You can check out the live demo <a target="_blank" href="https://tanyagupta.github.io/citi-app-demo/index.html">here</a> and the github repo <a target="_blank" href="https://github.com/tanyagupta/offline-uscitizenship-flashcards">here</a> under the development branch. And here is the <a target="_blank" href="https://github.com/tanyagupta/offline-uscitizenship-flashcards/wiki">wiki</a>. The UI is inspired by the wonderful design work of <a target="_blank" href="https://github.com/ahoef/es2015-flashcard-app">Alexandra Hoefinger</a>.</p>
<p>With all the learning from my PWA course, the scores were almost a perfect 100% on Lighthouse! Still trying to figure out the last bit to get to 100% on PWA.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771965674/KYg5dBHor.png" alt /></p>
<h2 id="here-are-my-main-noob-takeaways">Here are my main noob takeaways:</h2>
<ul>
<li><p>Although indexedDB is complicated, it is really worth the effort and <a target="_blank" href="https://twitter.com/jaffathecake">Jake Archibald</a>’s IndexedDB Promised <a target="_blank" href="https://github.com/jakearchibald/idb">library</a> makes it easier</p>
</li>
<li><p>Caching of static assets improves performance dramatically</p>
</li>
<li><p>Rather than develop stand alone functions for indexedDB it is far better to encapsulate all the functions within a variable</p>
</li>
<li><p>Write methods to get and set data (in my case I don’t have update and delete but you may want to use those too). See <a target="_blank" href="https://github.com/tanyagupta/offline-uscitizenship-flashcards/blob/development/static/js/scripts.js">link</a> in Github. This makes it much easier to do all the work you need to do with your data.</p>
</li>
<li><p><em>Check</em> to see if an object store exists before doing writing data (see code for details)</p>
</li>
<li><p>If you are making API calls, within the fetch statement, access the method you need from your idb variable and do stuff with your data</p>
</li>
</ul>
<p>I hope this write up including the code for the IndexedDB code and the Cache API code is helpful for someone else! If you need any help regarding use of IndexedDB, drop me a line but don’t forget to clap first :-)</p>
]]></content:encoded></item><item><title><![CDATA[The 5 super powers of ES6]]></title><description><![CDATA[This blog is about new ES6 features. Learning about ES6 is probably pretty straightforward for experienced folks. It wasn’t for me. As a part of Udacity’s Grow with Google challenge cohort where ES6 was covered, I see that I wasn’t alone. So here are...]]></description><link>https://blogs.learnin60seconds.com/the-5-super-powers-of-es6-84e62875eed6</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/the-5-super-powers-of-es6-84e62875eed6</guid><category><![CDATA[ES6]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Fri, 16 Mar 2018 23:57:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630772008931/-n4aZyO1C.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This blog is about new ES6 features. Learning about ES6 is probably pretty straightforward for experienced folks. It wasn’t for me. As a part of <a target="_blank" href="https://www.udacity.com/grow-with-google">Udacity’s Grow with Google challenge</a> cohort where ES6 was covered, I see that I wasn’t alone. So here are 5 new ES6 features written by a newbie for other newbies.</p>
<h2 id="default-function-parameters">Default function parameters</h2>
<p><strong>Before we start:</strong> You know what a function and a parameter is</p>
<p><strong>What it does</strong> The default function parameter allows you to set a default value for your parameter(s)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630772004704/IDSWGYL0A.jpeg" alt /></p>
<p><strong>Why is it useful ? </strong>Not all parameters are created equal. Sometimes if a parameter value is missing the code can crash badly. default allows the programmers a nice safety net.</p>
<p><strong>An example: </strong>Say you are writing a function that will perform a division by the value of one of its parameters. To avoid a division by zero you will have to do some detailed error checking.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">divide_old</span>(<span class="hljs-params">a, b</span>) </span>{
  <span class="hljs-comment">/* We have to make sure we have the right number of arguments and their values are not 0. We are simplifying here and assuming we are dealing only with positive numbers
*/</span>
  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">arguments</span>.length===<span class="hljs-number">2</span> &amp;&amp; <span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]&gt;<span class="hljs-number">0</span> &amp;&amp; <span class="hljs-built_in">arguments</span>[<span class="hljs-number">1</span>]&gt;<span class="hljs-number">0</span>){
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]/<span class="hljs-built_in">arguments</span>[<span class="hljs-number">1</span>]
  }
  <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-built_in">arguments</span>.length===<span class="hljs-number">1</span> &amp;&amp; <span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]&gt;<span class="hljs-number">0</span>){
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]/<span class="hljs-number">1</span>
  }
}
</code></pre><p>With the default value for the parameters in ES6 you can now write code as follows</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">divide</span>(<span class="hljs-params">a, b = <span class="hljs-number">1</span></span>) </span>{
  <span class="hljs-keyword">return</span> a / b;
}
</code></pre><p>This makes life a whole lot easier for both the user/caller of a function, who does not have to worry and of course for the function author.</p>
<p>For more see the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">MDN page</a></p>
<h2 id="fetch">Fetch</h2>
<p><strong>Before we start: </strong>you need to know what is a call to a REST API means and what JSON data is, and what JSON data processing is.</p>
<p><strong>What it does: </strong>Provides programmers with a really simple way to make calls to a REST API</p>
<p><strong>Why is it useful: </strong>REST APIs give you access to databases with rich information that your program can use. Before ES6 the most common ways of doing this was to use a third party library, with the most popular being jQuery’s <a target="_blank" href="http://api.jquery.com/jquery.ajax/">ajax</a>.</p>
<p><strong>An example: </strong>The example shows the mechanics of a fetch call and getting some JSON data. <strong>If you have done things the old way </strong>I am sure you can immediately appreciate the benefits.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetch_simple</span> (<span class="hljs-params">url</span>) </span>{
  fetch(url)
  .then (<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> {<span class="hljs-keyword">return</span> response.json()}) <span class="hljs-comment">// JSON parsing done for you</span>
  .then(<span class="hljs-function"><span class="hljs-params">data</span> =&gt;</span> {
      <span class="hljs-comment">// do whatever you want to do with the data</span>
  })
  .catch (<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"===we have an error==="</span>)
    <span class="hljs-built_in">console</span>.log(err.stack)
  })
}
</code></pre><p>For more see the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">MDN page</a></p>
<h2 id="sets">Sets</h2>
<p><strong>Before we start:</strong> You need to know arrays, and objects</p>
<p><strong>What it does:</strong> It’s an iterable collection of unique elements. However this is not about what it is, but rather what it can help you do.</p>
<p><strong>Why it is useful: </strong>You can very quickly remove duplicates from existing arrays.</p>
<h3 id="an-example-and-more">An example (and more):</h3>
<p>To remove duplicates just create a set from an array and then convert that set back to an array.</p>
<pre><code><span class="hljs-keyword">const</span> nums_with_duplicates = [<span class="hljs-number">1</span>,<span class="hljs-number">5</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>,<span class="hljs-number">5</span>,<span class="hljs-number">8</span>,<span class="hljs-number">23</span>,<span class="hljs-number">45</span>];

a_set = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(nums_with_duplicates);

<span class="hljs-keyword">const</span> nums_unique = [a_set]<span class="hljs-comment">// the [] changes the set back to an array</span>
</code></pre><p>While both objects and the new ES6 Map also provide the support for unique elements, Set preserves the iteration order of its elements. So when we need a collection where the order of iteration <em>and</em> uniqueness matter, Set comes upon top.</p>
<p>The pattern <code>[...new Set (array_with_duplicates)]</code> will always give you an array with the duplicates removed. Nice, right?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630772006076/4_oI4YKa8o.png" alt="Basic operations with a set" /><em>Basic operations with a set</em></p>
<p>The code to walk a set is also nice and compact</p>
<pre><code><span class="hljs-selector-tag">for</span> (const month of months) {
    <span class="hljs-selector-tag">console</span><span class="hljs-selector-class">.log</span>(month)
}
</code></pre><p>For more see the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set">MDN page</a></p>
<h2 id="rest-parameter-and-spread-operator">Rest parameter and Spread operator</h2>
<p><strong>Before we start: </strong>you need to know what arrays and parameters are. Also an iterable object</p>
<p><strong>What it does: </strong>
If you have been reading about ES6 and looking at code written in it I am sure you have seen the curious <code>...</code> three dots popping up everywhere. These three dots have two names and two very different meaning in ES6. The naming and the meaning depends on what section of the code they appear:</p>
<ul>
<li><p><code>...</code> is called a<strong> <em>rest parameter</em> </strong>when used in function declaration, for example, in <code>function foo (a, ...b){//do stuff}</code>, the dots <em>make</em> <code>b</code> a rest parameter. The dots also mean that the second parameter is an array with an unspecified number of elements.</p>
</li>
<li><p>Any other place you see those dots they are <strong><em>spread operator</em>s</strong>. The spread operators most commonly appear in array literals like this: <code>[...a, 4, 5,6]</code> Here also the dots represent an array of unspecified number of elements.</p>
</li>
</ul>
<p>The <code>a</code> must be an iterable object like arrays, strings and the ES6's new Maps and Sets.</p>
<p><strong>Why is it useful: </strong>When used as rest parameters, the dots “pack” many variables in to an array. So in the function <code>function foo (a, ...b){//do stuff}</code> if we call <code>foo</code> with <code>foo(5,6,9)</code>, this would mean that a is <code>5</code> and b, because of the three dots is an array<code>[6,9]</code></p>
<p>When used as a spread operator the dots “unpack” variables. See the following function:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span> (<span class="hljs-params">a, ...b</span>)</span>{ 
  <span class="hljs-built_in">console</span>.log(bar); 

<span class="hljs-comment">/* [6,9,10] Note it only starts from the second number because the first parameter is not part of the spread operator */</span>

  <span class="hljs-built_in">console</span>.log(...b);<span class="hljs-comment">// 6 9 10 //notice it unpacks [6,9,10] </span>

 }
bar(<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">9</span>,<span class="hljs-number">10</span>)
</code></pre><p>The first three dots are rest parameters and “pack” the variables into an array. The second set of three dots “unpack” the array into the individual elements. This makes it easier to work with arrays in functions.</p>
<p><strong>An example</strong></p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">foo</span> (<span class="hljs-params">a, ...rest</span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"\n\nvalue of the first param is  "</span> + a)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"the rest of the params are in an array: "</span>)
  <span class="hljs-built_in">console</span>.log(rest)
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"unpack them to a list as follows:"</span>)
  <span class="hljs-built_in">console</span>.log(...rest) 
  <span class="hljs-keyword">return</span> <span class="hljs-string">"Done"</span>
}

foo (<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">9</span>,<span class="hljs-number">11</span>) <span class="hljs-comment">// a will be assigned 5 and the rest will be [6,9,11]</span>
foo (<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,<span class="hljs-number">9</span>,<span class="hljs-number">11</span>, <span class="hljs-number">2</span>) <span class="hljs-comment">// a will be assigned 5 and the rest will be [6,9,11, 12]</span>
foo (<span class="hljs-number">5</span>) <span class="hljs-comment">// a will be assigned 5 and the rest will be empty</span>
foo (<span class="hljs-number">5</span>,<span class="hljs-number">6</span>,[<span class="hljs-number">9</span>,<span class="hljs-number">11</span>]) <span class="hljs-comment">// will be assigned 5 and the rest will be [6,[9,11]]</span>
</code></pre><p>Copy and paste the above to the console to see how it works</p>
<p>Feel free to dig deep into many interesting <a target="_blank" href="https://dmitripavlutin.com/how-three-dots-changed-javascript/">usecases for rest parameters and spread operators</a>.</p>
<p>But as a newbie I find the following two patterns very useful:</p>
<blockquote>
<p><em>The spread operator make array concatenation much more natural.</em></p>
</blockquote>
<p><code>joined_array = [...first_array, ...second_array, ...third_array]</code></p>
<blockquote>
<p><em>You can combine it with ES6 Sets to remove duplicate from arrays</em></p>
</blockquote>
<pre><code><span class="hljs-keyword">const</span> unique = [...<span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(non_unique)];
</code></pre><p>For more see the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">MDN page</a> and this <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">MDN page</a> too</p>
<h2 id="destructuring">Destructuring</h2>
<p><strong>Before we start:</strong> You need to know sets, arrays, parameters</p>
<p><strong>What it does: </strong>Destructuring allows a programmer to break a compound structure like an array or an object down to its elements (or properties in case of objects) and assign those “destructured” pieces to variables. <code>[a,b] = [1,2]</code> is now a valid Javascript statement, which assigns 1 to a, and 2 to b.</p>
<p><strong>Why it is useful: </strong>It makes code simpler and short. See example for more</p>
<h3 id="an-example-and-more"><strong>An example (and more):</strong></h3>
<p>Get rid of the pesky temp variable and three lines of code and swap variables in one shot.</p>
<pre><code><span class="hljs-keyword">var</span> a = <span class="hljs-number">1</span>;
<span class="hljs-keyword">var</span> b = <span class="hljs-number">3</span>;
[a, b] = [b, a]; <span class="hljs-comment">// </span>
<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 3</span>
<span class="hljs-built_in">console</span>.log(b); <span class="hljs-comment">// 1</span>
</code></pre><h3 id="parse-function-returns-like-a-pro">Parse function <code>returns</code> like a Pro</h3>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">f</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>];
}

<span class="hljs-keyword">var</span> a, b; 
[a, b] = f(); 
<span class="hljs-built_in">console</span>.log(a); <span class="hljs-comment">// 1</span>
<span class="hljs-built_in">console</span>.log(b); <span class="hljs-comment">// 2</span>
</code></pre><h3 id="remove-duplicates-from-arrays">Remove duplicates from Arrays</h3>
<p>Create a duplicate free arrays in one shot. This one needs to know Sets too!</p>
<pre><code><span class="hljs-keyword">const</span> unique = [...<span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(array_with_duplicates)];
</code></pre><ol>
<li><p>Create a set from the array_with_duplicates array, this will remove the duplicates</p>
</li>
<li><p>Use the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread</a> syntax to unpack the set elements</p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">“destructure”</a> the unpacked element back into an array</p>
</li>
</ol>
<p>For more see the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">MDN page</a></p>
<h2 id="and-finally-putting-everything-together">And finally putting everything together..</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630772007448/jSsklL-Mp.jpeg" alt="Javascript takes on the big guns" /><em>Javascript takes on the big guns</em></p>
<p>Many languages (such as Perl) are famous for allowing programmers to express fairly complicated commands in just one line. Javascript was never known for this. With ES6 it is slowly getting there.</p>
<p>Consider the following array that contains the month names when the temperature dipped below a threshold.</p>
<p><code>const low_temp_months = ['January','January', 'February', 'March','November', 'December','December'];</code></p>
<p>As you notice there are some duplicates perhaps caused by multiple readings submitted for the same month. If you want the month names to be unique you can do the following:</p>
<ol>
<li><p>Create a set from the low_temp_months array, this will remove the duplicates</p>
</li>
<li><p>Use the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread</a> syntax to unpack the set elements</p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">“Destructure”</a> the unpacked element back into an array</p>
</li>
</ol>
<p>All the three aspect can be implemented in a very nice one liner!</p>
<pre><code><span class="hljs-keyword">const</span> winter_months = [...<span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(low_temp_months)];
</code></pre>]]></content:encoded></item><item><title><![CDATA[My Udacity experience and the wonderful strange world of open source]]></title><description><![CDATA[Udacity sponsors a three month first round “Grow with Google Challenge Scholarship”.

When I applied to the Mobile Web Specialist track I was not sure what I would get out of Udacity. I considered myself a middling self-taught web programmer. (Here’s...]]></description><link>https://blogs.learnin60seconds.com/my-udacity-experience-and-the-wonderful-strange-world-of-open-source-3301464e7ec7</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/my-udacity-experience-and-the-wonderful-strange-world-of-open-source-3301464e7ec7</guid><category><![CDATA[Open Source]]></category><category><![CDATA[Mobile Development]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Fri, 16 Mar 2018 23:55:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771955393/RLfKqzpsw.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Udacity sponsors a three month first round “Grow with Google Challenge Scholarship”.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771944603/T5sSKSgaG.png" alt /></p>
<p>When I applied to the Mobile Web Specialist track I was not sure what I would get out of Udacity. I considered myself a middling self-taught web programmer. (Here’s a <a target="_blank" href="https://medium.com/@tanyagupta/i-dropped-my-cs-major-because-i-couldnt-do-a-bubble-sort-126e1242d86e">blog that documents my learning journey</a> and here’s the links (<a target="_blank" href="https://gsuite.google.com/marketplace/app/word_cloud_generator/360115564222?pann=gam">1 </a>and <a target="_blank" href="https://chrome.google.com/webstore/detail/word-cloud-generator/alhnlhbhnklajhmccemipdbaifocepab?authuser=0">2</a>) for my most popular app with over half million users). If I could learn anything I wanted to on my own, what would be Udacity’s value proposition for me ? So my expectations were fairly low even when I heard I got the scholarship. Fast forward three months.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771946153/EwROcsua-.png" alt /></p>
<blockquote>
<h1 id="i-am-blown-away-by-the-experience"><strong>I am blown away by the experience.</strong></h1>
</blockquote>
<p>Why ? Two words — <strong><em>community and open source.</em></strong></p>
<p>I quickly became part of a rich evolving learning community.</p>
<h2 id="four-specific-experiences-were-invaluable">Four specific experiences were invaluable:</h2>
<ul>
<li>For the first time in my life I worked on not just one but two open source projects, one of which I initiated both built around maps. One was the <a target="_blank" href="https://github.com/TheDevPath/googleMaps-offline-navigator">Navi project</a> with a very <a target="_blank" href="https://github.com/TheDevPath/googleMaps-offline-navigator/graphs/contributors">large team</a> and a great lead <a target="_blank" href="https://github.com/motosharpley">Bryan</a> who was very helpful. Another one was <a target="_blank" href="https://github.com/gwg-women/gwg-women-techmakers">Mappa</a> an <a target="_blank" href="https://github.com/gwg-women/gwg-women-techmakers/graphs/contributors">all women</a> project, one that I initiated just with <a target="_blank" href="https://github.com/khusbuchandra">Khusbu</a> but quickly grew to include some very talented and hardworking <a target="_blank" href="https://github.com/khusbuchandra">women</a>. Mappa started off with some of the code I used for a Udacity course using knockout js. Halfway through the project we switched to React, another interesting experience of changing track midway and managing the implications on the project timeline. On Navi, I focused on making documentation easy to read and understand. In the process I became familiar with git, github, learned to read other people’s code, realized the importance of documentation and much more.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771947770/chliXoNX4.jpeg" alt /></p>
<ul>
<li>Working with students from different programming backgrounds taught me a lot. There were absolute beginners, those with some experience, and others that with significant experience in open source and programming. With such a diversity of experience, collaboration is the only way the community moves together as a whole. The more experienced ones helped the less experienced ones, and the less experienced ones helped the more experienced by asking questions that need to be answered.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771949515/Nd9zBJsYG.jpeg" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771950998/oUYinI-kvz.png" alt /></p>
<ul>
<li><p>A community needs tools to grow and to communicate. Udacity chose Slack and Forums. What even Udacity could not predict was how the tools would be used. The organic growth and innovative use of the tools provided (Slack channel, forums) and tools not provided (Google Hangouts, opened issues on Github) was fascinating and could probably be a PhD in itself. Some folks started a list of useful resources, I wrote a tool to capture video captions from Udacity lessons and many others organized meetups and study sessions.</p>
</li>
<li><p>I was exposed to the advantages and disadvantages of the democratic experience where coders of different ability often have the same voice, and work together in a transparent atmosphere. You can join any channel you want, most ask for help when they need it without shame, and people are empowered to work on projects even if they don’t have much experience.</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771952447/Ws8nePNSe.jpeg" alt /></p>
<p>This led me to immediately contrast this way of working to the typical workplace that I am so used to — hierarchical, top down management structure, and with many black boxes.</p>
<p>Working on open source made me think about and reaffirm the importance of transparency, collaboration, balancing top-down design with bottom-up innovations in code and in life</p>
<p>Given the diversity of programming backgrounds, and seeing the difficulty in communication between those who knew a lot and those that were beginners, I have been inspired to tackle the gap: to really understand a topic in depth and create accessible materials that explain the topic to beginners or those with relatively less experience. This was the single biggest impact of the Udacity/Grow with Google experience on my life.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771954128/BKP5l2ZhU.jpeg" alt /></p>
]]></content:encoded></item><item><title><![CDATA[How to get multipage JSON results from Google and Zendesk APIs]]></title><description><![CDATA[This post is about two ways to handle pagination (getting multipage results) in response to queries on Google and Zendesk APIs
While most Web API provides multi page results to a call, most API documentation will only talk about how to get the first ...]]></description><link>https://blogs.learnin60seconds.com/how-to-get-multipage-results-from-web-apis-767df696923</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/how-to-get-multipage-results-from-web-apis-767df696923</guid><category><![CDATA[json]]></category><category><![CDATA[Google]]></category><category><![CDATA[APIs]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Mon, 02 Jan 2017 20:17:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771917754/h2MvMmxIU.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This post is about two ways to handle pagination (getting multipage results) in response to queries on Google and Zendesk APIs</p>
<p>While most Web API provides multi page results to a call, most API documentation will only talk about how to get the <strong>first page</strong> of those results.</p>
<h2 id="it-is-almost-impossible-to-find-guides-to-pagination">It is almost impossible to find guides to pagination!</h2>
<h3 id="zendesk-gets-a-b">Zendesk gets a B</h3>
<p>Here is an example from <a target="_blank" href="https://developer.zendesk.com/rest_api/docs/core/tickets">Zendesk</a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771913433/Jrsvaii8o.png" alt /></p>
<p>If at all they have instructions on pagination, it will be hidden away somewhere in the API documentation</p>
<p>Here’s the documentation on <a target="_blank" href="https://developer.zendesk.com/rest_api/docs/core/introduction#pagination">pagination</a> on Zendesk. This one was hard to find but not impossible.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771914847/zlYS5pz-S.png" alt /></p>
<h3 id="google-gets-an-f">Google gets an F</h3>
<p>Sometimes the instructions may be hidden way deeper than necessary. See below for a search on “pagination” on <a target="_blank" href="http://developers.google.com">http://developers.google.com</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771916348/v0I8yojsj.png" alt /></p>
<p>I am assuming the documentation people leave the details out because for most professional developers this is trivial.</p>
<p><strong>Not so for a newbie. </strong>
If you are a code n00b, you are have struggled with the stubborn OAuth, pored over API docs to get the perfect call that will get you the data for your app, and finally late in the evening, you are getting the data back! The last thing you want is to cross yet another hurdle.</p>
<p>So here’s what I have: <strong>There are two common ways API designers tell you that there are more pages of results.</strong></p>
<p><strong>One is via a next page field in the result</strong>, which will contain the url for the next page. If there are no next pages the field will not be present in the result. <a target="_blank" href="https://developer.zendesk.com/rest_api/docs/core/introduction#pagination">Zendesk</a> uses this approach.</p>
<p><strong>The other way is to return the token for the next page</strong>, which you append to your next call. Most Google APIs uses this approach. <a target="_blank" href="https://dev.twitter.com/ads/basics/pagination">Twitter</a> uses a similar next cursor key.</p>
<h3 id="in-either-case-the-solution-boils-down-to-the-following">In either case the solution boils down to the following</h3>
<ol>
<li><p>Have an array to store <strong>all</strong> the results</p>
</li>
<li><p>Make a call and get the result and push them to the array</p>
</li>
<li><p>Enter a loop if the next page field or page token is present</p>
</li>
<li><p>Make the new call either using the next page URL or the token</p>
</li>
<li><p>Get the result</p>
</li>
<li><p>Optionally — give the server a few milliseconds break. Be nice.</p>
</li>
<li><p>Here’s what I did for Zendesk. I used a do-while loop, but while-do works just fine of course.</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">zd_get</span> (<span class="hljs-params">cmd</span>) </span>{
  <span class="hljs-keyword">var</span> url = ZD_BASE+cmd;
  <span class="hljs-keyword">var</span> results =[];
  <span class="hljs-keyword">var</span> service = getService();

  <span class="hljs-keyword">if</span> (service.hasAccess()) {
    <span class="hljs-keyword">do</span> {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">var</span> response = UrlFetchApp.fetch(url, {<span class="hljs-attr">headers</span>: {<span class="hljs-string">'Authorization'</span>: <span class="hljs-string">'Bearer '</span> + service.getAccessToken(),}});
      }
      <span class="hljs-keyword">catch</span> (e) {
        <span class="hljs-keyword">return</span> e;

      }
      <span class="hljs-keyword">var</span> result = <span class="hljs-built_in">JSON</span>.parse(response.getContentText());
      results.push(result);
      url = result[<span class="hljs-string">'next_page'</span>];
      Utilities.sleep(<span class="hljs-number">250</span>); <span class="hljs-comment">// give the server a break</span>

    }  <span class="hljs-keyword">while</span> (result[<span class="hljs-string">'next_page'</span>] !=<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">return</span> results;
  }
  <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;

}
</code></pre>
<ol>
<li>Here’s what I did for a Google API call</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">zd_get</span> (<span class="hljs-params">cmd</span>) </span>{
  <span class="hljs-keyword">var</span> url = ZD_BASE+cmd;
  <span class="hljs-keyword">var</span> results =[];
  <span class="hljs-keyword">var</span> service = getService();

  <span class="hljs-keyword">if</span> (service.hasAccess()) {
    <span class="hljs-keyword">do</span> {
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">var</span> response = UrlFetchApp.fetch(url, {<span class="hljs-attr">headers</span>: {<span class="hljs-string">'Authorization'</span>: <span class="hljs-string">'Bearer '</span> + service.getAccessToken(),}});
      }
      <span class="hljs-keyword">catch</span> (e) {
        <span class="hljs-keyword">return</span> e;

      }
      <span class="hljs-keyword">var</span> result = <span class="hljs-built_in">JSON</span>.parse(response.getContentText());
      results.push(result);
      url = result[<span class="hljs-string">'next_page'</span>];
      Utilities.sleep(<span class="hljs-number">250</span>); <span class="hljs-comment">// give the server a break</span>

    }  <span class="hljs-keyword">while</span> (result[<span class="hljs-string">'next_page'</span>] !=<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">return</span> results;
  }
  <span class="hljs-keyword">else</span> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;

}
</code></pre>
]]></content:encoded></item><item><title><![CDATA[How to deploy a Node.js web app using Express in Cloud9]]></title><description><![CDATA[This post is about how simple it is to run a basic web app on Cloud9 if you can get past the jargon-heavy documentation on the Web. Read this “dejargonified” article, save time and hit the ground running right away.
Prerequisites

You are familiar wi...]]></description><link>https://blogs.learnin60seconds.com/how-to-deploy-a-node-js-web-app-using-express-in-cloud9-91e73910293f</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/how-to-deploy-a-node-js-web-app-using-express-in-cloud9-91e73910293f</guid><category><![CDATA[Express]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Mon, 05 Dec 2016 00:12:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771940072/Tk2vz28Z7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="this-post-is-about-how-simple-it-is-to-run-a-basic-web-app-on-cloud9httpsc9io-if-you-can-get-past-the-jargon-heavy-documentation-on-the-web-read-this-dejargonified-article-save-time-and-hit-the-ground-running-right-away">This post is about how simple it is to run a basic web app on <a target="_blank" href="https://c9.io">Cloud9</a> if you can get past the jargon-heavy documentation on the Web. Read this “dejargonified” article, save time and hit the ground running right away.</h3>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>You are familiar with basic Node (i.e. you know loops, if-thens etc.) and understand the basic <a target="_blank" href="https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/JS-Callback-Functions">callback</a> pattern.</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771932289/BLBgDgbOw.png" alt /></p>
<blockquote>
<p>For example, you are good to go if you have done (or can do) the Node challenges in <a target="_blank" href="https://twitter.com/ossia">Quincy Larson</a>’s <a target="_blank" href="https://twitter.com/freeCodeCamp">Free Code Camp</a></p>
</blockquote>
<ul>
<li><p>You are NOT an experienced programmer. You will be bored :-)</p>
</li>
<li><p>You have an account on <a target="_blank" href="https://twitter.com/cloud9_mobile">Cloud9</a> and you have <a target="_blank" href="https://docs.c9.io/v1.0/docs/create-a-workspace">created</a> a workspace on <a target="_blank" href="https://twitter.com/cloud9_mobile">Cloud9</a>.</p>
</li>
</ul>
<h2 id="terms">Terms</h2>
<ol>
<li><p><strong>Web Server:</strong> The Web is vast and complex but its core functionality is strikingly simple. The Web is built around two classes of programs: servers and requesters. Servers run continuously (unless they are “down”) and listen for requests for web pages. When it receives a request it provides a copy of that page (if it has access to it) to the requester.</p>
</li>
<li><p><strong>HTTP protocol: </strong>The communication convention these two classes of program use to talk to each other is the famous http protocol.</p>
</li>
<li><p><strong>Requesters, browsers and a web page: </strong>The requesters are programs that can ask for a specific web page from a server. A requester that can display the web page received from a server is what we know now as browsers. All browsers are requesters but not all requesters are browsers. For example, when you write some code to access and process <a target="_blank" href="https://medium.com/@tanyagupta/da10e81a035c#.quw44dphf">JSON data using web API</a>, your code is a requester and not a browser.</p>
</li>
<li><p><strong>Express:</strong> Express is a program that makes setting up your own web server very easy. It is a written in Node. Anything you can do in Express you can also do it in pure Node <a target="_blank" href="https://gist.github.com/tanyagupta/87bc01b561df839a275456c2183b1f68">but it is a lot of work</a>. Besides <a target="_blank" href="https://twitter.com/tjholowaychuk">TJ Holowaychuk</a> and <a target="_blank" href="https://twitter.com/nodejs">Node.js Foundation</a> <a target="_blank" href="https://github.com/expressjs/express/graphs/contributors">contributors</a>, have already solved the problem for us.</p>
</li>
</ol>
<h2 id="setting-up-express-creating-an-app-and-running-it-in-cloud9">Setting up express, creating an app and running it in Cloud9</h2>
<ol>
<li><a target="_blank" href="https://expressjs.com/en/starter/installing.html">Install express</a> in a directory of your choosing (see link for details)</li>
</ol>
<p><code>$ npm install express --save</code></p>
<ol>
<li>Create a new javascript file</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771933726/Wm1FlzLef.gif" alt /></p>
<ol>
<li>Use the code below</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">var</span> app = express();

app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) </span>{
  res.send(<span class="hljs-string">"&lt;h1&gt;hello world&lt;/h1&gt;"</span>);
});

app.listen(<span class="hljs-number">8080</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Example app listening on port 8080!'</span>);
  <span class="hljs-comment">//call this app from https://&lt;workspace name&gt;-&lt;user name&gt;.c9users.io</span>
});
</code></pre>
<ol>
<li>One challenge I had was that I did not know where the app was running. The typical <a target="_blank" href="http://localhost:8080/">*http://localhost:&lt;port number&gt;/</a> *as <a target="_blank" href="https://expressjs.com/en/starter/hello-world.html">referenced</a> in various express resources is not going to work since the app is running on Cloud9 servers and the command above works only to test apps running locally.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771935201/pemxpXrWd.png" alt /></p>
<p>On Cloud9 it will be http://&lt;<em>workspace name</em>&gt;-&lt;<em>user name</em>&gt;. If you’ve forgotten what these are, you can check in your browser window. For example in the picture here, the user name is <em>tanyagupta</em> (me) and the workspace name is <em>test</em>. Therefore in this case you would go to <a target="_blank" href="http://test-tanyagupta.c9users.io">http://test-tanyagupta.c9users.io</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771936751/bJ-RItKyu.gif" alt /></p>
<p>You can also use the preview button to do so.</p>
<p><strong>NOTE: </strong>The app “runs” only while you are logged in.</p>
<p>If you wanted to get into the details of the code, here is the same code, heavily marked up with comments:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Standard set up for the express code to work with your code</span>
<span class="hljs-keyword">var</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">var</span> app = express();

<span class="hljs-comment">/*

Routes a get request, and in this simple case - to the server's root. It sends a 
call back to handle the request. Not much will happen here, the call back is hardcoded  
to send a hello world string. But in theory you can do something with the req variable 
in the "/" directory, create a dynamic html and send that back
*/</span>

app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">req, res</span>) </span>{
  res.send(<span class="hljs-string">"&lt;h1&gt;hello world&lt;/h1&gt;"</span>);
});

<span class="hljs-comment">/*

Firing up your server. For most of us noobs - all that matters here is
a) remember the port number - 8080 (in this example). If you use some other port 
number make sure you mention it explicitly when you make a call to the server.
b) the console statement is just a note to tell you the server is running

 */</span>
app.listen(<span class="hljs-number">8080</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Example app listening on port 8080!'</span>);
  <span class="hljs-comment">//call this app from https://&lt;workspace name&gt;-&lt;user name&gt;.c9users.io</span>
});
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771938436/B2i2vxFdJ.gif" alt /></p>
]]></content:encoded></item><item><title><![CDATA[How to efficiently handle irregular JSON data:]]></title><description><![CDATA[Using Javascript logical operators && and ||
JSON
This post is about how I had been processing JSON data from Web API calls, why the approach I chose was “poor taste” code, and what I did to fix it.
Prerequisites

You are familiar with basic Javascri...]]></description><link>https://blogs.learnin60seconds.com/a-n00ber-pattern-for-taming-the-wild-data-web-da10e81a035c</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/a-n00ber-pattern-for-taming-the-wild-data-web-da10e81a035c</guid><category><![CDATA[json]]></category><category><![CDATA[Parse]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Mon, 05 Dec 2016 00:11:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771982262/rVBO27ZqO.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Using Javascript logical operators &amp;&amp; and ||</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771970327/pXJs2dp8g.png" alt="JSON" /><em>JSON</em></p>
<h3 id="this-post-is-about-how-i-had-been-processing-json-data-from-web-api-calls-why-the-approach-i-chose-was-poor-taste-code-and-what-i-did-to-fix-it"><strong>This post is about how I had been processing JSON data from Web API calls, why the approach I chose was “poor taste” code, and what I did to fix it.</strong></h3>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li><p>You are familiar with basic Javascript (i.e. you know loops, if-thens etc.).</p>
<blockquote>
<p>For example, you are good to go if you have done (or can do) the Basic JavaScript challenges in <a target="_blank" href="https://twitter.com/ossia">Quincy Larson</a>’s <a target="_blank" href="https://twitter.com/freeCodeCamp">Free Code Camp</a> (<a target="_blank" href="https://www.freecodecamp.com/map-aside#nested-collapseBasicJavaScript">link</a>)</p>
</blockquote>
</li>
<li><p>You have cursory knowledge of web APIs. (i.e. you <strong>know</strong> what they are used for). You know a bit about relational database and SQL.</p>
<blockquote>
<p>This does not mean you have actually used them in your code (although that would be nice).</p>
</blockquote>
</li>
<li><p>You are NOT an experienced programmer. You will be bored :-)</p>
</li>
</ul>
<h2 id="preamble-aka-why-this-post">Preamble (a.k.a. why this post?)</h2>
<p>The inspiration for this post comes from <a target="_blank" href="https://twitter.com/bartobri78">Brian Barto</a>’s thought provoking and popular (2.1 k recommends and counting) <a target="_blank" href="https://medium.com/@bartobri/applying-the-linus-tarvolds-good-taste-coding-requirement-99749f37684a#.xnta2qxv0">article</a> on “good taste” coding. <a target="_blank" href="https://twitter.com/bartobri78">Brian</a> used an example given by Linus Torvalds (<em>you know that guy who single handedly wrote the kernel of one of the world’s most robust, efficient and elegant operating system and gave it away for free</em>) in an interview to drive home some software development best practices. While I encourage everyone to read the article, my post here is about what <strong>I </strong>ended up doing after reading his article.</p>
<p>I am a <a target="_blank" href="https://medium.com/@tanyagupta/i-dropped-my-cs-major-because-i-couldnt-do-a-bubble-sort-126e1242d86e#.l6rxigrr0">self-taught</a> newbie hobbyist programmer. And my partner (in both code and in life) who is trained in “legacy” CS, says I am bit of a “code brat.” I code first, think (of algorithm and stuff) later. I code for my pleasure (i.e. not for money, for now). Once I get an app working and tested, I deploy it and never look back (well I do listen to user complains and fix them, but that is about it). Brian’s article nudged me to take a <strong>critical</strong> look at the code I have written over the last two years (as I learned Google Apps Script and built Google Doc/sheet Add-ons and web apps using Google App script).</p>
<p>It is humbling to find examples of “poor taste” programming in one’s own code. But it is fun to fix them and talking about them is almost therapeutic. In this post I will describe one such fix (the fancy word for it is refactoring).</p>
<h2 id="on-processing-the-data-web-using-apis-and-json">On processing the (data) web using APIs and JSON</h2>
<p>Web APIs give you access to databases with rich information that your program can use. Here’s an <a target="_blank" href="http://www.programmableweb.com/news/how-to-get-most-out-new-york-times-api-suite/how-to/2012/01/04">introduction with detailed example using the New York Times Web API.</a> Most modern Web APIs return data in JSON format. <a target="_blank" href="http://www.json.org/">JSON</a> is a subset of Javascript and parsing a string to a JSON (i.e. a Javascript) object is trivial.</p>
<p><code>var data = JSON.parse(string_result_of_api_call)</code></p>
<p>Boom! The Javascript object <code>data</code>now contains all the information that was sent back in response to the API call.</p>
<p><em>Things get a bit messy from here.</em></p>
<h3 id="the-mess-explained">The “mess” explained</h3>
<p>The use of Web API to get data from a web service is conceptually very similar to making a query into a database. For example, a SQL query <code>select * from cars where price &amp;lt;10K</code>(get me all the cars priced &lt;10K), will return a table with rows that match the query criteria.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771971802/FZnvUbFGM.png" alt /></p>
<p>In JSON the results would look a bit different.</p>
<p><code>[{make:'Toyota', model:'Camry', year:1999, price:7K, doors:'2DR'},{make:'Nissan', model:'Sentra', year:1988, price:3K, doors:'2DR'},{make:'Jeep', model:'Cherokee', year:1988, price:7K, doors:'4DR'}{make:'Jeep', model:'Wrangler', year:1984, price:9K, doors:'2DR'}]</code></p>
<ol>
<li><p>The result is a valid Javascript object (an array in this example)</p>
</li>
<li><p>Each row of the result is represented as an element of an array and the fields name are given for every value.</p>
</li>
</ol>
<p>Although the <strong>look</strong> is different, the underlying structure is still not <em>that</em> different.</p>
<p>Now let’s bring the Web’s messiness. What if some of the fields are absent from some of the rows. This usually does not happen in professionally built and curated in-house databases but irregularities like this is the norm when it comes to the Web and results from the Web API calls are no different.</p>
<p>If the results were returned in an SQL style rows they would look like the following (where we are missing information about the Nissan’s year and its drive train type the model for one of the two Jeep).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771973012/jJBsBbZtW.png" alt /></p>
<p>Processing this data is fairly straight forward. We loop through the data, for each row, we check if a value is null (or blank) and do what we need to do with the data that <em>is</em> available. Our code does not break, just because there is a null or an empty value.</p>
<p>In JSON the data would be something like</p>
<p><code>[{make:'Toyota', model:'Camry', year:1999, price:7K, doors:'2DR'}, {make:'Nissan', model:'Sentra', price:3K},{make:'Jeep', year:1988, price:7K, doors:'4DR'}, {make:'Jeep', model:'Wrangler', year:1984, price:9K, doors:'2DR'}]</code></p>
<p>For Nissan, as expected there is no key for year and doors. For one of the Jeeps the model is missing.</p>
<p>My n00b inclination was that the processing of this data is still quite simple. I will need to add an additional check to see if a field is present before accessing its value. I will access the key and see if accessing the key returns <em>undefined</em>. If it does not, then I capture the value. In our Nissan example, trying to access the key <em>year</em> will return undefined. So my pattern was</p>
<p><code>if (key != undefined) {do_some_thing(object[key]</code>}</p>
<p><strong>It worked well until I encountered complex (i.e. real life) JSONs.</strong></p>
<p>JSON is a nested tree like structure, rather than a table structure. While the keys of a JSON object has to be a string or a number, the values can be objects. The values of the keys of these <em>child</em> objects can themselves again be objects. Many real world JSONs can be 8 or 9 level deep. Using my pattern this would mean that I would have a 8<em> or 9 level <strong>nested</strong> if-thens.</em></p>
<p><strong><em>Try debugging that.</em></strong></p>
<h2 id="poor-taste-a-detailed-example">“Poor taste” a detailed example</h2>
<p>We continue with the car domain. Let’s say we are tasked to print the values of certain fields from the inventory. We will display the value of the fields if they are available. If the fields are not there or if the value of a field is not present we will not display anything (i.e. write a blank).</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Note that this is an INEFFICIENT way to solve the problem</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">noob_way</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-comment">// get test data from a test data utility</span>
  <span class="hljs-keyword">var</span> cars=get_data_set(<span class="hljs-string">"basic"</span>);  


  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> cars){
    <span class="hljs-keyword">if</span>(cars[i][<span class="hljs-string">"model"</span>]!==<span class="hljs-literal">undefined</span>) { 
      Logger.log(cars[i][<span class="hljs-string">"model"</span>]); <span class="hljs-comment">// Logger.log() is Google App Script's console.log  </span>
    } 

    <span class="hljs-keyword">if</span>(cars[i][<span class="hljs-string">"trim"</span>]!==<span class="hljs-literal">undefined</span>) {
      Logger.log(cars[i][<span class="hljs-string">"trim"</span>]); <span class="hljs-comment">// Logger.log() is Google App Script's console.log  </span>
    }

    <span class="hljs-keyword">if</span>(cars[i][<span class="hljs-string">"year"</span>]!==<span class="hljs-literal">undefined</span>) {
      Logger.log(cars[i][<span class="hljs-string">"year"</span>]); <span class="hljs-comment">// Logger.log() is Google App Script's console.log  </span>
    }

    <span class="hljs-keyword">if</span>(cars[i][<span class="hljs-string">"wheel"</span>]!==<span class="hljs-literal">undefined</span>) {
      Logger.log(cars[i][<span class="hljs-string">"wheel"</span>]);
      <span class="hljs-keyword">if</span>(cars[i][<span class="hljs-string">"wheel"</span>][<span class="hljs-string">"wheel_size"</span>]!==<span class="hljs-literal">undefined</span>){
        Logger.log(cars[i][<span class="hljs-string">"wheel"</span>][<span class="hljs-string">"wheel_size"</span>]); <span class="hljs-comment">// Logger.log() is Google App Script's console.log  </span>
      }
      <span class="hljs-keyword">if</span>(cars[i][<span class="hljs-string">"wheel"</span>][<span class="hljs-string">"wheel_metal"</span>]!==<span class="hljs-literal">undefined</span>){
        Logger.log(cars[i][<span class="hljs-string">"wheel"</span>][<span class="hljs-string">"wheel_metal"</span>]); <span class="hljs-comment">// Logger.log() is Google App Script's console.log  </span>
      }
    }
  }
}
</code></pre>
<p>Checking for <em>model</em>, <em>trim</em> and <em>year</em> is easy because the keys are at the first level. But <em>wheel_size </em>and<em> wheel_metal </em>are nested fields. We need to first check if the parent field (in this case <em>wheel</em>) exists before we access them. You can see how the complexity increases in line 21-29. Again imagine processing fields that are 8 or 9 level deep.</p>
<p>Before I describe my refactoring let’s look at an interesting feature that is available in many programming languages.</p>
<h2 id="short-circuiting-booleans">Short-circuiting — booleans</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771975097/BAHN12Jc_F.jpeg" alt /></p>
<p>As logical expressions are evaluated left to right, they are tested for possible “short-circuit” opportunities using the following <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">rule</a>s:</p>
<p><code>1. false &amp;&amp; (*anything)</code>* is short-circuit evaluated to false</p>
<p><code>2. true || (*anything)</code>* is short-circuit evaluated to true</p>
<p>Here’s a useful partial truth table</p>
<p><img src="https://cdn-images-1.medium.com/max/2000/1*W6-4oIkiJGdGIPAveVxgsA.png" alt="A partial [truth table](https://cdn.hashnode.com/res/hashnode/image/upload/v1630771977049/4uiFW7vvT.html)" /><em>A partial <a target="_blank" href="https://en.wikipedia.org/wiki/Truth_table">truth table</a></em></p>
<p>Taking advantage of rule # 1 if you write <code>cars["wheel"] &amp;&amp; cars["wheel"]["wheel_size"]</code> <strong>AND</strong> if <code>cars["wheel"]</code><em> </em>does not exist (i.e. it is false in Javascript) the rest never gets evaluated.</p>
<p>Basically the short-circuiting can convert a <strong>nested</strong> if else error checking for undefined fields to a simple single line of code. The depth of a field will not increase the complexity it will just add more clauses with &amp;&amp;s.</p>
<p>Finally, here’s the cleaned up code</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Smarter way to access the data</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">noob_smart_way</span>(<span class="hljs-params"></span>)</span>{

  <span class="hljs-keyword">var</span> cars=get_data_set(<span class="hljs-string">"basic"</span>);  
  <span class="hljs-keyword">var</span> format_string = <span class="hljs-string">"%s %s %s %s %s"</span>;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> cars){
    Logger.log(format_string, cars[i][<span class="hljs-string">"model"</span>] || <span class="hljs-string">""</span>,cars[i][<span class="hljs-string">"trim"</span>] || <span class="hljs-string">""</span>,cars[i][<span class="hljs-string">"year"</span>] ||  <span class="hljs-string">""</span>,
                cars[i][<span class="hljs-string">"wheel"</span>] &amp;&amp; cars[i][<span class="hljs-string">"wheel"</span>][<span class="hljs-string">"wheel_size"</span>]    ||  <span class="hljs-string">""</span>,
               cars[i][<span class="hljs-string">"wheel"</span>] &amp;&amp; cars[i][<span class="hljs-string">"wheel"</span>][<span class="hljs-string">"wheel_metal"</span>] || <span class="hljs-string">""</span>) 
    <span class="hljs-comment">// Logger.log() is Google App Script's console.log  </span>
  }   
}
</code></pre>
<p><strong>TL;DR:</strong> Use short circuit of <code>&amp;&amp;</code> to check for keys in a deep JSON instead of a nested if-else. This will significantly reduce your code complexity. Thread together all the keys from the top level until you reach the key whose value you want with bunch &amp;&amp;s.</p>
<blockquote>
<p>k_0:{k_1: {k_2:{k3: … kn}} should become k_0 &amp;&amp; k_0[k_1] &amp;&amp; k_0[k_1][k_2]&amp;&amp; … &amp;&amp;k_0[k_1][k_2]….[kn]</p>
</blockquote>
<p>In the last two years I have spent 2300 hours in coding and have written 23,342 lines of code. In that code I have made 349 real world JSON calls followed by nested if-then-else. Say it took me on the average 1 hour to code/debug each of them. That is still 350 hours or 15% of my coding time.</p>
<p>This pattern literally takes a minute or less to write and it is mostly bug proof. That is 350 minutes or about 6 hours.Go figure!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771978750/Gk1dBh1HC.gif" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771980572/kGDZZWliJ.gif" alt /></p>
]]></content:encoded></item><item><title><![CDATA[Tracking the *real* number of users in Google Add-Ons using Google Analytics]]></title><description><![CDATA[I developed my first add-on Word Cloud Generator for Google Docs without knowing much about who was using the Add-On and how they were using it.

Over time I introduced enhancements such as enabling downloadable word clouds but did not know if those ...]]></description><link>https://blogs.learnin60seconds.com/tracking-the-real-number-of-users-in-google-add-ons-using-google-analytics-fa91d447879c</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/tracking-the-real-number-of-users-in-google-add-ons-using-google-analytics-fa91d447879c</guid><category><![CDATA[Google]]></category><category><![CDATA[SEO]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Mon, 05 Dec 2016 00:10:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771928631/Ag0s8UWa3.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I developed my first add-on Word Cloud Generator for Google Docs without knowing much about who was using the Add-On and how they were using it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771921163/F3kDUbYEK.png" alt /></p>
<p>Over time I introduced enhancements such as enabling downloadable word clouds but did not know if those enhancements were indeed being used. I googled the <a target="_blank" href="https://support.google.com/analytics/answer/1032385?hl=en">essentials</a>, <a target="_blank" href="https://support.google.com/analytics/answer/1008080?hl=en">set up</a> <a target="_blank" href="https://developers.google.com/analytics/">Analytics</a> tracking, and included the basic tracking <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/analyticsjs/">code</a> in my script file.</p>
<p>This basic tracking code is well explained on the <a target="_blank" href="https://twitter.com/googledevs">Google Developers</a> <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/analyticsjs/">analytics.js page</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771922557/EZOPeYdyV.png" alt /></p>
<p>I quickly realized that the basic set up did not result in useful information on usage for Add-Ons as the counts were vastly exaggerated (tracking was done using cookies that were not persistent and resulted in information per <strong>use</strong>, and not per <strong>user</strong>). (<em>The number of installs displayed in the developer dashboard was not much help for analytics). </em>Then I found an Analytics <a target="_blank" href="https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id">resource</a> that presented the code to be used and a <a target="_blank" href="https://gsuite-developers.googleblog.com/2016/01/google-apps-script-tracking-add-on.html">blog</a> with a discussion of the cookie issue by <a target="_blank" href="https://twitter.com/romain_vialard">Romain Vialard</a>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771923988/dBtwWkLO0.png" alt /></p>
<p>This (ultimately) with a lot of trial and error, finally worked.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771925523/lf8ttGUAJ.png" alt /></p>
<p>However it took me a <strong>very long time to understand what this code was doing and how to use it.</strong> Not a fun experience. So in case there is somebody out there looking for a step by step explanation of why the above works and what it means, I posted my code on gist with a LOT of comments. I hope it helps someone to save some time and get to tracking Add-On usage rather than googling!</p>
<p>Leave a message if you have any additional tips or comments</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/* 
 The most common way to track users in Google Analytics is by using cookies. But sometimes 
 there are platform and security limitations that will not allow cookies to be set or 
 stored for multiple sessions. The following code uses the localStorage property (available 
 now in most browsers) to provide an alternate way to the cookie-based solution. The code 
 is heavily commented to help even the most casual users understand the overall workings 
 of the code. Feel free to ignore this part if you know what you are doing. 

This work is based on a Google example: 
https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id 
I have simplified it and added comments

There is a blog about this code in medium:link and some basic concepts explained in the 
comments section: 
*/</span>

<span class="hljs-comment">// First I make sure that there is localStorage available in the browser. The code </span>
<span class="hljs-comment">//only works if localStorage is available.</span>
<span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.localStorage) {

  <span class="hljs-comment">/* The first step to setting up a google analytics tracker is to issue a GA create 
  command. Typically it is done as follows: 
  ga ('create', 'UA-XXXXXXXX-5', 'auto')

  This tells the GA code to create a tracker for the property with an id 'UA-XXXXXXXX-5 
  and tells GA to use a default domain to store the analytics cookie.

  But I want to create the tracker a bit differently. I want to do three things:

  1) I want GA not to use cookies
  2) I want GA to use a client id to identify the browser so that I can track the user 
  and not every session of the user
  3) I want to store the client id locally (ie on the browser) so that it can be passed 
  on to GA for the next time 

  */</span>


  ga(<span class="hljs-string">'create'</span>, <span class="hljs-string">'UA-XXXXXXXX-5'</span>, <span class="hljs-comment">// these two parameters remains exactly the same as </span>
     <span class="hljs-comment">//Google's standard tracking code</span>
     <span class="hljs-comment">// I pass the added information via the following object:</span>
     {
       <span class="hljs-string">'storage'</span>: <span class="hljs-string">'none'</span>, <span class="hljs-comment">// Tells GA not to store cookies as local storage is being used</span>
       <span class="hljs-string">'clientId'</span>: <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">'local_client_id'</span>) <span class="hljs-comment">// Tells GA to set a clientId </span>
   <span class="hljs-comment">//to identify this browser/user</span>

       <span class="hljs-comment">/* Gotcha alert */</span>

       <span class="hljs-comment">/*        
       This tripped me up. So warning to you too: The value of clientId is initially null! 
       This is because there is nothing in localStorage yet and therefore 
       getItem ('local_client_id') will return null. GA when creating the tracker will 
       generate a random unique number as a client id      
       */</span>


     });


 <span class="hljs-comment">/* 
  Once the tracker is created I want to get the random client id generated by GA 
  and store it locally. 
  I want to do this because next time when the tracker is created the locally 
  stored client id will be passed, so that the GA knows it is NOT a new user 
  (because GA already has the client id)

  To do this Google offers a cool way to get tracker information. I call ga and 
  pass in an anonymous function with a single parameter. When ga gets a call 
  with a function (with a single parameter) 
  it puts the created tracker data in that parameter.

  The function passed earlier requests the client id from ga and stores 
  in the localStorage  

 */</span>


  ga(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">tracker_data</span>) </span>{ 
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">'local_client_id'</span>, tracker_data.get(<span class="hljs-string">'clientId'</span>)); 
   <span class="hljs-comment">// get the client id from GA and store it locally</span>
  });

}
<span class="hljs-keyword">else</span> {<span class="hljs-comment">/* fallback if there is no local storage - In this case, GA will 
count each and every hit even when the same user accesses the app multiple times*/</span>
  ga(<span class="hljs-string">'create'</span>, <span class="hljs-string">'UA-XXXXXXXX-5'</span>, <span class="hljs-string">'auto'</span>);
}
<span class="hljs-comment">// Send the hit - it will only be counted when the client id matches  </span>
ga(<span class="hljs-string">'send'</span>, <span class="hljs-string">'pageview'</span>);
</code></pre>
<h2 id="ga-concepts">GA concepts:</h2>
<p><strong>Tracker objects</strong>: A JS object created by GA that can collect and store data and then send that data to Google Analytics.</p>
<p><strong>Tracking id:</strong> A string like UA-000000–01. It is included in tracking code to tell Google Analytics which account and property to send data to.</p>
<p><strong>Client id:</strong> The client id is a unique, randomly generated string that usually gets stored in the browsers cookies, so subsequent visits are associated with the same user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771927183/YxhqeZtFI.gif" alt /></p>
]]></content:encoded></item><item><title><![CDATA[Encountering Javascript’s “weird” parts as a noob and how I dealt with it]]></title><description><![CDATA[Array.indexOf() and converting an array to an object literal

The weirdness of Javascript is hard enough to deal with if you are an experienced programmer. It is much harder for a new programmer.
My first encounter with Javascript’s strangeness was w...]]></description><link>https://blogs.learnin60seconds.com/a-n00ber-hack-for-solving-needle-haystack-problems-when-the-haystack-is-an-array-33dc54d0501b</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/a-n00ber-hack-for-solving-needle-haystack-problems-when-the-haystack-is-an-array-33dc54d0501b</guid><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Mon, 05 Dec 2016 00:08:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630772000167/MoJGLjbSy.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Array.indexOf() and converting an array to an object literal</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771987353/QCWK6tjWl.png" alt /></p>
<p>The <strong>weirdness</strong> of Javascript is hard enough to deal with if you are an experienced programmer. It is much harder for a new programmer.</p>
<p>My first encounter with Javascript’s strangeness was with the <em>in</em> operator. The <em>in</em> operator is a nifty tool to check if a specified property is present in a specified object. For example we can check if a certain key is present in a object that has several key value pairs.</p>
<pre><code>var mycar = {make: "Honda", model: "Accord", year: <span class="hljs-number">1998</span>};
"make" <span class="hljs-keyword">in</span> mycar  // <span class="hljs-keyword">returns</span> <span class="hljs-keyword">true</span>

"mileage" <span class="hljs-keyword">in</span> mycar  // <span class="hljs-keyword">returns</span> <span class="hljs-keyword">false</span>
</code></pre><p><strong>Unfortunately the <em>in</em> does not work in an intuitive (and useful) way when used with arrays.</strong></p>
<p>In the example below, I would really like it if Javascript’s <em>in</em> would work like this:</p>
<pre><code>var trees = ["redwood", "bay", "cedar", "oak", "maple"];

"bay" <span class="hljs-keyword">in</span> trees    // <span class="hljs-keyword">returns</span> <span class="hljs-keyword">false</span>
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771989721/xWvJZK9m7.png" alt /></p>
<p>The reason it does not work (and it should not) is the particular way Javascript’s array objects are implemented. They are internally viewed as a key value pairs of index and the corresponding element. For example the <em>trees</em> above is stored internally as something like:</p>
<pre><code>{<span class="hljs-attribute">0</span>:<span class="hljs-string">"redwood"</span>, <span class="hljs-number">1</span>:<span class="hljs-string">"bay"</span>, <span class="hljs-number">2</span>:<span class="hljs-string">"cedar"</span>, <span class="hljs-number">3</span>:<span class="hljs-string">"oak"</span>, <span class="hljs-number">4</span>:<span class="hljs-string">"maple"</span>}
</code></pre><p>And yes, 1 in trees will return true, but that is not useful to me as a programmer.</p>
<p>I am relatively new to programming (<a target="_blank" href="https://medium.com/@tanyagupta/i-dropped-my-cs-major-because-i-couldnt-do-a-bubble-sort-126e1242d86e#.aohwtloii">here’s my story in medium</a>) and I do not code professionally. But even I encounter several scenarios almost every day where I need to check if some item is in an array or not. Naturally this weirdness in Javascript puzzled me a bit. From what I found out, this is available in other languages (Python, Ruby) so — why not Javascript? I googled a bit and found <a target="_blank" href="https://www.tutorialspoint.com/data_structures_algorithms/linear_search_algorithm.htm">this</a> on how to implement a “linear search” in Javascript. Which I did.</p>
<blockquote>
<p>To check if an item is in an array, I have to iterate through the array elements until the item is found in the array.</p>
</blockquote>
<pre><code><span class="hljs-keyword">function</span> inArray (item, theArray) {
  var <span class="hljs-built_in">found</span> = <span class="hljs-keyword">false</span>;
  var i=<span class="hljs-number">0</span>;
  <span class="hljs-keyword">while</span> (!<span class="hljs-built_in">found</span> &amp;&amp; i <span class="hljs-keyword">in</span> theArray) {
    <span class="hljs-built_in">found</span> =(item === theArray[i]);
    i++;
  }
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">found</span>;

}
</code></pre><p>But it was not satisfying. I could not tell then what exactly about it dissatisfied me — at that point it was just something I did not think was cool. I now know better. Please read on.</p>
<h2 id="1-arrayindexof">1) Array.indexOf()</h2>
<p>The <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">Array.indexOf() method</a> returns the first index at which a given item can be found in the array. If it is not present it returns -1. Thanks to <a target="_blank" href="https://medium.com/@neversleep">Nikolay Digaev</a> for pointing me to this (another is Array.includes() — which unfortunately is not currently supported by Google Apps Script where I mostly work on these days. The Array.includes() <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes">method</a> returns true or false based on whether an array includes a certain element.)</p>
<p>Here is a simple use case for Array.indexOf():</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">item_in_array</span>(<span class="hljs-params"></span>)</span>{
 <span class="hljs-keyword">var</span> fruits = [<span class="hljs-string">"Bob"</span>, <span class="hljs-string">"Rob"</span>, <span class="hljs-string">"Amanda"</span>, <span class="hljs-string">"Cheryl"</span>,<span class="hljs-string">"Susan"</span>];


  Logger.log(fruits.indexOf(<span class="hljs-string">"Susan"</span>)) <span class="hljs-comment">//returns 4 which is the index of Susan</span>
  Logger.log(fruits.indexOf(<span class="hljs-string">"Frank"</span>)) <span class="hljs-comment">//returns -1 since the item is not found</span>

}
</code></pre>
<h2 id="2-convert-the-array-to-an-object-literal-and-use-the-in-operator">2) Convert the array to an object literal and use the “in” operator</h2>
<p>I figured out a way to use the <em>in</em> operator in my use cases. I started converting my arrays to objects. I would store each (unique) item as a key and just put a blank in the corresponding value.</p>
<blockquote>
<p>The Hack: convert the array to a typical object with items as keys and empty values</p>
</blockquote>
<pre><code>**Creating the <span class="hljs-keyword">object</span>:**

  <span class="hljs-keyword">var</span> hack_object_literal = {};
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> test_data) {
    hack_object_literal[test_data[i]]=<span class="hljs-string">""</span>;

  }
</code></pre><p>Careful readers may notice that my hack ignores duplicate items when building the object. Which is fine since all we want to know if an item is present. Not how many of them are present.</p>
<p>Now I can use the <em>in</em> operator to check if the item is present in the object which in effect tells me if the item is present in my array.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">inArrayMyHack</span> (<span class="hljs-params">item, arrayDataAsObject</span>) </span>{ 
  <span class="hljs-keyword">return</span> item in arrayDataAsObject; 
}
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771991214/B07wz7l-o.png" alt /></p>
<h3 id="recommendation-use-arrayindexof-easier-andshorter">Recommendation: use Array.indexOf() — easier andshorter</h3>
<p><img src="https://cdn-images-1.medium.com/max/2000/1*YJmKqYHIMiiPcMBDtuG5hw.jpeg" alt="Courtesy: [Pixabay](https://cdn.hashnode.com/res/hashnode/image/upload/v1630771992388/xhHcT3-Ie.html)" /><em>Courtesy: <a target="_blank" href="https://pixabay.com/en/binary-system-code-computer-files-1543168/">Pixabay</a></em></p>
<h2 id="an-experiment-to-determine-speed">An experiment to determine speed</h2>
<p>Computer science purists believe that data structures should be used for the tasks they are originally designed to do, as otherwise, it results in unmaintainable code. One may deviate from this principle only if there is a compelling reason to do so. Leaving the values empty in a collection of key-value pairs seem to be a major deviation. So I decided to see if there is a compelling reason for my “hack.” And I found it.</p>
<p>I implemented the three functions: the linear search function as inArray, Array.indexOf() and inArrayMyHack</p>
<ol>
<li>For every size of arrays that I created:</li>
</ol>
<p>a) I sorted the array element and created a sorted version of the array</p>
<p>b) For every element in the sorted array I called both the functions giving them the element and the array. So for a 200 size array both the functions will be called 200 times each.</p>
<p>I recorded the time it took for them to complete.</p>
<p><em>Note for inArrayMyHack I also had to convert the array to an object before I made the call. I added that time to the performance time of inArrayMyHack — but there is a catch to that to0, read on..</em></p>
<h2 id="try-there-are-significant-efficiency-gains">Try { there are significant efficiency gains}</h2>
<p>The graph and the table below shows that either of the two methods are way faster than the linear search.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771993699/dIBYHpJtp.png" alt /></p>
<p><strong>The hack and Array.indexOf() </strong>are close initially but the Array.indexOf() methods slows down once size increases. I talked to some coder friends who told me that the reason for this performance is the <em>in</em> operation uses a very fast algorithmic technique called hashing. This technique produces a performance that is (almost) constant time regardless of the data size. Linear search time increases as the data size increase. The data conversion time is very negligible compared to the speed gained by hashing.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771995012/3FdXG6w7c.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771996320/1xcVnkpOM.png" alt="Speed test" /><em>Speed test</em></p>
<h2 id="catch-with-the-hackwe-bomb-if-the-arrays-are-not-known-at-coding-time">Catch with the hack{We bomb if the arrays are not known at coding time}</h2>
<p>There can be situations where I do not know about the arrays at coding time. In such case I will not be able to convert the arrays to objects <strong>before</strong> making the call. Things will slow down if I have to do a lot of searches each time with a different unknown array.</p>
<h3 id="bottom-line-use-arrayindexof-will-fit-for-most-use-cases-unless-you-are-dealing-with-large-sizes-and-you-have-some-knowledge-of-the-arrays-at-coding-time">Bottom line: Use Array.indexOf() — will fit for most use cases unless you are dealing with large sizes and you have some knowledge of the arrays at coding time.</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771997585/mjJM9DCuo.gif" alt /></p>
]]></content:encoded></item><item><title><![CDATA[I dropped my CS major because I couldn’t do a bubble sort.]]></title><description><![CDATA[I dropped my idea of a double major, stuck with Economics, and started working in international development. Life went on. Now, as a successful mid career professional with a somewhat stressful job, I was looking for a “midlife reprieve.” I decided t...]]></description><link>https://blogs.learnin60seconds.com/i-dropped-my-cs-major-because-i-couldnt-do-a-bubble-sort-126e1242d86e</link><guid isPermaLink="true">https://blogs.learnin60seconds.com/i-dropped-my-cs-major-because-i-couldnt-do-a-bubble-sort-126e1242d86e</guid><category><![CDATA[Beginner Developers]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[tanyagupta]]></dc:creator><pubDate>Sun, 17 Jul 2016 21:59:08 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771960919/kPqGb5sMo.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I dropped my idea of a double major, stuck with Economics, and started working in international development. Life went on. Now, as a successful mid career professional with a somewhat stressful job, I was looking for a “midlife reprieve.” I decided to learn to code again. I wanted the adult to conquer the fear that cut short the dream of a child. I also remembered how coding helps destress and clear the mind (before the bubble sort came in).</p>
<p>I started my journey of code. Here’s the <strong>TL;DR</strong></p>
<ul>
<li><p>2000 hours of weekends and evenings — <em>check</em></p>
</li>
<li><p>Close to 60,000 users for one of my software products — <em>check</em></p>
</li>
<li><p>5 software products in Chromestore — <em>check</em></p>
</li>
<li><p>Can code up an app in a week, something that would have taken me 3–4 months, just two years ago — <em>check</em></p>
</li>
</ul>
<p>And <strong>most importantly</strong> a lifelong desire to continue as a (hobbyist) programmer.</p>
<h3 id="the-longer-version">The longer version:</h3>
<p>I am not an expert programmer. Novice++ at best. My code is very green. I know it. My partner <a target="_blank" href="https://twitter.com/abirqasem">Abir Qasem</a>, who has a Phd in Computer Science, agrees. But I have no fear of programming anymore and I do have a few products that people like and <strong>use. </strong>I am deeply humbled by the knowledge that I have so much more to learn. But at the same time I am very happy and proud of whatever little I have achieved.</p>
<p>I kept records of my progress mostly to learn from my experience and to know if and when I need to throw in the towel. But since this journey has at least, on a personal level, become a success story, I want to share. I have inspired by the journey of others. So I am sharing my story in the hope others may find it useful. And I like infographics too. So ‘nuff text.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630771959096/fXZOPTY_z.png" alt /></p>
<h3 id="thanks-to-free-code-camphttpstwittercomfreecodecamp-quincy-larsonhttpstwittercomossia-lucahttpsgithubcomlucaong-ben-at-google-and-google-plus-group-for-add-on-developershttpsplusgooglecomu0communities117193953428311185494">(thanks to <a target="_blank" href="https://twitter.com/freeCodeCamp">Free Code Camp</a>, <a target="_blank" href="https://twitter.com/ossia">Quincy Larson</a>, <a target="_blank" href="https://github.com/lucaong">Luca</a>, Ben at Google, and <a target="_blank" href="https://plus.google.com/u/0/communities/117193953428311185494">Google Plus Group for Add-On Developers</a>)</h3>
]]></content:encoded></item></channel></rss>