<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Ashutosh Singh, learning in public</title>
  <link>https://ashu1461.com/</link>
  <description>Ashutosh Singh on running a startup, developer productivity, engineering, and AI.</description>
  <language>en</language>
  <lastBuildDate>Mon, 27 Jan 2025 00:00:00 GMT</lastBuildDate>
  <atom:link href="https://ashu1461.com/rss.xml" rel="self" type="application/rss+xml"/>
  <item>
    <title>Shopify&#39;s Weird API Deprecation strategy</title>
    <link>https://ashu1461.com/posts/shopifys-weird-api-deprecation-strategy/</link>
    <guid isPermaLink="true">https://ashu1461.com/posts/shopifys-weird-api-deprecation-strategy/</guid>
    <pubDate>Mon, 27 Jan 2025 00:00:00 GMT</pubDate>
    <description>Shopify deprecates their APIs once every 6 months and it is a situation of anxiety for our development team. Because in case there is still a call site which is making calls to deprecated APIs, your shopify app can get delisted.</description>
    <category>startup</category><category>engineering</category>
    <content:encoded><![CDATA[<p>Shopify deprecates their APIs once every 6 months and it is a situation of anxiety for our development team.</p>
<p>Because in case there is still a call site which is making calls to deprecated APIs, your shopify app can get delisted.</p>
<p>Finding call sites for deprecated APIs can sometimes become challenging specially in large code bases involving multiple services.</p>
<p><figure class="figure"><img src="/images/posts/shopify-deprecation.png" alt="Shopify API deprecation warning" loading="lazy" decoding="async"></figure></p>
<p>In case a developer made a postman call to a deprecated API I guess that would still count as an invalid call and can lead to delisting.</p>
<p>In Shopify&#39;s defence they do start to give a warning about deprecated APIs way before but taking a strong action like delisting the app feels weird.</p>
<p>Maybe just making the existing APIs return an error citing deprecation would have been better ?</p>
]]></content:encoded>
  </item>
  <item>
    <title>Interview gone wrong</title>
    <link>https://ashu1461.com/posts/interview-gone-wrong/</link>
    <guid isPermaLink="true">https://ashu1461.com/posts/interview-gone-wrong/</guid>
    <pubDate>Fri, 01 Nov 2024 00:00:00 GMT</pubDate>
    <description>I use tic tac toe as one of the interview questions, the logic is straightforward and it helps to judge things like code quality, speed, and conciseness. One candidate&#39;s Python answer taught me something new.</description>
    <category>engineering</category><category>productivity</category>
    <content:encoded><![CDATA[<p>I use tic tac toe as one of the interview questions, the logic is straightforward and it helps to judge things like code quality / speed / conciseness.</p>
<h2 id="the-surprising-comparison" class="heading heading--2">The surprising comparison<a class="heading__anchor" href="#the-surprising-comparison" aria-label="Link to this section">#</a></h2>
<p>One candidate who was a Python developer wrote something like this:</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">python</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-python"><span class="hljs-keyword">if</span> (cell[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>] == cell[<span class="hljs-number">1</span>][<span class="hljs-number">1</span>] == cell[<span class="hljs-number">2</span>][<span class="hljs-number">2</span>]):
    <span class="hljs-keyword">return</span> Winner</code></pre></figure>
<p>At first I thought this was logically flawed. Since <code class="inline-code">cell[x][y]</code> contains characters (<code class="inline-code">'-'</code>, <code class="inline-code">'X'</code>, or <code class="inline-code">'Y'</code>), the expression <code class="inline-code">True == cell[2][2]</code> would return <code class="inline-code">False</code> in JavaScript.</p>
<h2 id="pythons-chained-expressions" class="heading heading--2">Python&#39;s chained expressions<a class="heading__anchor" href="#pythons-chained-expressions" aria-label="Link to this section">#</a></h2>
<p>However, Python handles this differently through <strong>chained expressions</strong>. Python transforms the above into:</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">python</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-python"><span class="hljs-keyword">if</span> ((cell[<span class="hljs-number">0</span>][<span class="hljs-number">0</span>] == cell[<span class="hljs-number">1</span>][<span class="hljs-number">1</span>]) <span class="hljs-keyword">and</span> (cell[<span class="hljs-number">1</span>][<span class="hljs-number">1</span>] == cell[<span class="hljs-number">2</span>][<span class="hljs-number">2</span>])):
    <span class="hljs-keyword">return</span> Winner</code></pre></figure>
<p>The code is indeed correct. Python has yet another way to confuse us all.</p>
]]></content:encoded>
  </item>
  <item>
    <title>Can GPT generate random numbers ?</title>
    <link>https://ashu1461.com/posts/can-gpt-generate-random-numbers/</link>
    <guid isPermaLink="true">https://ashu1461.com/posts/can-gpt-generate-random-numbers/</guid>
    <pubDate>Fri, 16 Aug 2024 00:00:00 GMT</pubDate>
    <description>Well a random thought came to my mind if GPT can really generate a random number? Best thing is to find out yourself. I ran experiments using Claude 3.5 Sonnet and the results were fascinating.</description>
    <category>ai</category><category>engineering</category>
    <content:encoded><![CDATA[<p>Well a random thought came to my mind if GPT can really generate a random number ?</p>
<p>Best thing is to find out yourself.</p>
<p>First thing is to quickly write boiler plates around random number generation using the cohere sonet model.</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">python</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-python"><span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">generate_random_number</span>(<span class="hljs-params">till: <span class="hljs-built_in">int</span></span>):
    temperature = random.random()
    message = <span class="hljs-keyword">await</span> client.messages.create(
        model=<span class="hljs-string">&quot;claude-3-5-sonnet-20240620&quot;</span>,
        max_tokens=<span class="hljs-number">1000</span>,
        temperature=temperature,
        messages=[
            {
                <span class="hljs-string">&quot;role&quot;</span>: <span class="hljs-string">&quot;user&quot;</span>,
                <span class="hljs-string">&quot;content&quot;</span>: [
                    {
                        <span class="hljs-string">&quot;type&quot;</span>: <span class="hljs-string">&quot;text&quot;</span>,
                        <span class="hljs-string">&quot;text&quot;</span>: <span class="hljs-string">f&quot;Generate a random number between 1 to <span class="hljs-subst">{till}</span>&quot;</span>
                        + <span class="hljs-string">&quot;. Answer in the json format {number: int} only answer a valid json&quot;</span>,
                    }
                ],
            }
        ],
    )
    random_number = json.loads(message.content[<span class="hljs-number">0</span>].text)
    <span class="hljs-keyword">return</span> random_number.get(<span class="hljs-string">&quot;number&quot;</span>)


<span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">generate_random_x_times</span>(<span class="hljs-params">times: <span class="hljs-built_in">int</span>, till: <span class="hljs-built_in">int</span></span>) -&gt; <span class="hljs-type">List</span>[<span class="hljs-built_in">str</span>]:
    tasks = [generate_random_number(till) <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(times)]
    random_results = <span class="hljs-keyword">await</span> asyncio.gather(*tasks)
    <span class="hljs-keyword">return</span> random_results


<span class="hljs-keyword">def</span> <span class="hljs-title function_">plot_histogram</span>(<span class="hljs-params">random_numbers: <span class="hljs-type">List</span>[<span class="hljs-built_in">int</span>]</span>):
    <span class="hljs-comment"># plot the random_numbers</span></code></pre></figure>
<h2 id="results-for-numbers" class="heading heading--2">Results for numbers<a class="heading__anchor" href="#results-for-numbers" aria-label="Link to this section">#</a></h2>
<p>Now how random were the results ?</p>
<p>For a random number between 1 to 10000 (Cohere), the model is settling amongst predicting amongst a handful of numbers</p>
<p><figure class="figure"><img src="/images/posts/gpt-random-1.png" alt="Random numbers 1-10000 iter 1" loading="lazy" decoding="async"></figure></p>
<p>still majority of the numbers are between 7300 - 7400 range.</p>
<p><figure class="figure"><img src="/images/posts/gpt-random-2.png" alt="Random numbers 1-10000 iter 2" loading="lazy" decoding="async"></figure></p>
<p>Let us try reducing the upper limit to 1000.</p>
<p><figure class="figure"><img src="/images/posts/gpt-random-3.png" alt="Random numbers 1-1000" loading="lazy" decoding="async"></figure></p>
<p>What is interesting is that in this case even trying multiple times gave the same distribution.</p>
<p>For upper limit 100, the number is always 73 and for 10 the number is always 7.</p>
<p><figure class="figure"><img src="/images/posts/gpt-random-4.png" alt="Random numbers 1-100" loading="lazy" decoding="async"></figure></p>
<p><figure class="figure"><img src="/images/posts/gpt-random-5.png" alt="Random numbers 1-10" loading="lazy" decoding="async"></figure></p>
<h2 id="results-for-strings" class="heading heading--2">Results for strings<a class="heading__anchor" href="#results-for-strings" aria-label="Link to this section">#</a></h2>
<p>Now let us twist the experiment a little bit and ask Claude to pick a random string from a given set of 10 names.</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">python</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-python">RANDOM_NAMES = [<span class="hljs-string">&quot;Olivia&quot;</span>, <span class="hljs-string">&quot;Liam&quot;</span>, <span class="hljs-string">&quot;Emma&quot;</span>, <span class="hljs-string">&quot;Noah&quot;</span>, <span class="hljs-string">&quot;Sophia&quot;</span>, <span class="hljs-string">&quot;James&quot;</span>, <span class="hljs-string">&quot;Isabella&quot;</span>, <span class="hljs-string">&quot;Benjamin&quot;</span>, <span class="hljs-string">&quot;Mia&quot;</span>, <span class="hljs-string">&quot;Elijah&quot;</span>]</code></pre></figure>
<p><figure class="figure"><img src="/images/posts/gpt-random-6.png" alt="Name selection iter 1" loading="lazy" decoding="async"></figure></p>
<p><figure class="figure"><img src="/images/posts/gpt-random-7.png" alt="Name selection iter 2" loading="lazy" decoding="async"></figure></p>
<p><figure class="figure"><img src="/images/posts/gpt-random-8.png" alt="Name selection 500 times" loading="lazy" decoding="async"></figure></p>
<p>I ran it couple of times, the results in case were different but still centered around the names which appear in the beginning of the list.</p>
<h2 id="some-takeaways" class="heading heading--2">Some takeaways<a class="heading__anchor" href="#some-takeaways" aria-label="Link to this section">#</a></h2>
<ul>
<li>The number is always 7 for a window of 1 to 10 and 73 for a window between 1 to 100.</li>
<li>The number range is weirdly centered around the number 7. Maybe because of the training data ?</li>
<li>While asked to choose randomly from a list, GPT is more probable to select from the starting of the list.</li>
</ul>
<h2 id="follow-up-questions" class="heading heading--2">Follow up questions<a class="heading__anchor" href="#follow-up-questions" aria-label="Link to this section">#</a></h2>
<ul>
<li>Would prompt engineering help here ?</li>
<li>How are the results with other models - though I guess the behaviour would be the same</li>
<li>How much dollars did I burn while doing this ?</li>
</ul>
]]></content:encoded>
  </item>
  <item>
    <title>Why you should make sure that your function params are extensible</title>
    <link>https://ashu1461.com/posts/extensible-function-params/</link>
    <guid isPermaLink="true">https://ashu1461.com/posts/extensible-function-params/</guid>
    <pubDate>Mon, 08 Jul 2024 00:00:00 GMT</pubDate>
    <description>For critical functions which you feel will change a lot in the future best to avoid primitive types directly in params and use extensible objects.</description>
    <category>engineering</category><category>productivity</category>
    <content:encoded><![CDATA[<p>For critical functions which you feel will change a lot in the future best to avoid primitive types directly in params and use extensible objects.</p>
<h2 id="making-response-objects-extensible" class="heading heading--2">Making response objects extensible<a class="heading__anchor" href="#making-response-objects-extensible" aria-label="Link to this section">#</a></h2>
<p>Rather than returning primitive types directly, wrap responses in objects:</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">typescript</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-typescript"><span class="hljs-comment">// Option 1 - not extensible</span>
<span class="hljs-keyword">class</span> <span class="hljs-title class_">DbUser</span> {
    <span class="hljs-attr">name</span>: <span class="hljs-built_in">string</span>;
    <span class="hljs-attr">age</span>: <span class="hljs-built_in">number</span>;
}
<span class="hljs-keyword">function</span> <span class="hljs-title function_">getUser</span>(<span class="hljs-params"><span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span></span>): <span class="hljs-title class_">DbUser</span>

<span class="hljs-comment">// Option 2 - extensible</span>
<span class="hljs-keyword">class</span> <span class="hljs-title class_">APIUserResponse</span> {
    <span class="hljs-attr">user</span>: <span class="hljs-title class_">DbUser</span>
}
<span class="hljs-keyword">function</span> <span class="hljs-title function_">getUser</span>(<span class="hljs-params"><span class="hljs-attr">id</span>: <span class="hljs-built_in">string</span></span>): <span class="hljs-title class_">APIUserResponse</span></code></pre></figure>
<p>The second option sounds better as you can simply add error state / tasks in the UserResponse object without requiring frontend and backend refactoring.</p>
<h2 id="making-requests-extensible" class="heading heading--2">Making requests extensible<a class="heading__anchor" href="#making-requests-extensible" aria-label="Link to this section">#</a></h2>
<p>Rather than accumulating function parameters, use objects for request handling:</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">typescript</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-typescript"><span class="hljs-comment">// Hard to read, hard to extend</span>
<span class="hljs-title function_">getUser</span>(<span class="hljs-string">&#x27;1&#x27;</span>, <span class="hljs-literal">false</span>, none, <span class="hljs-literal">true</span>);

<span class="hljs-comment">// Self-documenting, easy to extend</span>
<span class="hljs-title function_">getUser</span>({
    <span class="hljs-attr">id</span>: <span class="hljs-string">&#x27;1&#x27;</span>,
    <span class="hljs-attr">includeDisabled</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">includeTasks</span>: <span class="hljs-literal">true</span>
})</code></pre></figure>
<p>The second approach is significantly more readable and maintainable.</p>
<h2 id="key-takeaway" class="heading heading--2">Key takeaway<a class="heading__anchor" href="#key-takeaway" aria-label="Link to this section">#</a></h2>
<p>For critical functions which you feel will change a lot in the future best to avoid primitive types directly in params and use extensible objects. Primitive types lack extensibility, while context-dependent objects can provide it.</p>
]]></content:encoded>
  </item>
  <item>
    <title>Terminal Wisdom : Shortcut of the day</title>
    <link>https://ashu1461.com/posts/terminal-wisdom-tip-of-the-day/</link>
    <guid isPermaLink="true">https://ashu1461.com/posts/terminal-wisdom-tip-of-the-day/</guid>
    <pubDate>Thu, 22 Feb 2024 00:00:00 GMT</pubDate>
    <description>I was reading a recent blog post about this cool git shortcut which shows you the recent working branches you have been working on. So why not make a simple utility which prints a random shortcut whenever a terminal session starts.</description>
    <category>productivity</category><category>tooling</category>
    <content:encoded><![CDATA[<p>I was reading a recent blog post about this cool git shortcut which shows you the recent working branches you have been working on.</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">bash</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-bash">automation git:(singla/add_missing_model) x gitrecent
38 minutes ago  singla/add_missing_model
25 hours ago    singla/bug_fixes_21st
25 hours ago    singla/track_order_revamp</code></pre></figure>
<p>While the shortcut is useful, I was afraid that I might just forget it so why not make a simple utility which prints a random shortcut whenever a terminal session starts.</p>
<h2 id="step-1-create-a-tips-file" class="heading heading--2">Step 1: Create a tips file<a class="heading__anchor" href="#step-1-create-a-tips-file" aria-label="Link to this section">#</a></h2>
<p>Create a file <code class="inline-code">~/tips</code> containing useful shortcuts:</p>
<ul>
<li><code class="inline-code">git ac</code> for amending and committing</li>
<li><code class="inline-code">git uc</code> for adding and committing</li>
<li><code class="inline-code">git pullff</code> for pulling without the no-ff flag</li>
<li><code class="inline-code">gitrecent</code> for displaying recent branches</li>
<li>Wellness reminders (Pomodoro timer, water breaks, walks)</li>
</ul>
<h2 id="step-2-add-to-your-shell-config" class="heading heading--2">Step 2: Add to your shell config<a class="heading__anchor" href="#step-2-add-to-your-shell-config" aria-label="Link to this section">#</a></h2>
<p>Add this to your <code class="inline-code">.bashrc</code> or <code class="inline-code">.zshrc</code>:</p>
<figure class="codeblock"><figcaption class="codeblock__bar"><span class="codeblock__name">bash</span><button class="codeblock__copy" type="button" data-copy>Copy</button></figcaption><pre class="codeblock__pre"><code class="hljs language-bash">tip=$(<span class="hljs-built_in">shuf</span> ~/tips | <span class="hljs-built_in">head</span> -n 1)
<span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;Tip of the session: <span class="hljs-variable">$tip</span>&quot;</span></code></pre></figure>
<p><figure class="figure"><img src="/images/posts/terminal-wisdom.png" alt="Terminal wisdom in action" loading="lazy" decoding="async"></figure></p>
<p>Now every time you open a terminal, you get a random useful tip or shortcut. Simple but effective.</p>
]]></content:encoded>
  </item>
</channel>
</rss>
