<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Neeldhara</title>
<link>https://www.neeldhara.com/blog.html</link>
<atom:link href="https://www.neeldhara.com/blog.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.6.40</generator>
<lastBuildDate>Thu, 09 May 2024 18:30:00 GMT</lastBuildDate>
<item>
  <title>Creating a Gallery of Solved Crosswords</title>
  <link>https://www.neeldhara.com/blog/indiamini-crosswords/</link>
  <description><![CDATA[ 





<p>H/T <a href="https://twitter.com/mnwsth/status/1788781998904914215">Manu</a>: I’ve discovered the <a href="https://indiamini.in/play/">India Mini Crossword series</a> and it’s a great two-to-five minute thing to solve every morning! Here’s a little workflow I cobbled together to generate this collage of solved crosswords in <a href="https://obsidian.md/">Obsidian</a>:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/indiamini-crosswords/collage.png" class="img-fluid figure-img"></p>
<figcaption>Indiamini Crossword Solves Collage</figcaption>
</figure>
</div>
<p>In practice, after the one-time setup I describe here, all I do after solving the crossword is print it and save the PDF to a folder called <code>Notes/</code>. The rest is automatic.</p>
<p>To begin with, I have <a href="https://www.noodlesoft.com/">Hazel</a> monitor the <code>Notes/</code> folder and run this rule:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/indiamini-crosswords/hazel-01.png" class="img-fluid figure-img"></p>
<figcaption>Hazel Rule (Part 1)</figcaption>
</figure>
</div>
<p>All this does is checks if a PDF file has been added to the root level of the <code>Notes/</code> folder which has the string <code>Welcome to the India Mini crossword!</code>. It then pulls out the date from the file and pushes it into a date-based subfolder; e.g, if the crossword was for the 10th of May, the PDF file moves to the folder <code>Notes/2024/05/10/</code>. This is nice because even if I miss a day and solve something later, simply saving the file will still auto-file it in the correct directory.</p>
<p>Next up, there is a second rule:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/indiamini-crosswords/hazel-02.png" class="img-fluid figure-img"></p>
<figcaption>Hazel Rule (Part 2)</figcaption>
</figure>
</div>
<p>which processes the PDF file by extracting an image that contains the solved crossword. The actual work is carried out by this shell script, written mostly by chatGPT, complete with hard-coded paths:</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/bin/bash</span></span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Extract the first page</span></span>
<span id="cb1-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/usr/local/bin/pdftk</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/indiamini-crossword.pdf cat 1 output /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.pdf</span>
<span id="cb1-5"></span>
<span id="cb1-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/indiamini-crossword.pdf</span>
<span id="cb1-7"></span>
<span id="cb1-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Convert the first page to a PNG</span></span>
<span id="cb1-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/opt/homebrew/bin/convert</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-density</span> 300 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-quality</span> 100 /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.pdf /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.png</span>
<span id="cb1-10"></span>
<span id="cb1-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Get the height and width of the image</span></span>
<span id="cb1-12"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">height</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/opt/homebrew/bin/identify</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-format</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%h"</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.png<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-13"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">width</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/opt/homebrew/bin/identify</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-format</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%w"</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.png<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-14"></span>
<span id="cb1-15"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Calculate the half height and width</span></span>
<span id="cb1-16"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">half_height</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$((height</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb1-17"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">half_width</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$((width</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb1-18"></span>
<span id="cb1-19"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Crop the image to the top right half</span></span>
<span id="cb1-20"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/opt/homebrew/bin/convert</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.png <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-crop</span> 1100x1100+<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">${half_width}</span>+315 /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/indiamini-crossword.png</span>
<span id="cb1-21"></span>
<span id="cb1-22"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Delete intermediate files</span></span>
<span id="cb1-23"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rm</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.png</span>
<span id="cb1-24"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rm</span> /Users/neeldhara/Library/CloudStorage/Dropbox/Notes/<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$1</span>/first_page.pdf</span></code></pre></div>
<p>I finally have a very simple <a href="http://www.keyboardmaestro.com/">Keyboard Maestro</a> macro that runs every morning at 7AM — except Sundays, because the Sunday crossword is not a mini :) — to create the crossword note in my Obsidian vault in a date-based folder:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/indiamini-crosswords/km-macro.png" class="img-fluid figure-img"></p>
<figcaption>KM Macro</figcaption>
</figure>
</div>
<p>The crossword note template is very minimal:</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">---</span></span>
<span id="cb2-2"><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">title:</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> India Mini Crossword · &lt;% tp.date.now("YYYY") %&gt;-&lt;% tp.date.now("MM") %&gt;-&lt;% tp.date.now("DD") %&gt;</span></span>
<span id="cb2-3"><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">tags:</span></span>
<span id="cb2-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">  - kw/c/crossword</span></span>
<span id="cb2-5"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">  - kw/i/indiamini</span></span>
<span id="cb2-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">  - puzzles/indiamini-crossword</span></span>
<span id="cb2-7"><span class="an" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">asset:</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"> file:///Users/neeldhara/Library/CloudStorage/Dropbox/Notes/&lt;% tp.date.now("YYYY") %&gt;/&lt;% tp.date.now("MM") %&gt;/&lt;% tp.date.now("DD") %&gt;/indiamini-crossword.pdf</span></span>
<span id="cb2-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">---</span></span>
<span id="cb2-9"></span>
<span id="cb2-10"></span>
<span id="cb2-11">!<span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">Crossword</span><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>(file:///Users/neeldhara/Library/CloudStorage/Dropbox/Notes/&lt;% tp.date.now("YYYY") %&gt;/&lt;% tp.date.now("MM") %&gt;/&lt;% tp.date.now("DD") %&gt;/indiamini-crossword.png)</span></code></pre></div>
<p>The <a href="https://github.com/SilentVoid13/Templater">Templater plugin for Obsidian</a> ensures that the dates expand correctly at the time the note is created. You could instead run a shell script to just generate these notes for all dates in advance, but I like this because the KM prompt reminds me to do the crossword :)</p>
<p>The individual crossword file simply shows the PNG file generated by the Hazel rule. I might eventually add solve times to the frontmatter. For the collage, I use this dataview query in a separate note:</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb3-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">console</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">log</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Fetching pages from "Notes" with specific tag...'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> assets <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pages</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'"Notes"'</span>)</span>
<span id="cb3-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">where</span>(p <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">tags</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">includes</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"puzzles/indiamini-crossword"</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;&amp;</span> p<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">asset</span>)</span>
<span id="cb3-5">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">map</span>(page <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> {</span>
<span id="cb3-6">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Replace .pdf with .png in the asset path</span></span>
<span id="cb3-7">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> pngAsset <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> page<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">asset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">replace</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.pdf'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.png'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-8">    <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">console</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">log</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`Found page: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>page<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">path</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;"> with asset: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>pngAsset<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> {</span>
<span id="cb3-10">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">file</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> page<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">link</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb3-11">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">asset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> pngAsset <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Now the asset points to a .png file instead of a .pdf</span></span>
<span id="cb3-12">    }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-13">  })<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-14"></span>
<span id="cb3-15">dv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paragraph</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`Total images found: </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>assets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">length</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-16">assets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sort</span>()<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-17"></span>
<span id="cb3-18"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">let</span> fullstring <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-19"></span>
<span id="cb3-20"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> (assets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">length</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">===</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) {</span>
<span id="cb3-21">  dv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paragraph</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"No assets found. Check the folder, tags, and frontmatter."</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-22">} <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> {  </span>
<span id="cb3-23">  assets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">forEach</span>((item<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> index) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> {</span>
<span id="cb3-24">    fullstring <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">`![|230](</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">${</span>item<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">asset</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">)&amp;nbsp;&amp;nbsp;&amp;nbsp;`</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-25">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> ((index <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">%</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">===</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) { <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// After every third image</span></span>
<span id="cb3-26">      fullstring <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Append a line break</span></span>
<span id="cb3-27">    }</span>
<span id="cb3-28">  })<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-29">}</span>
<span id="cb3-30"></span>
<span id="cb3-31"></span>
<span id="cb3-32">dv<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paragraph</span>(fullstring)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div>
<p>The <a href="https://github.com/zremboldt/obsidian-media-grid">media grid snippet for Obsidian</a> gets the grid alignment going for the images.</p>
<p>And that’s it!</p>



 ]]></description>
  <category>workflows</category>
  <guid>https://www.neeldhara.com/blog/indiamini-crosswords/</guid>
  <pubDate>Thu, 09 May 2024 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Winning</title>
  <link>https://www.neeldhara.com/blog/poems/winning/</link>
  <description><![CDATA[ 





<p>if you find a thing <br> that is so that <br> <br> whoever has it<br> can’t keep it<br> <br> and <br> <br> whoever doesn’t have it<br> can always get it back<br> <br> then this a thing<br> that is to be avoided<br> in the beginning<br></p>
<hr>



 ]]></description>
  <category>poem</category>
  <guid>https://www.neeldhara.com/blog/poems/winning/</guid>
  <pubDate>Fri, 12 Jan 2024 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Poetry</title>
  <link>https://www.neeldhara.com/blog/poems/poetry/</link>
  <description><![CDATA[ 





<p>collect your grief<br> and inject it<br> in words<br> <br> spill them on paper<br> and shred it to tatters<br> to piece yourself together<br></p>
<hr>



 ]]></description>
  <category>poem</category>
  <guid>https://www.neeldhara.com/blog/poems/poetry/</guid>
  <pubDate>Sun, 31 Dec 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Course Plan Generator</title>
  <link>https://www.neeldhara.com/blog/course-plan/2024-spring/</link>
  <description><![CDATA[ 
<script src="plan.js"></script>
<style>
    .checkbox-container {
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
        width: 100%;
        margin-bottom: 1rem;
    }
    .custom-button {
        background-color: darkseagreen;
        border: none;
        color: white;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 1rem;
        padding: 0.5rem 1rem;
        border-radius: 0.25rem;
        cursor: pointer;
        transition: background-color 0.3s;
    }
    .custom-button:hover {
        background-color: seagreen;
    }
</style>





<p>If you are</p>
<ol type="a">
<li>teaching a course at IIT Gandhinagar next term (Jan-Apr 2024),</li>
<li>working on your course plan, and</li>
<li>need a list of dates on which you have classes,</li>
</ol>
<p>then you can use the generator below to get a list, by checking your teaching days.</p>
<p>Dates during the mid-sem exam (Feb 19 – 24, 2024) and the mid-sem recess (Mar 23 - 31, 2024) are excluded. <a href="https://iitgn.ac.in/holiday/2024">Holidays</a> are excluded too, but <em>restricted holidays are not</em>. If you need to view the holidays, you can indicate as much via the checkbox below.</p>
<p>For those outside IITGN: a standalone version is <a href="https://classplan.neeldhara.repl.co/">here</a> and the source is <a href="https://github.com/neeldhara/ClassPlan/tree/main">here</a>, in case you’d like to adapt this to your own context.</p>
<div>
<form>
<input type="checkbox" id="monday" name="day">&nbsp;Monday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="tuesday" name="day">&nbsp;Tuesday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="wednesday" name="day">&nbsp;Wednesday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="thursday" name="day">&nbsp;Thursday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="friday" name="day">&nbsp;Friday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="saturday" name="day">&nbsp; Saturday
</form>
</div>
<br> <label><input type="checkbox" id="includeHolidays" name="includeHolidays"> Include Holidays</label> <br> <label><input type="checkbox" id="indicateRestrictedHolidays"> Indicate Restricted Holidays</label> <br> <br> <button class="custom-button" onclick="generateDates()"> Generate Dates for Course Plan </button> <br><br>
<div class="sourceCode" style="background: #f1f3f5;">
<pre class="sourceCode plaintext code-with-copy"><code class="sourceCode plaintext" id="datesList">
</code>
</pre>
</div>



 ]]></description>
  <category>workflows</category>
  <guid>https://www.neeldhara.com/blog/course-plan/2024-spring/</guid>
  <pubDate>Sun, 24 Dec 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Course Plan Generator</title>
  <link>https://www.neeldhara.com/blog/course-plan/2024-fall/</link>
  <description><![CDATA[ 
<script src="plan.js"></script>
<style>
    .checkbox-container {
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
        width: 100%;
        margin-bottom: 1rem;
    }
    .custom-button {
        background-color: darkseagreen;
        border: none;
        color: white;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 1rem;
        padding: 0.5rem 1rem;
        border-radius: 0.25rem;
        cursor: pointer;
        transition: background-color 0.3s;
    }
    .custom-button:hover {
        background-color: seagreen;
    }
</style>





<p>If you are</p>
<ol type="a">
<li>teaching a course at IIT Gandhinagar next term (Jan-Apr 2024),</li>
<li>working on your course plan, and</li>
<li>need a list of dates on which you have classes,</li>
</ol>
<p>then you can use the generator below to get a list, by checking your teaching days.</p>
<p>Dates during the mid-sem exam (Feb 19 – 24, 2024) and the mid-sem recess (Mar 23 - 31, 2024) are excluded. <a href="https://iitgn.ac.in/holiday/2024">Holidays</a> are excluded too, but <em>restricted holidays are not</em>. If you need to view the holidays, you can indicate as much via the checkbox below.</p>
<p>For those outside IITGN: a standalone version is <a href="https://classplan.neeldhara.repl.co/">here</a> and the source is <a href="https://github.com/neeldhara/ClassPlan/tree/main">here</a>, in case you’d like to adapt this to your own context.</p>
<div>
<form>
<input type="checkbox" id="monday" name="day">&nbsp;Monday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="tuesday" name="day">&nbsp;Tuesday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="wednesday" name="day">&nbsp;Wednesday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="thursday" name="day">&nbsp;Thursday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="friday" name="day">&nbsp;Friday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="saturday" name="day">&nbsp; Saturday
</form>
</div>
<br> <label><input type="checkbox" id="includeHolidays" name="includeHolidays"> Include Holidays</label> <br> <label><input type="checkbox" id="indicateRestrictedHolidays"> Indicate Restricted Holidays</label> <br> <br> <button class="custom-button" onclick="generateDates()"> Generate Dates for Course Plan </button> <br><br>
<div class="sourceCode" style="background: #f1f3f5;">
<pre class="sourceCode plaintext code-with-copy"><code class="sourceCode plaintext" id="datesList">
</code>
</pre>
</div>



 ]]></description>
  <category>workflows</category>
  <guid>https://www.neeldhara.com/blog/course-plan/2024-fall/</guid>
  <pubDate>Sun, 24 Dec 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Intro to Crypto</title>
  <link>https://www.neeldhara.com/blog/crypto-intro/</link>
  <description><![CDATA[ 





<div class="callout callout-style-default callout-caution no-icon callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Background
</div>
</div>
<div class="callout-body-container callout-body">
<p>This post is based on a series of lectures that <a href="https://web.iitd.ac.in/~kvenkata/">Venkata Koppula</a> gave at IIT Gandhiangar during the inter-IIT sports meet.</p>
</div>
</div>
<section id="lecture-1-how-to-define-security" class="level2">
<h2 class="anchored" data-anchor-id="lecture-1-how-to-define-security">Lecture 1: How to define security?</h2>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
A first threat scenario, informally:
</div>
</div>
<div class="callout-body-container callout-body">
<ul>
<li>A king and an admiral share some secret information beforehand.</li>
<li>Later, the king wants to send exactly one message.</li>
<li>The admiral should learn the message.</li>
<li>No one else should learn anything.</li>
</ul>
</div>
</div>
<section id="encrpytion-and-decryption" class="level3">
<h3 class="anchored" data-anchor-id="encrpytion-and-decryption">Encrpytion and Decryption</h3>
<p>The setup:</p>
<p>Let <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BA%7D"> be an abitrary but fixed set of symbols, which we call the alphabet.</p>
<ul>
<li>The <em>key space</em> <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BK%7D"> is a set of strings over <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BA%7D">.</li>
<li>The <em>message space</em> <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BM%7D"> is also a set of strings over <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BA%7D">.</li>
<li>The <em>ciphertext space</em> <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BC%7D"> is also a set of strings over <img src="https://latex.codecogs.com/png.latex?%5Cmathcal%7BA%7D">.</li>
</ul>
<p>We also have two functions:</p>
<ol type="1">
<li>The <strong>encryption</strong> function:</li>
</ol>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BE%7D:%20%5Cmathcal%7BK%7D%20%5Ctimes%20%5Cmathcal%7BM%7D%20%5Clongrightarrow%20%5Cmathcal%7BC%7D,"></p>
<p>which takes as input a key <img src="https://latex.codecogs.com/png.latex?k%20%5Cin%20%5Cmathcal%7BK%7D"> and a message <img src="https://latex.codecogs.com/png.latex?m%20%5Cin%20%5Cmathcal%7BM%7D">, and outputs a ciphertext <img src="https://latex.codecogs.com/png.latex?c%20%5Cin%20%5Cmathcal%7BC%7D">.</p>
<ol start="2" type="1">
<li>The <strong>decryption</strong> function:</li>
</ol>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D:%20%5Cmathcal%7BK%7D%20%5Ctimes%20%5Cmathcal%7BC%7D%20%5Clongrightarrow%20%5Cmathcal%7BM%7D%20%5Ccup%20%5C%7B%5Cbot%5C%7D,"></p>
<p>which takes as input a key <img src="https://latex.codecogs.com/png.latex?k%20%5Cin%20%5Cmathcal%7BK%7D"> and a ciphertext <img src="https://latex.codecogs.com/png.latex?c%20%5Cin%20%5Cmathcal%7BC%7D">, and outputs a message <img src="https://latex.codecogs.com/png.latex?m%20%5Cin%20%5Cmathcal%7BM%7D"> or the symbol <img src="https://latex.codecogs.com/png.latex?%5Cbot"> (which is pronounced <em>bottom</em>, and captures a failure signal, e.g, on a corrupt input).</p>
<p>The encrpytion scheme is said to be <em>valid</em> if for all <img src="https://latex.codecogs.com/png.latex?(k,m)%20%5Cin%20%5Cmathcal%7BK%7D%20%5Ctimes%20%5Cmathcal%7BM%7D">, it holds that:</p>
<p><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D(k,%20%5Cmathfrak%7BE%7D(k,%20m))%20=%20m"></p>
</section>
<section id="a-secruity-definition" class="level3">
<h3 class="anchored" data-anchor-id="a-secruity-definition">A Secruity Definition</h3>
<p>Once we have a proposal for a valid encryption/decryption scheme, we would like to know if it is a decent one: and in our context, we like schemes that can survive adverserial attacks: imagine someone snooping over the communication channel, and trying to learn the message from the ciphertext — we would like to make claims to the effect of “that won’t be possible”.</p>
<p>To formalize this, we have the notion of a security game, which is a game played between two players: a challenger and an adversary. The challenger is the one who sets up the game, and the adversary is the one who tries to break the scheme. Here’s what the game looks like:</p>
<ol type="1">
<li>The challenger picks a key <img src="https://latex.codecogs.com/png.latex?k%20%5Cin%20%5Cmathcal%7BK%7D"> uniformly at random and a picks a bit <img src="https://latex.codecogs.com/png.latex?b%20%5Cin%20%5C%7B0,1%5C%7D"> uniformly at random</li>
<li>The adversary sends the challenger two messages <img src="https://latex.codecogs.com/png.latex?m_0"> and <img src="https://latex.codecogs.com/png.latex?m_1">.</li>
<li>The challenger sends the ciphertext <img src="https://latex.codecogs.com/png.latex?c%20=%20%5Cmathfrak%7BE%7D(k,%20m_b)"> to the adversary.</li>
<li>The adversary outputs a bit <img src="https://latex.codecogs.com/png.latex?b'">.</li>
<li>The adversary wins if <img src="https://latex.codecogs.com/png.latex?b%20=%20b'">.</li>
</ol>
<p>Note that an adversary that outputs a bit in step 4 by tossing a coin (<code>1</code> if <code>H</code> and <code>0</code> if <code>T</code>) wins this game with probability <img src="https://latex.codecogs.com/png.latex?1/2">.</p>
<p>A self-respecting adversary will want to fare better, while a scheme worth its salt will not want to be vulnerable with respect to <em>any</em> adverseray, so we say that:</p>
<ul>
<li>an adversary wins this game if they can win it with probability greater than half, and,</li>
<li>a scheme is secure if no adversary can win this game with probability greater than half.</li>
</ul>
</section>
<section id="example-an-insecure-scheme" class="level3">
<h3 class="anchored" data-anchor-id="example-an-insecure-scheme">Example: An Insecure Scheme</h3>
<p>Consider a lazy encryption scheme that does not encrypt a message at all:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BE%7D(k,m)%20=%20m"> and</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D(k,c)%20=%20c">.</li>
</ul>
<p>It is easy to see that there is an adversary who can win the security game defined above with probability 1, so this is not a terribly smart scheme. The same is true for schemes that rotate the message by a fixed amount (why?).</p>
</section>
<section id="example-an-secure-scheme" class="level3">
<h3 class="anchored" data-anchor-id="example-an-secure-scheme">Example: An Secure Scheme</h3>
<p>Assume the message space, key space, and ciphertext space are all <img src="https://latex.codecogs.com/png.latex?n">-bit strings for some arbitrary but fixed choice of <img src="https://latex.codecogs.com/png.latex?n">. Consider the following encryption scheme:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BE%7D(k,m)%20=%20k%20%5Coplus%20m"> and</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D(k,c)%20=%20k%20%5Coplus%20c">.</li>
</ul>
<p>It turns out that this scheme is secure, intuitively because for any ciphertext <img src="https://latex.codecogs.com/png.latex?c">, there are two keys <img src="https://latex.codecogs.com/png.latex?k_1"> and <img src="https://latex.codecogs.com/png.latex?k_2"> which are such that:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D(k_1,c)%20=%20m_0">, and</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D(k_2,c)%20=%20m_1">,</li>
</ul>
<p>for any two messages <img src="https://latex.codecogs.com/png.latex?m_0"> and <img src="https://latex.codecogs.com/png.latex?m_1">, so there is no way for the adversary to reverse engineer the bit <img src="https://latex.codecogs.com/png.latex?b">.</p>
<p>(Exercise: prove this formally.)</p>
</section>
<section id="example-another-insecure-scheme" class="level3">
<h3 class="anchored" data-anchor-id="example-another-insecure-scheme">Example: Another Insecure Scheme</h3>
<p>Assume the message space and ciphertext space are <img src="https://latex.codecogs.com/png.latex?2n">-bit strings for some arbitrary but fixed choice of <img src="https://latex.codecogs.com/png.latex?n">, and the key space is the set of all <img src="https://latex.codecogs.com/png.latex?n">-bit strings. Consider the following encryption scheme:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BE%7D(k,m)%20=%20(k%20%7C%20k)%20%5Coplus%20m"> and</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D(k,c)%20=%20(k%20%7C%20k)%20%5Coplus%20c">,</li>
</ul>
<p>where <img src="https://latex.codecogs.com/png.latex?(a%20%7C%20b)"> denotes the concatenation of two strings.</p>
<p>It turns out that this scheme is <em>not</em> secure (why?).</p>
</section>
<section id="a-stronger-secruity-definition" class="level3">
<h3 class="anchored" data-anchor-id="a-stronger-secruity-definition">A Stronger Secruity Definition</h3>
<p>Consider the following extended security game:</p>
<ol type="1">
<li>The challenger picks a key <img src="https://latex.codecogs.com/png.latex?k%20%5Cin%20%5Cmathcal%7BK%7D"> uniformly at random and a picks a bit <img src="https://latex.codecogs.com/png.latex?b%20%5Cin%20%5C%7B0,1%5C%7D"> uniformly at random.</li>
<li>The adversary sends the challenger two messages <img src="https://latex.codecogs.com/png.latex?m_%7B00%7D"> and <img src="https://latex.codecogs.com/png.latex?m_%7B01%7D">.</li>
<li>The challenger sends the ciphertext <img src="https://latex.codecogs.com/png.latex?c_0%20=%20%5Cmathfrak%7BE%7D(k,%20m_%7B0b%7D)"> to the adversary.</li>
<li>The adversary sends the challenger two messages <img src="https://latex.codecogs.com/png.latex?m_%7B10%7D"> and <img src="https://latex.codecogs.com/png.latex?m_%7B11%7D">.</li>
<li>The challenger sends the ciphertext <img src="https://latex.codecogs.com/png.latex?c_1%20=%20%5Cmathfrak%7BE%7D(k,%20m_%7B1b%7D)"> to the adversary.</li>
<li>The adversary outputs a bit <img src="https://latex.codecogs.com/png.latex?b'">.</li>
<li>The adversary wins if <img src="https://latex.codecogs.com/png.latex?b%20=%20b'">.</li>
</ol>
<p>As before, we say that:</p>
<ul>
<li>an adversary wins this game if they can win it with probability greater than half, and,</li>
<li>a scheme is secure if no adversary can win this game with probability greater than half.</li>
</ul>
<p>However, in the extended game, we have empowered the adversary to a point where <em>no</em> deterministic scheme can be secure in this stronger sense! Here’s why:</p>
<ul>
<li>Suppose the adversary picks: <img src="https://latex.codecogs.com/png.latex?m_%7B00%7D%20=%200%5En">, <img src="https://latex.codecogs.com/png.latex?m_%7B01%7D%20=%201%5En">, <img src="https://latex.codecogs.com/png.latex?m_%7B10%7D%20=%200%5En">, <img src="https://latex.codecogs.com/png.latex?m_%7B11%7D%20=%2001%5E%7Bn-1%7D">.</li>
<li>Then the adversary returns <img src="https://latex.codecogs.com/png.latex?0"> if <img src="https://latex.codecogs.com/png.latex?c_0"> and <img src="https://latex.codecogs.com/png.latex?c_1"> are identical, and <img src="https://latex.codecogs.com/png.latex?1"> otherwise.</li>
</ul>
<p>Note that this particular adversary wins with probability 1, no matter what <img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BE%7D"> and <img src="https://latex.codecogs.com/png.latex?%5Cmathfrak%7BD%7D"> are.</p>
<p>What can we say about <em>randomized</em> schemes? Can they be secure in the extended setting?</p>


</section>
</section>

 ]]></description>
  <category>talk</category>
  <category>exposition</category>
  <guid>https://www.neeldhara.com/blog/crypto-intro/</guid>
  <pubDate>Wed, 20 Dec 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Exportober 2023</title>
  <link>https://www.neeldhara.com/blog/2023-exportober-workflows/</link>
  <description><![CDATA[ 





<p>I am going to use this post to document 31 workflows for feeling good about day to day work at the computer, one for each day of October, hopefully! Most of this will be in the context of macOS, but hopefully the principles are adataptable to the platforms and tools of your choice.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-1-contents" aria-controls="callout-1" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
(10/01). Faux Hot Key Sequences in Keyboard Maestro
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-1" class="callout-1-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Turns out I am terrible with remembering keyboard shorcuts, so in an ideal world I’d like to have things triggered by single key presses that are awfully predictably related to whatever I want. For example, hit the “b” key to type out a 🟦. Now this is not tenable of course: there are multiple things vying for the “b” trigger, including, well, the letter <em>b</em> wanting to be typed out.</p>
<p>A natural solution is to have a keystroke sequence for disambiguation. So in principle something like “e” followed by “b”, where the first “e” signals that they keyboard is to prepare itself for an emoji-based trigger, and the “b” does the blue square thing. However, pure key sequences are also going to get in your way, because most of them will be substrings of naturally typed text.</p>
<p>So you’d want a hot key trigger to say you’re going into shortcut mode first: something like <code>Cmd+K → e → b</code>. BTT supports such sequences out of the box, but Keyboard Maestro, my default tool for such matters, does not with the following explanation in their <a href="https://wiki.keyboardmaestro.com/Frequently_Asked_Questions#How_do_I_use_a_multiple_keystroke_trigger">FAQ</a>:</p>
<blockquote class="blockquote">
<p>But Keyboard Maestro does not directly support assigning a two-keystroke hot key to a trigger. The problem with multiple keystroke triggers like Option-F R is what to do if you type Option-F A?</p>
<p>Logic dictates that the Option-F A should go through to the system unimpeded, but Option-F R should be swallowed entirely. But this is impossible. The only way to do it would be to swallow the Option-F key, and then swallow the second key and then resubmit the Option F and the second key unless it matches Option-F R.</p>
<p>However, that is fraught with peril and cannot work robustly in the presence of other applications placing things on the keyboard event queue (or even a sufficiently fast typist).</p>
<p>For example, suppose you quickly typed Option-F A B. Keyboard Maestro would have swallowed the Option F and then the A, and then resubmitted it to the event queue, resulting in the stream of characters B, Option-F, A. There is no way to avoid this race condition, and as such Keyboard Maestro does not support any such mechanism.</p>
<p>As described above, Keyboard Maestro has a variety of ways you can use Option-F as a hot key that allows a second key to be used to select a macro. However in all cases it is clear that the Option-F has been used and there is no concept that the Option-F might come back later to do something else.</p>
</blockquote>
<p>However, as a tip from the same FAQ suggests, you can more or less achieve the desired effect by using macro grouping and group activation triggers. So I have a macro group that triggers the square emojis by single keystrokes like so:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/2023-exportober-workflows/blue-square-emoji.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>Keyboard Maestro macro group for emoji triggers</figcaption>
</figure>
</div>
<p>…but this macro group is only activated for one action at a time, and its activation is triggered by <em>another KM macro</em> - whose only job is to activate this macro group for a single action, like so:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/2023-exportober-workflows/trigger-emoji-squares.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>Keyboard Maestro macro for activating emoji macro group</figcaption>
</figure>
</div>
<p>You might notice that this trigger is also a single keypress (in this example, “U”). This entire macro group is activated for one action with the <code>Cmd+Alt+K</code> keystroke. So effectively I only remember the <code>Cmd+Alt+K</code> keystroke, which activates this collection of macros for one action:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/2023-exportober-workflows/meta-macro-group.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>Meta Macros in KM</figcaption>
</figure>
</div>
<p>…and from here I just have to press “U” followed by “B” to get my 🟦. Just this two-level triggering gives access to potentially 500+ triggers that mneomically efficient, and potentially many more actions (for example, you could map “B” to a bunch of different emojis that share blue as the predominant color, and KM will display a pallette for you to do the final disamiguiation).</p>
<p>IRL I use <a href="https://matthewpalmer.net/rocket/">Rocket</a> by <a href="https://matthewpalmer.net/">Matthew Palmer</a> to pick out emojis quickly (thanks to a <a href="https://twitter.com/wesbos/status/790607013680074752?lang=mr">tip</a> from <a href="https://wesbos.com/">Wes Bos</a>), or just the built-in macOS picker. But I do find the setup described above handy for some unicode symbols that I frequently use.</p>
<p>I should mention <a href="https://medium.com/@nikitavoloboev/karabiner-god-mode-7407a5ddc8f6">God Mode</a> as another popular way to reduce clutter in the keyboard shortcut mindspace, but I never really got used to Karabiner and am too used to the left CAPS key being mapped to Ctrl for me to give that up to the hyper key.</p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-2-contents" aria-controls="callout-2" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
(10/02). File Searches with Alfred App
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-2" class="callout-2-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>To open a file, I simply open up <a href="https://www.alfredapp.com/">Alfred</a> and press the spacebar or the <code>'</code> symbol and start typing out a filename. This is enabled by going in to Alfred preferences and making sure that <code>Quick Search: Enable Quick File Search mode</code> is enabled:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/2023-exportober-workflows/alfred-file-search.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>Alfred Quick File Search</figcaption>
</figure>
</div>
<p>Most launchers have some kind of file search enabled, so look out for it even if you are on, say, <a href="https://www.raycast.com/">Raycast</a>, or <a href="https://www.obdev.at/launchbar">Launchbar</a>, or something else.</p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-3-contents" aria-controls="callout-3" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
(10/03). Bookmarks with Static Marks
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-3" class="callout-3-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>I use <a href="https://darekkay.com/static-marks/">StaticMarks</a> to track key locations across the web and my filesystem. Typically, any project that I am working on has some subset of the following key links:</p>
<ul>
<li>A Drive/Dropbox or local Folder</li>
<li>A Notes Folder within my PKM system of choice (Obsidian/Quarto)</li>
<li>A Notion or Things page that tracks tasks</li>
<li>A Zoom/Meet URL if meetings/classes are online</li>
<li>Other External URLs (spreadsheets, grading pages, pages on Overleaf/Github, key email threads, and so forth)</li>
</ul>
<p>I now dump most of this in a YAML file (using <a href="https://hookproductivity.com/">Hookmark</a> for local folders, so that the links persist even if I move things around) now, and have a few HTML pages that give me a quick overview of all my major projects. I typically restrict myself to the first three or four links, because that covers 90% of what I need quickly, and the other associated external URLs go into the notes page that I have for the project in my whatever-system, so they do end up being at most one hop away from the static marks page.</p>
<p>Previously I used to try to maintain everything within <a href="https://arc.net/">Arc</a> folders but that got somewhat out of hand, so I swept it all clean and only have more or less top level folders in Arc now representing major themes that I can categorize my efforts into, and each such theme has its own static marks file that I can use to get a nice, searchable big picture.</p>
<p>One thing that I do find annoying in general is the fact that reference material is often common to multiple efforts (e.g, the same papers relevant to multiple research projects). Since I access my files by search, I am perhaps more sensitive than usual to any kind of redundancy — it clutters up the search results (besides, I prefer a single source of truth on, say PDFs, because I am typically annotating them). These days, I keep my reference material separate from projects, and link them to projects using either a PKM system, or more casually, using Hookmark.</p>
<p>Related: <a href="https://bunchapp.co/">Bunch</a> by <a href="https://brettterpstra.com/">Brett Terpstra</a> is a handy plaintext automation tool: the website has some really indicative use cases, go check it out! I don’t use this myself but am looking forward to incorporating it into my workflow once my life is sorted enough for me to figure out what I typically do in the context of a specific project, and for said things to be sufficiently distinguishable from complete chaos :)</p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-4-contents" aria-controls="callout-4" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
(10/04). Search Links by Brett Terpstra
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-4" class="callout-4-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>If you’ve used <code>Cmd+K</code> on Google docs, you may have noticed — and even been spoiled by — how Google can figure out your links for you based on the content of the selected text:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/2023-exportober-workflows/gdoc-autosuggest-links.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>Google Docs link search</figcaption>
</figure>
</div>
<p>If you want something similar while editing Markdown files, look no further than the <em><a href="https://brettterpstra.com/projects/searchlink/">Search Links</a></em> service by <a href="https://brettterpstra.com/">Brett Terpstra</a>. It basically has the same effect: my experience is that I select some text and press a shortcut to invoke Search Links, which then does its thing in the background, and then my selected text is replaced by a markdown-formatted link. The results may not be always what you are looking for (I usually try to keep the text descriptive, and potentially edit later if required), but it works most of the time, and saves me the back and forth of having to open a browser, look for the link, copy it over, paste it back and format it in a markdown-appropriate manner. Great for when you don’t want to leave your editor!</p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-5-contents" aria-controls="callout-5" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
(10/05). Send to Alfred
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-5" class="callout-5-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>When something is selected (a bunch of text, or a file or a folder), I can double-tap the <code>Alt</code> key to “send” the material to <a href="https://www.alfredapp.com/">Alfred</a>, and to process it further from there. This is very handy: for example, if I want some text switched to title case, it’s a few quick keystrokes: double-tap <code>Alt</code> on selected text, then <code>Ctrl+A</code> to move to the start of text, type out “case”, and then <code>Cmd + 3</code>: this replaces the selected text with the same text but in title case. This works because I have the <a href="https://github.com/gillibrand/alfred-change-case">case switch Alfred workflow</a> enabled. I also use this often to open a folder from Finder in VSCode: select folder → send to Alfred → <code>Open With...</code> → choose VSCode.</p>
<p>Note: I am yet to find something equivalent to this on Raycast, if anyone has a pointer, please let me know!</p>
</div>
</div>
</div>



 ]]></description>
  <category>workflows</category>
  <guid>https://www.neeldhara.com/blog/2023-exportober-workflows/</guid>
  <pubDate>Sat, 30 Sep 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Building Interactives</title>
  <link>https://www.neeldhara.com/blog/building-interactives/</link>
  <description><![CDATA[ 





<section id="background" class="level2">
<h2 class="anchored" data-anchor-id="background">Background</h2>
<p>Interactions and visualizations have been useful for explaining concepts, although they are known to potentially mislead or confuse as often as they have been thought of as tools that help clarify concepts. <a href="https://visualgo.net/en">VisuAlgo</a> is a very successful<sup>1</sup> example of interactive learning in CS education at an undergraduate level, which brings the algorithms that one would typically encounter in an introductory algorithms course to life: users can often provide their own input, and the interface does the rest. On the bottom-right corner one can typically see an implementation of the algorithm in code, which is “run through” as elements get manipulated on a “main stage”.</p>
<p>Other examples of deeply interactive experiences include:</p>
<ol type="1">
<li><a href="https://brilliant.org/home/">Brilliant</a></li>
<li><a href="https://mathigon.org/">Mathigon</a></li>
<li><a href="https://seeing-theory.brown.edu/">Seeing Theory</a></li>
<li><a href="https://ncase.me/crowds/">The Wisdom and/or Madness of the Crowds</a></li>
<li><a href="https://ncase.me/trust">The Evolution of Trust</a></li>
<li><a href="https://ncase.me/polygons/">Parable of the Polygons</a></li>
<li><a href="https://ncase.me/ballot/">To Build a Better Ballot</a></li>
<li><a href="https://eater.net/quaternions">Visualizing Quaternions</a></li>
<li><a href="https://ciechanow.ski/mechanical-watch/">Mechanical Watch</a></li>
</ol>
<p>…to name a few. These combine interactive workouts interleaved with text, and usually encourage active participation from the reader. However, while such tools can be invaluable, they are often tedious and time-consuming to build, not to mention that they require fairly specialized expertise. For instance, Ben Eater, the creator of the quaternions visualization, says about the process of builiding the visualization<sup>2</sup>:</p>
<blockquote class="blockquote">
<p><em>Since there wasn’t really anything like this yet, we built it all ourselves from a variety of existing web tools: WebGL (using threejs plus some custom shaders) for 3d stuff, raw canvas for the 2d stuff, howlerjs for handling the audio playback, and lots of React for the UI and to glue it all together. It’s very much a bespoke app. In the future, I hope we’ll build more of these and as we do so, the tech will evolve to something more easily generalized.</em></p>
</blockquote>
<p>The availability of tools like chatGPT and its ilk, powered by large language models, have been the subject of much heated debate, especially in the context of their role in education. They have been viewed (e.g, by <a href="https://www.turnitin.com/blog/sneak-preview-of-turnitins-ai-writing-and-chatgpt-detection-capability">plagiairsm detectors</a>, where <a href="https://www.k12dive.com/news/turnitin-false-positives-AI-detector/652221/">challenges about false positives</a> persist) as tools that can help students cheat, although there is also much work arguing for their use in helping students learn.</p>
<p>Here, I want to focus on something perhaps more mundane, but a theme that has been one of my favorite chatGPT use cases over the last few months: it’s utility in helping create materials that are too tedious to bring to life otherwise. It turns out that I often envision neat little interactive experiences when I am thinking about how to describe something: it could just be a thing that lets folks play with examples to build out some intuition or it could be something that helps bring out a specific element of an argument or an idea. However, the barrier of entry to creating those experiences myself is <em>just a little out of reach</em>, enough for me to not do it. But with the kind of help I have had from chatGPT, I feel invested enough to mess around.</p>
<p>For a lot of standard topics, there are plenty of visualizations and interactive experiences already available: so one might wonder if this is worth it. I do think that leveraging existing content that’s already been done well is important, but: (a) not everything is already done, and (b) experiences created from scratch allow for instructors to incorporate their own variations on the textbook premise, and would also offer the flexibility to be transformed into assessments — both of these goals are often hard to meet with off-the-shelf demonstrations.</p>
<p>Note: Although a lot of this discussion is about how instructors can leverage chatGPT as a tool to efficiently create visualizations and interactive experiences for their learners, none of the text in the blog itself is generated with AI 😀 To make this distinction clear, all text quoted verbatim from either books or chatGPT’s output will be placed in grey boxes. Prompts to chatGPT are not AI-generated either and are shown in boxes with a green background.</p>
</section>
<section id="for-instructors" class="level2">
<h2 class="anchored" data-anchor-id="for-instructors">For Instructors</h2>
<p>I’ll describe two examples of visualizations of textbook topics that may not be widely available otherwise. The entire chatlogs for the specific demonstrations can be found as PDFs at the following links:</p>
<ol type="1">
<li><a href="chatGPT-subtraction-chatlog.pdf">Subtraction Game</a></li>
<li><a href="tape-drag-drop.pdf">File Storage 1</a></li>
<li><a href="draggable-tape.pdf">File Storage 2</a></li>
</ol>
<p>(The May 12 release of chatGPT was in use.)</p>
<section id="exhibit-a.-the-subtraction-game" class="level3">
<h3 class="anchored" data-anchor-id="exhibit-a.-the-subtraction-game">Exhibit A. The Subtraction Game</h3>
<p>The subtraction game is the following.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
The Game of Subtraction
</div>
</div>
<div class="callout-body-container callout-body">
<p><span class="smallcaps">Subtraction</span> is a game played on a heap of tokens. Each turn, the current player can remove either 1, 2, or 3 tokens from the pile, provided enough tokens exist. When the pile is empty there are no available moves. In this text, we will use a fancy number script to denote a subtraction position, e.g.&nbsp;S for a subtraction game with five tokens. Sample game: <img src="https://latex.codecogs.com/png.latex?6%20%5Crightarrow%205%20%5Crightarrow%203%20%5Crightarrow%200"> Starting from a pile of 6 , the first player takes one, then the second player takes two, then the first player takes all three to win the game.</p>
<p><em>— from <a href="http://kyleburke.info/PlayingWithDiscreteMath.pdf">Playing with Discrete Math</a>.</em></p>
</div>
</div>
<p>The text goes on to encourage the reader to play the game to develop a feel for it, and uses the game as a running example to develop various concepts in combinatorial game theory, including strategies, positions, game trees, and so on.</p>
<p>The game of <span class="smallcaps">Subtraction</span> can doubtless be played in a low-tech environment using a whiteboard, pen and paper, or an actual heap of tokens. However, an instructor may want to make an interactive version of the game available as a part of instructional material such as lecture notes. At this point, an instructor may look for an existing implementations, although in this particular example this may turn out to be a bit of a challenge: the internet is rife with so-called “subtraction” games, most of which have nothing to do with the game at hand. Besides, a custom implementation would provide a starting point for the development of related concepts, customized quizzes, and so on.</p>
<p>As discussed earlier, creating a playable version of <span class="smallcaps">Subtraction</span> from scratch is arguably not a difficult exercise, but for most people it would be time-consuming to the point where the cost may outweigh the benefits. However, with a tool like chatGPT at hand, the process becomes substantially easier.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Prompt
</div>
</div>
<div class="callout-body-container callout-body">
<p>We are going to code a simple HTML/JS/CSS game.</p>
<p>Please create a game arena that is a 420 x 420 canvas with rounded corners. The background outside the canvas should be lightseagreen.</p>
<p>All the elements below should be centered within the canvas.</p>
<p>Inside the canvas, close to the top, draw a box with a random number between 15 and 50.</p>
<p>Just below this box, draw three boxes labeled 1, 2, and 3.</p>
<p>Just below these three boxes, display the text: “Lata’s turn to move.” Let us call this string ’whoseTurn‘.</p>
<p>Just below this text, add a link that says “Instructions”. This should bring up a modal with the text “SUBTRACTION is a game played on a heap of tokens. Each turn, the current player can remove either 1, 2, or 3 tokens from the pile, provided enough tokens exist. When the pile is empty there are no available moves. The player with no valid moves left loses.”.</p>
<p>Finally, when the user clicks on either 1, 2, or 3, the number in the central box should reduce by 1, 2, or 3 respectively. If the subtraction results in a negative number, disregard the click and alert the user that “Only moves resulting in a positive result remaining.”</p>
<p>When a button is clicked, if whoseTurn is “Lata’s turn to move”, then it should change to “Raj’s turn to move”, and vice versa.</p>
<p>When the number hits 0, if whoseTurn is “Lata’s turn to move”, then update whoseTurn to “Game over, Lata won”, and “Game over, Raj won” otherwise. At this point, none of the buttons should be clickable.</p>
</div>
</div>
<p>The output of chatGPT on this prompt, with some minor modifications in styling, leads to an interface that looks as shown below:</p>
<div id="fig:001" class="quarto-figure quarto-figure-center anchored">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/building-interactives/image001.png" class="img-fluid figure-img"></p>
<figcaption>An interactive version of Subtraction.</figcaption>
</figure>
</div>
<p>A natural extension to the game of subtraction is go beyond the numbers 1,2, and 3. One might then use a follow up prompt such as the one below.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Prompt
</div>
</div>
<div class="callout-body-container callout-body">
<p>Can you make it so that instead of 1, 2, 3, the buttons display three distinct random numbers between 1 and 9 (inclusive), and the rules are the same?</p>
</div>
</div>
<p>In this process we realize that the players may run out of moves even before the number in question hits zero. An easy way to mitigate this is to ensure that one of the numbers is always one, while the others are randomly chosen. The output of chatGPT may have minor issues: for instance, the documentation in the instructions modal would possibly not adapted to the new set of numbers, the buttons may display the numbers in non-ascending order, and so on. All of these “quirks” are easily fixed with follow up prompts, and a working demonstration of the final implementation can be found <a href="https://subtraction.netlify.app/">here</a>.</p>
</section>
<section id="exhibit-b.-storing-files-on-tape" class="level3">
<h3 class="anchored" data-anchor-id="exhibit-b.-storing-files-on-tape">Exhibit B. Storing Files on Tape</h3>
<p>The problem of optimally storing files on a tape is a classic example of an optimization problem that admits a greedy algorithm: the intuitive approach to the solution turns out to be the correct one.</p>
<p>We reproduce the problem statement as given in <a href="http://jeffe.cs.illinois.edu/teaching/algorithms/">Algorithms</a> by <a href="http://jeffe.cs.illinois.edu/">Jeff Erickson</a>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
The Optimal File Storage Problem
</div>
</div>
<div class="callout-body-container callout-body">
<p>Suppose we have a set of <img src="https://latex.codecogs.com/png.latex?n"> files that we want to store on magnetic tape. <img src="https://latex.codecogs.com/png.latex?%7B%20%7D%5E1"> In the future, users will want to read those files from the tape. Reading a file from tape isn’t like reading a file from disk; first we have to fast-forward past all the other files, and that takes a significant amount of time. Let <img src="https://latex.codecogs.com/png.latex?L%5B1..n%5D"> be an array listing the lengths of each file; specifically, file <img src="https://latex.codecogs.com/png.latex?i"> has length <img src="https://latex.codecogs.com/png.latex?L%5Bi%5D">. If the files are stored in order from 1 to <img src="https://latex.codecogs.com/png.latex?n">, then the cost of accessing the <img src="https://latex.codecogs.com/png.latex?k"> th file is <img src="https://latex.codecogs.com/png.latex?%5Coperatorname%7Bcost%7D(k)=%5Csum_%7Bi=1%7D%5Ek%20L%5Bi%5D"></p>
<p>The cost reflects the fact that before we read file <img src="https://latex.codecogs.com/png.latex?k"> we must first scan past all the earlier files on the tape. If we assume for the moment that each file is equally likely to be accessed, then the expected cost of searching for a random file is <img src="https://latex.codecogs.com/png.latex?%5Cmathrm%7BE%7D%5B%5Coperatorname%7Bcost%7D%5D=%5Csum_%7Bk=1%7D%5En%20%5Cfrac%7B%5Coperatorname%7Bcost%7D(k)%7D%7Bn%7D=%5Cfrac%7B1%7D%7Bn%7D%20%5Csum_%7Bk=1%7D%5En%20%5Csum_%7Bi=1%7D%5Ek%20L%5Bi%5D%20."> If we change the order of the files on the tape, we change the cost of accessing the files; some files become more expensive to read, but others become cheaper. Different file orders are likely to result in different expected costs. Specifically, let <img src="https://latex.codecogs.com/png.latex?%5Cpi(i)"> denote the index of the file stored at position <img src="https://latex.codecogs.com/png.latex?i"> on the tape. Then the expected cost of the permutation <img src="https://latex.codecogs.com/png.latex?%5Cpi"> is <img src="https://latex.codecogs.com/png.latex?%5Cmathrm%7BE%7D%5B%5Coperatorname%7Bcost%7D(%5Cpi)%5D=%5Cfrac%7B1%7D%7Bn%7D%20%5Csum_%7Bk=1%7D%5En%20%5Csum_%7Bi=1%7D%5Ek%20L%5B%5Cpi(i)%5D%20."> Which order should we use if we want this expected cost to be as small as possible? The answer seems intuitively clear: <strong>Sort the files by increasing length.</strong> But intuition is a tricky beast. <strong>The only way to be sure that this order works is to</strong> take off and nuke the entire site from-orbit <strong>actually prove that it works!</strong></p>
<p><em>— From <a href="http://jeffe.cs.illinois.edu/teaching/algorithms/">Algorithms</a>.</em></p>
</div>
</div>
<p>Now the key to appreciating the proof of the greedy algorithm here is to see that if we violate the “natural order” then we pay more in expected cost. While the calculation is straightforward, an instructor may find that it makes sense to motivate the main idea by allowing the learners to play around with some examples.</p>
<p>There are two approaches to visualizing this problem. In both cases, the stage consists of a tape represented as a long horizontal rectangle, and the files are represented as rectangles whose height matches the height of the tape, and whose lengths are proportional to their sizes. The expected cost of access of whatever is on the tape is displayed at all times, along with the optimal cost possible.</p>
<ul>
<li><p>A predefined set of files are given and are initially placed outside the tape. The user can position them on the tape by, for example, dragging and dropping them on the tape, or double clicking them: in either case, the chosen file is appended to the end of the tape. We may allow the user to reorder the files on the tape by drag and drop actions or remove them off the tape entirely. The expected cost is dynamically calculated and displayed.</p></li>
<li><p>A set of files, say all equal in size, are already on the tape. The learner can then drag the boundaries to change the file lengths, and the change in costs update dynamically.</p></li>
</ul>
<section id="the-first-approach" class="level4">
<h4 class="anchored" data-anchor-id="the-first-approach">The First Approach</h4>
<p>To create the first visualization, we started with the following prompt.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Prompt
</div>
</div>
<div class="callout-body-container callout-body">
<p>I want to help students understand the problem of “storing files on a tape”. I am seeking your help in creating the following interface via HTML, JS, and CSS. What I want is for the user to be able to drag and drop several rectangular blocks (which I will refer to as pieces henceforth), whose total length is a fixed number of units, on to something that looks like a tape.</p>
<p>So the interface should have a thin rectangular strip (which I will refer to as a tape henceforth) with a grey background at the center, and a collection of draggable pieces placed below it (none overlapping). When a piece is dropped on the tape, it should snap and align to the left without overlapping any of the strips that are already there. When a piece is dragged out of the tape, it should disappear from the tape and the pieces to the right of it should move leftward until the gap is filled.</p>
<p>Please make the total length of the tape 420px wide, and the lengths of the pieces should be either 20px, 30px, 40px, or 50px wide; and they should be made of different colors from a neutral palette. Note that the piece lengths should be generated randomly from this set, they should add up to 420px.</p>
<p>Let N be the number of pieces on the tape at any given point of time. There should be a display which shows the sum of the following quantities (and this should update as pieces are added or dropped on the top): the length of the first (i.e, leftmost) piece multiplied by N, the length of the second piece multiplied by (N-1), and so on, until the length of the last piece, multiplied by 1.</p>
</div>
</div>
<p>The first few outcomes on this and subsequent prompts had several issues:</p>
<ul>
<li><p>the boxes were not stacked horizontally;</p></li>
<li><p>the drag and drop behaviors were unpredictable;</p></li>
<li><p>the pieces had spacing between them when pushed on the tape.</p></li>
</ul>
<p>However, all of this was eventually fixed by describing the inaccuracies in natural language. We also added some functionality allowing the learner to see if their attempt was optimal:</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Prompt
</div>
</div>
<div class="callout-body-container callout-body">
<p>Below average, can we add the following text: “Target:” followed by the sum of the following numbers, where X is the total number of pieces:</p>
<p>the size of the smallest piece multiplied by X the size of the second smallest piece multiplied by X-1 and so on up to the size of the second largest piece multiplied by 2 the size of the largest piece multiplied by 1</p>
<p>Below the target, display the text “Keep going until all pieces are on the tape”, and if the tape has all the pieces but the average is not equal to the target, change the message to “Nice try, but you can do better!” and if the tape has all the pieces and the average is equal to the target, change the message to “Mission Accomplished!”.</p>
</div>
</div>
<p>Eventually, we obtain an interface that looks as shown in with some minor styling and updates in the desired widths.</p>
<p>Notice that one of the things that chatGPT had to do was randomly generate a set of pieces from a given set of widths that added up the exact width of the tape (as per our prompt). It did this using the following loop:</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Output
</div>
</div>
<div class="callout-body-container callout-body">
<pre><code>  // Create pieces
    let totalWidth = 0;
    while(totalWidth &lt; 420) {
      
    const size = 
      sizes[Math.floor(Math.random() 
      * sizes.length)];

      if(totalWidth + size &lt;= 420) {
        totalWidth += size;
        // Code to create the pieces
      }
    }</code></pre>
</div>
</div>
<p>Evidently, if the sizes array does not have an appropriate set of sizes, this can loop forever. It turns out that chatGPT did not recognize this issue on its own, and it is typical of the sort of bug that the user would have to watch out for, either at the time of formulating specifications or while working through the output.</p>
<p>You can play around with the implementation that I finally ended up with <a href="https://filestorage1.netlify.app/">here</a>.</p>
</section>
<section id="the-second-approach" class="level4 unnumbered">
<h4 class="unnumbered anchored" data-anchor-id="the-second-approach">The Second Approach</h4>
<p>For the second approach, we start off with the following prompt.<sup>3</sup></p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Prompt
</div>
</div>
<div class="callout-body-container callout-body">
<p>Please give me separate css, js, and html files for the following demonstration</p>
<p>What I want initially is as follows</p>
<ul>
<li><p>centered on the screen there is a 420px x 50px horizontal slab</p></li>
<li><p>there are three draggable dividers shown as black dotted lines inside the slab that divide the region equally into 4 parts of width 105 eac</p></li>
<li><p>the regions should initially display the number 105.</p></li>
</ul>
<p>If a divider is dragged, it changes the width of at most two regions that it is involved in. These regions should update their width. If any region becomes smaller than 20 px on drag, then any further drag should not be possible</p>
<p>Then I want a text below the slab which says cost, followed by the sum of the following numbers</p>
<ul>
<li><p>the width of the leftmost region * 4</p></li>
<li><p>the width of the region next to the leftmost region * 3</p></li>
<li><p>the width of the region to the left of the rightmost region * 2</p></li>
<li><p>the width of the rightmost region * 1</p></li>
</ul>
<p>divided by 4. This number should be dynamically updated as the regions change</p>
<p>Below cost, compute the following quantity and display it, prepended with the text “Optimal Cost”</p>
<ul>
<li><p>the width of the smallest region * 4</p></li>
<li><p>the width of the second-smallest region * 3</p></li>
<li><p>the width of the second-largest region * 2</p></li>
<li><p>the width of the largest region * 1</p></li>
</ul>
<p>divided by 4.</p>
</div>
</div>
<p>For visual clarity we also follow up with the following suggestion.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
chatGPT Prompt
</div>
</div>
<div class="callout-body-container callout-body">
<p>Can the background color be Mediumseagreen but with opacity proportional to the width (i.e, more opaque for wider regions and more transparent for smaller ones)?</p>
</div>
</div>
<figure id="fig:003" class="figure">
<figure class="figure">
<img src="https://www.neeldhara.com/blog/building-interactives/image003-a.png" class="figure-img">
<figcaption>
The initial configuration
</figcaption>
</figure>
<figure class="figure">
<img src="https://www.neeldhara.com/blog/building-interactives/image003-b.png" class="figure-img">
<figcaption>
An example where the current cost is worse than the optimal cost.
</figcaption>
</figure>
<figure class="figure">
<img src="https://www.neeldhara.com/blog/building-interactives/image003-c.png" class="figure-img">
<figcaption>
An example where the current and optimal costs are the same.
</figcaption>
</figure>
</figure>
<p>The current version of this implementation is <a href="https://filestorage2.netlify.app/">here</a>, and it’s still a little quirky in terms of the first couple of times you drag the slider, but stabilizes soon after. I hope to fix this… eventually :)</p>
</section>
</section>
</section>
<section id="for-students" class="level2">
<h2 class="anchored" data-anchor-id="for-students">For Students</h2>
<p>Sal Khan makes a compelling case for the use of AI to help with the learning process <a href="https://www.ted.com/talks/sal_khan_how_ai_could_save_not_destroy_education?language=en">in a recent TED talk</a>. In a computer programming exercise available on Khan Academy, a student needs to modify an existing snippet of code to “make two clouds drift apart”. The student attempts this by writing “leftX–”, but notices that this only affects the left cloud, and not the right one. The student then pulls up Khanmigo to inquire why the attempt did not work out, and Khanmigo recognized enough of the surrounding context to make a meaningful suggestion.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/building-interactives/image005.png" class="img-fluid figure-img"></p>
<figcaption>A typical exercise on Khan Academy, with the exercise material and the student’s attempt on the left; and the rendering on the right. The goal is to modify the code so that the clouds drift apart.</figcaption>
</figure>
</div>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/building-interactives/image004.png" class="img-fluid figure-img"></p>
<figcaption>Khanmigo trying to analyze the issue.</figcaption>
</figure>
</div>
<p>While <a href="https://www.khanacademy.org/khan-labs">Khanmigo</a> is still under development a the time of this writing, this example already demonstrates the potential of a collaboration between a well-intentioned learner and a well-intentioned AI. Just as learning a language on a platform like Duolingo is an enhanced experience when we attempt talking with native speakers, so is programming language learning potentially enhanced by such transactions between the learner and someone who has the advantage of expertise.</p>
<p>As a sample counterpoint to this thread of thought, in a <a href="https://cacm.acm.org/blogs/blog-cacm/273577-ai-does-not-help-programmers/fulltext#comments">CACM blog</a>, Bertrand Meyer argues that chatGPT may not, in fact, be helpful for (expert) programmers:</p>
<blockquote class="blockquote">
<p>Here is my experience so far. As a programmer, I know where to go to solve a problem. But I am fallible; I would love to have an assistant who keeps me in check, alerting me to pitfalls and correcting me when I err. A effective pair-programmer. But that is not what I get. Instead, I have the equivalent of a cocky graduate student, smart and widely read, also polite and quick to apologize, but thoroughly, invariably, sloppy and unreliable. I have little use for such supposed help.</p>
</blockquote>
<p>Check out the blog to see where this is coming from: you can eavesdrop on Meyer’s conversation with chatGPT and decide for yourself :)</p>
</section>
<section id="whats-next" class="level2">
<h2 class="anchored" data-anchor-id="whats-next">What’s Next?</h2>
<p>For the interactives discussed here, there are several ways of extending what has been cobbled together. For instance, for the visualization of <span class="smallcaps">Subtraction</span>, a natural next step is to create an interactive process that allows the learner to visualize the game tree, at least for small versions of the game.</p>
<p>For the visualization of the problem of storing files on a tape, there are several possible enhancements:</p>
<ol type="a">
<li><p>Show the cost breakdown more explicitly in terms of the formula, with a color coding that relates the numeric file sizes shown in the formula with the colors of the boxes on the tape.</p></li>
<li><p>Add an option to generate the optimal ordering in the first approach.</p></li>
<li><p>Gamify the problem where two users take turns to position files on the tape, and one wants to minimize the expected cost, while the other wants to maximize it: in particular, we establish a target cost, and the first player wins if the final cost is smaller than the target, the second player wins if the final cost is higher than the target, and the game is a draw otherwise.</p></li>
<li><p>Generalize the visualization to the situation where we not only have files, but also associated frequencies of access.</p></li>
</ol>
<p>These were just a couple of examples to suggest that creating fun and customized experiences for your classes may now just be a little easier than before, and hopefully this encourages more of us to experiment with the ideas we have.</p>
<p>On the theme of learners using chatGPT: there are several demonstrations that LLMs do well on the kind of programming tasks that show up in introductory coursework; for instance <a href="https://arxiv.org/abs/2210.15157">here is a preprint</a> suggesting as much:</p>
<blockquote class="blockquote">
<p>We […] evaluate the performance of Copilot on a publicly available dataset of 166 programming problems. We find that it successfully solves around half of these problems on its very first attempt, and that it solves 60% of the remaining problems using only natural language changes to the problem description. We argue that this type of prompt engineering, which we believe will become a standard interaction between human and Copilot when it initially fails, is a potentially useful learning activity that promotes computational thinking skills, and is likely to change the nature of code writing skill development.</p>
</blockquote>
<p>Such illustrations simply reinforce my sense that class materials and exercises should be adapted so that LLMs can be leveraged by students to accelerate their learning processes, making the “cheat use case” implausible almost by defintion. I realize this is easier said than done, but it’s already interesting to see all the ideas that have come up to this effect.</p>
<p>Check out this <a href="https://twitter.com/ShriramKMurthi/status/1683301415005855744">very cool thread</a> on Porpoise, a tool meant to help learners articulate specs for a given task: the first part of the exercise is reverse engineer what the task in question based on some sample I/O that is given, and the second part is to write it up so that chatGPT can produce code to match the sample I/O + some hidden tests that extrapolate on the samples.</p>
<p>Apart from writing code, chatGPT/Copilot/Ghostwriter can read code too, and often provide <a href="https://www.zdnet.com/article/okay-so-chatgpt-just-debugged-my-code-for-real/">surprisingly relevant insights</a> on why a piece of code does not work as expected. One context in which I would like to leverage this is to look at failed submissions on competitive coding platforms. Perhaps with some background from the editorials, chatGPT and its ilk can provide meaningful explanations of why something does not work, and if this turns out to be reliable, then it potentially removes some of the frustration from the learning process without short-circuiting it in bad ways.</p>
<p>I am aware that the release of chatGPT and friends has unleashed a flurry of work in the teaching/learning space, so do let me know in the comments if you have pointers to fun projects and ideas!</p>


</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>The success of Visualgo is witnessed by its wide usage and several anecdotal reports of positive feedback.↩︎</p></li>
<li id="fn2"><p>At the time this writing, this comment is from five years ago, and to the best of our knowledge, not much has moved along on the state of the art in terms of tools for authors of interactive experiences.↩︎</p></li>
<li id="fn3"><p>The conversation found in the supplementary material differs slightly from what is shown below; we have consolidated some of the prompts in the interest of brevity.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>exposition</category>
  <guid>https://www.neeldhara.com/blog/building-interactives/</guid>
  <pubDate>Sat, 29 Jul 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Note Taking Resources</title>
  <link>https://www.neeldhara.com/blog/note-taking-resources/</link>
  <description><![CDATA[ 





<p>Here is a list of courses, books, essays, youtube playlists, and other miscellany about taking notes, with the act interpreted broadly to include things like systems for filing, organization, linking, and thinking. Please feel free to drop a line in the comments or send a PR my way if you have something to add!</p>
<p>Thanks to <a href="https://twitter.com/abhinav">Abhinav</a> for <a href="https://twitter.com/abhinav/status/1664359012467441664?s=20">the prompt</a> :)</p>
<p><br><br></p>
<div id="listing-resources-listing" class="quarto-listing quarto-listing-container-custom">
<div class="listing-actions-group">
   <div class="input-group input-group-sm quarto-listing-sort">
     <span class="input-group-text"><i class="bi bi-sort-down"></i></span>
     <select id="listing-resources-listing-sort" class="form-select" aria-label="Order By" onchange="window['quarto-listings']['listing-resources-listing'].sort(this.options[this.selectedIndex].value, { order: this.options[this.selectedIndex].getAttribute('data-direction')})">
       <option value="" disabled="" selected="" hidden="">Order By</option>
       <option value="index" data-direction="asc">Default</option>
         <option value="listing-title" data-direction="asc">
          Title
        </option>
         <option value="listing-type" data-direction="asc">
          type
        </option>
     </select>
  </div>
    <div class="input-group input-group-sm quarto-listing-filter">
      <span class="input-group-text"><i class="bi bi-search"></i></span>
      <input type="text" class="search form-control" placeholder="Filter">
    </div>
</div>
<table class="quarto-listing-table table">
    <thead>
        <tr><td class="listing-type" style="max-width: 42px !important; text-align: center;">Type</td>
        <td class="listing-type" style="max-width: 42px !important; text-align: center;">Link</td>
        <td>Resource</td>
    </tr></thead>
    <tbody class="list">
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> <span class="bi bi-book"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://leanpub.com/cognitiveproductivity/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>1. Cognitive Productivity: Using Knowledge to Become Profoundly Effective</strong><br>
                <p>Book by Luc P. Beaudoin. <br> Official book summary: You distinguish yourself from others not so much by what you've read, viewed or listened to, but by the lasting impact that information has had upon you. How can you use knowledge to become a more effective person? Cognitive Productivity answers this question with cognitive science and practical strategies.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> <span class="bi bi-book"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://leanpub.com/cognitive-productivity-macos"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>2. Cognitive Productivity with macOS: 7 Principles for Getting Smarter with Knowledge</strong><br>
                <p>Book by Luc P. Beaudoin. <br> Official book summary: In today's competitive knowledge economy, you always need to keep learning —and fast. But most information and apps get in the way. This book describes 7 principles for selecting, processing and mastering knowledge using potent Mac apps.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> 
                <strong> <span class="bi bi-map"></span>  
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://zettelkasten.de/posts/overview/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>3. The Introduction to the Zettelkasten Method</strong><br>
                <p>Zettelkasten is a rather specific note-taking system (disclaimer: it is not something that I use, but I do find the principles vaguely intriguing). It relies heavily on tagging, linking, going with the flow, not overthinking, and somehow simultaneously keeps things systematic from a retrieval perspective. This overview page has a bunch of pointers that that should serve as a roadmap for the Zettelkasten for anyone inclined to find out more.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> <span class="bi bi-card-text"></span>  
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://numinous.productions/ttft/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>4. How can we develop transformative tools for thought?</strong><br>
                <p>Essay by Andy Matuschak and Michael Nielsen <br> Arguably not about taking notes per se, but about philosophies associated with systems and — as the title suggests — tools for thought.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> <span class="bi bi-card-text"></span>  
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://notes.andymatuschak.org/z4SDCZQeRo4xFEQ8H4qrSqd68ucpgE6LU155C"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>5. Evergreen Notes</strong><br>
                <p>Thoughts from Andy Matuschak <br>The OG 'digital garden', if I am not mistaken!</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> <span class="bi bi-journal-bookmark"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://courses.nicolevanderhoeven.com/o4e"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>6. Obsidian for Everyone</strong><br>
                <p>Nicole van der Hoeven's course. <br> Nicole is a pro Obsidian user and a master expositor. This particular course is nice because it focuses on all the things you can achieve without the use of any plugins: just bare-bones Obsidian. You'd be surprised at how far you can go!</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/@nicolevdh/playlists"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>7. Youtube channel: Nicole van der Hoeven</strong><br>
                <p>Excellent content for pro and starter Obsidian users alike. Very accessible and engaging, and I believe most people will find something relevant and relatable here.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> <span class="bi bi-book"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://groktiddlywiki.com/read/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>8. Grok TiddlyWiki</strong><br>
                <p>Grok TiddlyWiki is written and maintained by Soren Bjornstad. <br> Outstanding introduction to TiddlyWiki. Even non-TW users are likely to get some fun ideas from skimming this. And if you are a TW user, then this is one of the best journeys from starter to pro! Also check out Soren's own digital garden.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/@linkingyourthinking"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>9. Youtube channel: Linking Your Thinking (LYT)</strong><br>
                <p>This is Nick Milo's Youtube channel. It is mostly principles around linking, but uses Obsidian as the tool of choice. Nick also organizes a LYT conference regularly that is hugely popular and not particularly restricted to Obsidian. He also has a cohort-based course around LYT principles, a great Obsidian starter playlist, and a course called Obsidian Flight School as well.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/@augustbradley"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>10. Youtube channel: August Bradley</strong><br>
                <p>This channel focuses on 'life design' as a broad concept, using Notion as the underlying tool of choice for organization. There is an extensive discussion of the 'PPV' system - Pillars, Pipelines, and Vaults. Lots of system thinking in here, and I think although all of it is done on Notion, several principles are tool-agnostic.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> <span class="bi bi-book"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.buildingasecondbrain.com/course"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>11. Building a Second Brain</strong><br>
                <p>This is a cohort-based course around the notion of building a second brain by Tiago Forte. The material is centered around the 'PARA' method - Projects, Areas, Resources, Archives: a fairly intuitive system that many have found useful. Tiago has one published and one upcoming [at the time of this writing] book on these methods. His blog and Youtube channel dive fairly deep into these concepts, and I think the cohorts are useful if you are building something out and are looking for ways to stay accountable on sticking a system, or want a community/platform to brainstorm ideas.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/c/mariepoulin"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>12. Youtube channel: Marie Poulin</strong><br>
                <p>Marie is an authority when it comes to adapting Notion in creative ways for both personal and business use. She has a very comprehensive course called Notion Mastery that covers a lot of ground in terms of both techniques and principles.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/@VisualPKM"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>13. Youtube channel: Zsolt's Visual Personal Knowledge Management</strong><br>
                <p>This is the Zsolt's channel, who is behind tools like Excalibrain and Excalidraw for Obsidian and beyond. The channel emphasizes visual aspects of note-taking, while some of it is focused on Excalidraw/Excalibrain, a lot of content is also about general principles, examples, and so on.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/@Thomasfrank"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>14. Youtube channel: Thomas Frank</strong><br>
                <p>This channel is another one that pushes Notion to its limits. While overall this might be more productivity/systems/management territory than note-taking, I have found some great discussions about organizational principles here.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> <span class="bi bi-stars"></span>  
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://johnnydecimal.com/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>15. Johnny Decimal</strong><br>
                <p>This is purely about organization, but for me how notes are stored are an important piece of the puzzle. If you like folders, you might enjoy this system.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> 
                <strong> <span class="bi bi-map"></span>  
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.reddit.com/r/PKMS/comments/nfef59/list_of_personal_knowledge_management_systems/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>16. A list of PKM tools</strong><br>
                <p>A reddit post collecting a bunch of PKM software options, ranging from mainstream to exotic and everything in between!</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> <span class="bi bi-journal-bookmark"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://thesweetsetup.com/obsidian/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>17. To Obsidian and Beyond</strong><br>
                <p>A course by Mike Schmitz. From the official description: A master-course for Obsidian users (new and old alike). Finally organize your notes and ideas to make creative output easy.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/c/RedGregory"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>18. Youtube channel: Red Gregory</strong><br>
                <p>A Notion-based channel: I have found some of the workflows here to be advanced and intriguing in equal measure. Many principles are tool-agnostic, although the focus here is mostly on Notion.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> <span class="bi bi-youtube"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://www.youtube.com/@DannyHatcher"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>19. Youtube channel: Danny Hatcher</strong><br>
                <p>A channel focused on PKM and organizational systems broadly. I have mostly viewed the Obsidian-related material here: several demonstrations and tutorials have been very helpful.</p>
            </td>
        </tr>
    
        <tr data-index="0" data-categories="null">     
            <td class="listing-type" style="max-width: 42px !important; text-align: center;">
                <strong> 
                <strong> 
                <strong> <span class="bi bi-journal-bookmark"></span>  
                <strong> 
                <strong> 
                <strong> 
                <strong> 
            </strong></strong></strong></strong></strong></strong></strong></td>
            <td class="listing-link" style="max-width: 42px !important; text-align: center;">
                
                    <a href="https://verbaltovisual.com/"><span class="bi bi-link-45deg"></span></a>
                
            </td>
            <td class="listing-title" style="max-width: 420px !important;">
                <strong>20. Verbal to Visual</strong><br>
                <p>Lots of resources on sketchnoting and visual approaches to note-taking.</p>
            </td>
        </tr>
    
</tbody>
</table>

<div class="listing-no-matching d-none">
No matching items
</div>
</div>




 ]]></description>
  <category>lists</category>
  <guid>https://www.neeldhara.com/blog/note-taking-resources/</guid>
  <pubDate>Thu, 01 Jun 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>On Career Choices</title>
  <link>https://www.neeldhara.com/blog/on-career-choices/</link>
  <description><![CDATA[ 





<div class="callout callout-style-simple callout-tip no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>A version of this article was featured in <em>A Lesson from IIT</em>, a column on the Indian Express. The link to the column is <a href="https://indianexpress.com/about/a-lesson-from-iit/">here</a>, and <a href="https://indianexpress.com/article/education/a-lesson-from-iit-how-do-you-figure-out-your-interest-if-engineering-is-right-choice-iit-gandhinagar-jee-main-jee-advanced-2023-8629639/">this</a> is the link to the present article. Many thanks to <a href="https://indianexpress.com/profile/author/ritika-chopra/">Ritika Chopra</a> for prompting me to write this, and for not giving up on me as I took my time :)</p>
<p>Thanks are also due to friends Manasa, Jyothi, and Sharmistha for going over early versions of this writeup and sharing their thoughts!</p>
</div>
</div>
</div>
<p>During school, my earliest exposure to the notion of being an engineer was an at-the-time popular audio clip called <em>The Knack</em>, in which a doctor is diagnosing a kid with a condition involving extreme intuition for all things mechanical and electrical. It is implied that having “the knack” is not compatible with a normal life, since the kid is now destined to… be an engineer. This causes his mother to experience much concern and grief. The episode inspired me to keep a polite but firm distance from all things engineering, conveniently including the entrance exams meant to unlock the gates of the IITs.</p>
<p>College admissions are rife with two types of scenarios that are less than ideal: students ending up in programs that are not their cup of tea, and students missing out on experiences that would have been right up their alley. These mismatches are cumulatively expensive: there is the price paid in misallocated resources, and then there’s the personal cost of training for programs that eventually turn out to be a poor fit, which is typically very substantial.</p>
<p>Some of this can be mitigated with an appreciation of what these programs entail, and what the campuses have to offer. The IITs are known predominantly for their undergraduate programs in the traditional engineering disciplines. However, several of them also host excellent programs in the sciences. Further, there are an increasing number of undergraduate programs that have interdisciplinary themes (such as the Btech program in <a href="https://iitj.ac.in/department/index.php?id=ug_program&amp;dept=civil">Civil and Infrastructure Engineering with specialization in Smart Infrastructure</a> at IIT Jodhpur) and a focus on emerging technologies and areas (for instance, the BTech program in <a href="https://ai.iith.ac.in/programs/btech.html">Artificial Intelligence</a> at IIT Hyderabad or the undergraduate program in <a href="https://twitter.com/iitdelhi/status/1574782831221698562">Design</a> at IIT Delhi).</p>
<p>Currently, awareness about these opportunities is mostly a heady mix of word of mouth, Quora answers, vibes from coffee-table conversations at coaching centers, and placement statistics on popular media. Impressions of what campus life entails is also largely a combination of imagination fueled by things seen on, say, Netflix and the like. However, if you are a prospective student or a parent of one, you would do well to go beyond these secondary sources of intelligence and get some first-hand experience.</p>
<p>Most IITs host open days every so often: these are special days when the campuses are open to anyone to walk in, and professors and students from the organization delight in sharing what they are up to with accessible demonstrations or lab tours. A recent example is the <a href="https://students.iitgn.ac.in/ignite">G20-Ignite Sci-Tech fair</a> which hosted hundreds of school students at the IIT Gandhinagar campus. Often, even one such experience can trigger an inner calling, helping you identify the thing you want to do for life – or at least for a substantial duration.&nbsp;</p>
<p>You could also go beyond the glimpses offered by open days. Watch out for opportunities to collaborate over small projects. For example, the <a href="https://ccl.iitgn.ac.in/">Center for Creative Learning at IIT Gandhinagar</a> welcomes high school students for short term projects over summer, and students who do well in courses on the <a href="https://nptel.ac.in/">NPTEL</a> platform have a shot at internships with the instructors of those courses. Many professors delight in talking to students: check out the various seasons of <a href="https://www.talktoascientistindia.com/home">Talk to a Scientist</a>, for example. You can also ask your school to reach out to professors at nearby institutions for an interactive session, or approach organizations like <a href="https://inyas.in/">INYAS</a> that focus deeply on outreach activities at the school level. Finally, several IITs also host bootcamps, hackathons, and so on: they are usually announced on their websites and social media channels, so keep an eye out for these!</p>
<p>Having said all this, a choice of career – or more immediately, a branch or stream – does not have to be prompted necessarily by an intense love at first sight. The routes leading to your final pursuit(s) can be potentially meandering, and not having an inner voice abundant in clarity should be no cause for alarm. Examples of this abound, and I’ll share a representative one. <a href="https://en.wikipedia.org/wiki/Ronald_Graham">Ronald Graham</a> is arguably best-known as an American mathematician who made fundamental contributions to combinatorics. Because his father worked in various jobs related to oil fields and shipbuilding, he moved schools often. He did not study in any school for more than eighteen months and often studied in grades higher than what would have been normal for his age.</p>
<p>At the age of 15, Graham won a Ford Foundation scholarship to the University of Chicago, where he spent three years learning gymnastics. Because of his outstanding performance in math on the scholarship examinations, he did not (have to) take any mathematics courses. After the duration of the scholarship, he moved to the University of California at Berkeley, where he majored in electrical engineering. During this time, a one-off number theory course with D H Lehmer “fired his imagination for the subject”. After four subsequent years in the Air Force, during which he also earned a B.S. in physics, he returned to UC Berkeley where he completed his Ph.D.&nbsp;in mathematics with D H Lehmer as his thesis advisor.&nbsp;</p>
<p>All this is to say that life can be — and typically is — highly non-linear. I would argue that as much as we like to imagine being in control, planning one’s future down to summer-vacation-wise bucket lists is perhaps somewhat excessive. Your first branch and your first job does not have to be your last: for more evidence, I recommend reading Tim Ferriss’ book, <a href="https://www.amazon.in/Tribe-Mentors-Short-Advice-World/dp/1328994961">Tribe of Mentors</a>. Now, you might be prone to making your choices after optimizing for a dozen variables or more, or you might prefer leaving your destiny to the gods of randomness. I believe somewhere in between, there is an approach more reasonable than either extreme: make an informed choice after investing a finite amount of your own time and energy into understanding what actually lies in store.</p>
<p>The IITs are now far from being the only ticket to the good life and a powerful alumni network: if these are your main motivators, you might consider exploring less painful pathways to the same outcomes. If not, allow yourself the space to let your instincts come to the fore, and follow them to make your choices. This will maximize the chances that you will end up in a meaningful journey that involves truly enjoying what the programs have to offer, instead of being in a situation where you have simply transitioned from one rat race into another.</p>



 ]]></description>
  <category>funda</category>
  <guid>https://www.neeldhara.com/blog/on-career-choices/</guid>
  <pubDate>Thu, 25 May 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Letting Go</title>
  <link>https://www.neeldhara.com/blog/poems/letting-go/</link>
  <description><![CDATA[ 





<p>ख्वाब हे वो माशूका<br> जो तुझे मिलने से रहा,<br> हकीकत हे वो हमसफर<br> जिसे तुने है ठुकरा दिया<br></p>
<p>सपनों का घर है नींदो मे<br> उन्हे वहीं तू छोड दे<br> जो हकीकत सम्झोता लगे<br> वहीं सुकून है जान ले<br></p>
<hr>
<p>A dream is an elusive enchantment;<br> while that that is to be treasured<br> is what has been for real<br> and is easily ignored.<br></p>
<p>But a mere figment of imagination,<br> a dream is captive and binding:<br> let it go to be free from<br> your quest never-ending.<br></p>
<hr>
<p><em>Inspired by Pallavi Mahajan’s <a href="https://www.youtube.com/watch?v=M6mmF8OM9SM">brilliant poetry</a>.</em></p>



 ]]></description>
  <category>poem</category>
  <guid>https://www.neeldhara.com/blog/poems/letting-go/</guid>
  <pubDate>Wed, 10 May 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Course Plan Generator</title>
  <link>https://www.neeldhara.com/blog/course-plan/</link>
  <description><![CDATA[ 
<script src="plan.js"></script>
<style>
    .checkbox-container {
        display: flex;
        justify-content: space-between;
        flex-wrap: wrap;
        width: 100%;
        margin-bottom: 1rem;
    }
    .custom-button {
        background-color: darkseagreen;
        border: none;
        color: white;
        text-align: center;
        text-decoration: none;
        display: inline-block;
        font-size: 1rem;
        padding: 0.5rem 1rem;
        border-radius: 0.25rem;
        cursor: pointer;
        transition: background-color 0.3s;
    }
    .custom-button:hover {
        background-color: seagreen;
    }
</style>





<p>If you are</p>
<ol type="a">
<li>teaching a course at IIT Gandhinagar next term (Aug-Dec 2023),</li>
<li>working on your course plan, and</li>
<li>need a list of dates on which you have classes,</li>
</ol>
<p>then you can use the generator below to get a list, by checking your teaching days.</p>
<p>Dates during Exam I (Sep 02 – 06, 2023), Exam II (Oct 11 – 15, 2023), and the mid-sem recess (Oct 21 - 29, 2023) are excluded. Holidays are excluded too, but <em>restricted holidays are not</em>. If you need to view the holidays, you can indicate as much via the checkbox below.</p>
<p>For those outside IITGN: a standalone version is <a href="https://classplan.neeldhara.repl.co/">here</a> and the source is <a href="https://github.com/neeldhara/ClassPlan/tree/main">here</a>, in case you’d like to adapt this to your own context.</p>
<div>
<form>
<input type="checkbox" id="monday" name="day">&nbsp;Monday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="tuesday" name="day">&nbsp;Tuesday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="wednesday" name="day">&nbsp;Wednesday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="thursday" name="day">&nbsp;Thursday &nbsp;&nbsp;&nbsp; <input type="checkbox" id="friday" name="day">&nbsp;Friday
</form>
</div>
<br> <label><input type="checkbox" id="includeHolidays" name="includeHolidays"> Include Holidays</label> <br> <label><input type="checkbox" id="indicateRestrictedHolidays"> Indicate Restricted Holidays</label> <br> <br> <button class="custom-button" onclick="generateDates()"> Generate Dates for Course Plan </button> <br><br>
<div class="sourceCode" style="background: #f1f3f5;">
<pre class="sourceCode plaintext code-with-copy"><code class="sourceCode plaintext" id="datesList">
</code>
</pre>
</div>



 ]]></description>
  <category>workflows</category>
  <guid>https://www.neeldhara.com/blog/course-plan/</guid>
  <pubDate>Mon, 24 Apr 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>13 Sheep</title>
  <link>https://www.neeldhara.com/blog/13sheep/</link>
  <description><![CDATA[ 





<p><a href="https://www.moritzdressler.de/en/13_Sheep">13 Sheep</a> happens to be a cute roll-and-write game designed by Moritz Dressler that involves protecting a bunch of sheep on a grid by placing small fences that have pre-defined shapes.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/13sheep.png" class="img-fluid figure-img" width="420"></p>
<figcaption>The Roll and Write Game</figcaption>
</figure>
</div>
<p>The initial position of a certain number — typically 13, as the name suggests — of sheep over a 7x7 grid is given. Some grid edges are not available because there happen to be bushes: so you cannot fence them. The bushes do not protect the sheep either, the wolf can slide under them.</p>
<p>Your goal is to enclose as many sheep as possible: the ones that are not fully protected by fences may, alas, be at considerable risk when the inevitable wolf attack happens.</p>
<p>There are three main constrianing factors in this game:</p>
<ul>
<li>The shape of the fences that you can draw are determined by the roll of a die;</li>
<li>You cannot overwrite lines that are already drawn, you cannot also draw over bushes;</li>
<li>You have ~11 chances to place your randomly gifted fence shapes.</li>
</ul>
<p>You can find out more about the game <a href="https://www.moritzdressler.de/en/13_Sheep">here</a>, where you can generate board layouts to print and play as well.</p>
<p>I found this game a lot of fun to play, and I thought it would be lovely to be able to play it on a computer, where the user can decide how many rounds, sheep, and bushes they want to play with. Given also that chatGPT has been apparently <a href="https://twitter.com/ammaar/status/1637830530216390658?s=20">remarkably adept at coding games</a>, I figured I’d give it a shot<sup>1</sup>.</p>
<p>I describe my conversation with chatGPT below, but if you just want to cut to the case and check the game out, you can find the playable version <a href="https://13sheep.netlify.app/">here</a> and the source <a href="https://github.com/neeldhara/13sheep/">here</a>.</p>
<p>Here’s what we finally built:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/finalui.png" class="img-fluid figure-img" style="width:100.0%"></p>
<figcaption>The 13 Sheep UI</figcaption>
</figure>
</div>
<p>And once you’ve finished playing you can share your accomplishment like so:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/download.png" class="img-fluid figure-img" width="420"></p>
<figcaption>One of my completed games… where we protect five sheep, can you figure out how many rounds?</figcaption>
</figure>
</div>
<hr>
<p>So, back to chatGPT. My first prompt was just a polite inquiry about willingness to participate in this exercise:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>We want to code a game called 13 Sheep using HTML, CSS, and Javascript. Ready?</p>
</div>
</div>
</div>
<p>And well, it immediately made <a href="https://13-sheep-v3-GPT4-v30.neeldhara.repl.co">this</a>, based on the prompt above: a game where you get to count to 13 sheep. Huh. Promising.</p>
<p>In my next few prompts, I steered it away from the default game. The first few steps just involved setting up the UI:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Great start! Please make the main canvas a square and draw a 7 x 7 grid in it. I want all the corners of the cells to look like small + signs. Do not draw any grid borders yet.</p>
</div>
</div>
</div>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Nice, how can I make the grid background mediumseagreen?</p>
</div>
</div>
</div>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>On load, I want 13 grid cells to be identified at random, and the image sheep.png to be placed at their centers, appropriately scaled to fit.</p>
</div>
</div>
</div>
<p>At this point I already had a nice-looking grid with 13 sheep on it (thanks to Flaticon for the cute sheep icon). The plus signs drawn on the boundary were oddly cropped out, so we fixed that next:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Ok this looks great. Can you update the drawcross function so that crosses are also drawn on the grid boundary? And make the canvas a little bigger if needed so the entire cross is visible?</p>
</div>
</div>
</div>
<p>This didn’t immediately work but some nudging fixed it:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>The crosses at the bottom are getting cut off and now the sheep are off center. Please fix?</p>
</div>
</div>
</div>
<p>That worked — phew! Now we draw the bushes:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Very nice. Can you randomly select 7 cells now and for each such cell make one of the cell boundaries colored indianred?</p>
</div>
</div>
</div>
<p>Next we get the dice roll UI up:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Excellent. Now please add six divs below the canvas, centered, evenly spaced, and with a light grey circular background, with the text 1, 2, 3, 4, 5, and 6 written inside them. Note that the first div should have the text 1, the second should have 2, and so on. Make sure the divs have at least 10px spacing between them.</p>
<p>Below these divs, please add a large button in the shape of a rounded rectangle, with the text “Roll Dice” written on it. The background color for this button should be indianred with a transparency of 0.42.</p>
</div>
</div>
</div>
<p>This actually worked out of the box, the next step was to make the roll dice functional:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Super nice!</p>
<p>Now can you make it so that when the user clicks on the button labeled “Roll Dice”, we generate a number between 1 and 6 at random, and highlight the corresponding circular div by changing its background to Lavendar, while also resetting any previous highlight?</p>
</div>
</div>
</div>
<p>So far, so good. Now all that was left was to get the fences drawn depending on what dice was rolled out.</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-1-contents" aria-controls="callout-1" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Fence Shapes Based on Dice Rolls
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-1" class="callout-1-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/1.png" class="img-fluid figure-img"></p>
<figcaption>Dice Roll 1</figcaption>
</figure>
</div>
<hr>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/2.png" class="img-fluid figure-img"></p>
<figcaption>Dice Roll 2</figcaption>
</figure>
</div>
<hr>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/3.png" class="img-fluid figure-img"></p>
<figcaption>Dice Roll 3</figcaption>
</figure>
</div>
<hr>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/4.png" class="img-fluid figure-img"></p>
<figcaption>Dice Roll 4</figcaption>
</figure>
</div>
<hr>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/5.png" class="img-fluid figure-img"></p>
<figcaption>Dice Roll 5</figcaption>
</figure>
</div>
<hr>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/13sheep/6.png" class="img-fluid figure-img"></p>
<figcaption>Dice Roll 6</figcaption>
</figure>
</div>
</div>
</div>
</div>
<p>This was perhaps the trickiest bit. My first attempt was this prompt here:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Great! Now can you update it so that:</p>
<p>if the outcome of the dice roll is a 1, the cursor should change to a shape that looks like a U, and nothing outside the grid should be clickable. If the user clicks on a grid cell, then the left, bottom, and right borders of the cell should change color and become a thick line colored in olivedrab. Once the user has clicked on a grid cell the cursor should change back to normal.</p>
<p>if the outcome of the dice roll is a 2, the cursor should change to a shape that looks like a long line, and nothing outside the grid should be clickable, and none of the cells in the last column should be clickable either. If the user clicks on a grid cell, then the bottom border of the cell should change color and become a thick line colored in olivedrab, and the the bottom border of the horizontally adjacent cell should change color and become a thick line colored in olivedrab. Once the user has clicked on a grid cell the cursor should change back to normal.</p>
</div>
</div>
</div>
<p>My hope was that the change of cursor would be a good way for the player to register that they need to move on the grid now. At this point, I was not thinking about the different orientations of the fences, because I was not sure about how to incorporate that into the UI (my first thought was to have the fences rotate on subsequent clicks until the player clicks on a confirm button, but that seemed too messy). I also did not give all six scenarios in one go since — from recent experience — the interface dies out on longer requests. You can prod it to continue from where it left off, but it’s typically messy.</p>
<p>In any case, we could not get the change of cursor to work. At this point, note that the code is also not tracking what borders are colored, so even as we got things to mildly work, we were often overwriting fences and bushes. So anyway, at some point I gave up and it was back to square one, but smaller steps. First, instead of a change of cursor, I just requested a canvas background color change to subtly communicate a change of game state:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Once the dice roll button is clicked, can you change the background of the canvas to dodgerblue with transparency 0.42, and disable the roll dice button until the user clicks on a grid cell?</p>
</div>
</div>
</div>
<p>Then we added a round tracker:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Add the following text just below the “Roll Dice” button: “Roll a dice now, 11 rounds left”. Every time the user clicks on “Roll Dice”, change the text to “Place a fence now.” Once the user clicks on a grid cell, change the text back to “Roll a dice now, 11 rounds left”, but decrease the number of rounds by one each time. Can you do this?</p>
</div>
</div>
</div>
<p>This took some back and forth to get working, since it was getting some details mixed up, but it was finally alright. I had to prompt more to take care of some edge cases and minor details, for instance:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Anyway, can you make it so that when there are 0 rounds left, the text simply says “Game Over”?</p>
<p>Also when the roll dice button is not active, can it have a grey background? Only when it is not active.</p>
</div>
</div>
</div>
<p>Now we are back to actually trying to get the fences to be drawn. With some nervousness, I go:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Very nice. Now, if the dice roll is a 1 and the user clicks on a grid cell, can you do the following?</p>
<ol type="1">
<li>let us say that a cell is valid if the top, left, and bottom borders of the grid have no visible borders.</li>
<li>if the cell is valid, then make its top, left, and bottom borders colored olivedrab.</li>
</ol>
</div>
</div>
</div>
<p>At this point the code generated starts tracking what borders are visible. I did have to prompt it explicitly to update the earlier function that generated the bushes to feed into the visibility states. However, this went off pretty smoothly overall. For quite some time the fences drawn when the user clicked a grid cell were not the ones I wanted, but after a few nudges it got it about right.</p>
<p>Now it occured to me that I could actually show the orientations after the dice is rolled and the user can select one of them, and we can draw the appropriate fence after this selection is made.</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Great. This works. Now below the instruction-text element, please add another div with ID “orientation-select” that begins with the text: “Pick an orientation”. Below this, add four circular divs with a light grey backgorund with the content: “0”, “90”, “180”, “270”. This div should only be visible when the gamestate is “chooseFenceOrientation” or “placeFence”.</p>
<p>Once a dice is rolled, the game state should change to chooseFenceOrientation and the user should be allowed to click any of these four divs. Once the user clicks one of the four divs, highlight it with the color burntorange and change the gamestate to placeFence. Store the choice of which div the user clicked on in a variable called fenceorientation and change the game state to placeFence.</p>
<p>Once the user clicks on a grid cell, clear the burntorange highlight and hide the “orientation-select” div, as it should not be visible any more.</p>
</div>
</div>
</div>
<p>Of course in the UI at the moment we just have these four numbers so it does not make a lot of sense to the player, so I whipped some images to show the user what fences would be drawn depending on what grid cell was clicked.</p>
<p>Now we come back to the fence drawing thing to account for the orientations as well:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>In the handleGridClick() function, we want to implement the following functionality.</p>
<p>If the outcome is 1 and the orientation is 0, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if the top, left, and bottom borders of the grid have no visible borders.</li>
<li>if the cell is valid, then make its top, left, and bottom borders colored olivedrab.</li>
</ol>
<p>If the outcome is 1 and the orientation is 90, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if the right, left, and bottom borders of the grid have no visible borders.</li>
<li>if the cell is valid, then make its right, left, and bottom borders colored olivedrab.</li>
</ol>
<p>If the outcome is 1 and the orientation is 180, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if the right, top, and bottom borders of the grid have no visible borders.</li>
<li>if the cell is valid, then make its right, top, and bottom borders colored olivedrab.</li>
</ol>
<p>If the outcome is 1 and the orientation is 270, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if the right, left, and top borders of the grid have no visible borders.</li>
<li>if the cell is valid, then make its right, left, and top borders colored olivedrab.</li>
</ol>
<p>Please remember to use the drawBorder function from before as you work out these cases. Also remember to update the grid visibility values, for the two relevant cells per border drawn. Thanks.</p>
</div>
</div>
</div>
<p>Getting this going for all the 20 different cases was really the bulk of the back and forth. While it got the overall functionality right, there would be small and frequent bugs in the details. For instance, if a cell’s top border is being fenced, then the cell above it should have its bottom border’s visibility updated: it knows this, but frequently got combinations wrong, and so I did have to read the code generated carefully. I either fixed it manually when the bugs were minor, or went back to requesting corrections by explaining the issue when it was off by a whole lot.</p>
<p>You can see that some of the prompts are longer than the corresponding code :D</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Looks great! Lets continue with our updates. Please remember to account for all the cases when updating the grid visibility values.</p>
<p>If the outcome is 4 and the orientation is 0, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if its bottom and left borders are not visible and the horizontally adjacent cell (i.e, the cell to the right of it) also does not have a bottom border. if a cell is on the right-most column, it is automatically not valid.</li>
<li>if the cell is valid, then make its bottom and left borders colored olivedrab. Also make the bottom border of the horizontally adjacent cell colored olivedrab. Update the grid visibility values as appropriate.</li>
</ol>
<p>If the outcome is 4 and the orientation is 180, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if its top border is not visible and the horizontally adjacent cell (i.e, the cell to the right of it) also does not have a top border and the horizontally adjacent cell (i.e, the cell to the right of it) also does not have a right border. if a cell is on the right-most column, it is automatically not valid.</li>
<li>if the cell is valid, then make its top border colored olivedrab. Also make the top border of the horizontally adjacent cell colored olivedrab. Also make the right border of the horizontally adjacent cell colored olivedrab. Update the grid visibility values as appropriate.</li>
</ol>
<p>If the outcome is 4 and the orientation is 90, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if its top and left borders are not visible and the vertically adjacent cell (i.e, the cell below it) also does not have a left border. if a cell is on the right-most column, it is automatically not valid.</li>
<li>if the cell is valid, then make its top and left borders colored olivedrab. Also make the left border of the vertically adjacent cell colored olivedrab. Update the grid visibility values as appropriate.</li>
</ol>
<p>If the outcome is 4 and the orientation is 270, then do the following when the user clicks on a grid cell.</p>
<ol type="1">
<li>let us say that a cell is valid if its bottom and right borders are not visible and the vertically adjacent cell (i.e, the cell to the top of it) also does not have a right border. if a cell is on the right-most column, it is automatically not valid.</li>
<li>if the cell is valid, then make its bottom and right borders colored olivedrab. Also make the right border of the vertically adjacent cell colored olivedrab. Update the grid visibility values as appropriate.</li>
</ol>
</div>
</div>
</div>
<p>Maybe it’ll soon be possible to just upload a picture of the game instruction booklet and let chatGPT do the rest of the heavy lifting. Until then, this was the best I could think of: maybe there’s a shorter way? I did try using generic shape descriptions, but no luck on those.</p>
<p>Now the basic game was done, and there were three main features I’d have really liked to add at this point:</p>
<ul>
<li>Allow the user undo the previous fence placement.</li>
<li>Count the number of protected sheep at the end.</li>
<li>Make a version of this game where instead of rolling a dice, we let the user pick the fences they want: this can be useful for a multiplayer setting where we want the random choices to be the same for all players: so one player can roll the dice and the others can follow along.</li>
</ul>
<p>I did try some of this: it’s impressive that chatGPT gets the main ideas right the first two requirements (the use of an action stack for implementing undo, and recognizing that we need some kind of flood fill algorithm for the score). However, all the implementations ended up being somewhat buggy and after some wrestling I decided to push these extras to the roadmap. The deterministic version of the game should not be hard to make, even manually at this point, so I hope to come back to it soon.</p>
<p>After this I mainly asked for chatGPT to let the user customize the parameters of the game:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Can you make it so that when the page loads we ask the user (via an alert) for a number between 7 and 32 and set the number of rounds to the number specified by the user?</p>
</div>
</div>
</div>
<p>It got this immediately right, and I wanted some styling:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Can you add some css styling so that this prompt looks nice?</p>
</div>
</div>
</div>
<p>and it’s response was:</p>
<div class="callout callout-style-simple callout-tip no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Unfortunately, you cannot directly style the default JavaScript prompt function. Instead, you can create a custom modal using HTML, CSS, and JavaScript to achieve a more visually appealing and flexible solution.</p>
<p>Here’s an example of how you can create a custom modal to ask for the number of rounds:</p>
<p>…</p>
</div>
</div>
</div>
<p>Good to know! The modals worked out of the box, and it was easy to extend them so they asked for the number of sheep and bushes as well. The last thing I wanted to add was a sharing feature:</p>
<div class="callout callout-style-simple callout-note no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>Can you add code so that the user can share a screenshot of just the canvas once the game is over? So once the game is over, I want to show a link called “Share My Game!” The screenshot and options to share on social media should show up in a modal when the user clicks this link.</p>
</div>
</div>
</div>
<p>Now this it did remarkably well, except that when it tried to pass the entire image as a URL parameter, that didn’t work out. When I conveyed this, the response was:</p>
<div class="callout callout-style-simple callout-tip no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<p>I apologize for the inconvenience. The reason for this issue is that sharing an image directly using a URL is not possible due to security reasons. To share your game image on social media platforms like Facebook and Twitter, you’ll need to use their respective APIs.</p>
<p>Here’s a modified approach for sharing the image on Facebook and Twitter. You’ll need to create Facebook and Twitter developer accounts and register your app to get the API keys.</p>
</div>
</div>
</div>
<p>Whoa… so ok, I don’t have developer accounts and I was not going to follow through, but this was definitely interesting!</p>
<p>I did interleave responses from chatGPT with help from Ghostwriter, which is the intelligence built into repl.it out of the box. Ghostwriter’s responses were usually not as sophisticated on comparable prompts, but on a couple of occassions chatGPT was completely lost on why something wasn’t working, but Ghostwriter would figure it out when asked pointed questions about an error. There seems to be some potential that they will be a good team — possibly also alongside Copilot, which I did not use at all here.</p>
<div class="callout callout-style-default callout-caution callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
The Final Product
</div>
</div>
<div class="callout-body-container callout-body">
<p>Anyway, long story short, I cleaned up a little further on my own, and finally: the game is <a href="https://13sheep.netlify.app">here</a>, the source is <a href="https://github.com/neeldhara/13sheep/">here</a>.</p>
</div>
</div>
<p>My experience with chatGPT and Ghostwriter as pair programmers was — I daresay — rewarding overall. When I first thought of doing this, perhaps partially <a href="https://twitter.com/ShriramKMurthi/status/1637058628187312134">intoxicated by all the hype</a>, I figured I could get this done in a couple of hours at the most: I estimated twenty minutes for functional code, and about a 100 minutes for making up my mind about colors and fonts. This was a vast underestimate: I think I spent close to a good twelve hours (including a couple of early throw-away prototypes, and all the failed attempts on the flood filling) altogether<sup>2</sup>… at some point it did get a little addictive, and perhaps there was a sunk cost argument for not letting go halfway through.</p>
<p>As someone who does not know javascript, I found this to be a part empowering, part learning, and mostly amusing experience. It felt like picking up a natural language by directly talking to mostly fluent speakers who made random and small mistakes. My overall sentiments were very similar to the process described <a href="https://twitter.com/ammaar/status/1637592014446551040">in this thread</a>, where <a href="https://twitter.com/ammaar">Ammaar Reshi</a> uses GPT-4, Replit, MidJourney, and Claude to create a 3D space runner from scratch with ZERO [sic] knowledge of Javascript or 3D game programming: you should check this out if you are interested in a much more sophisticated demonstration for deploying AI tools to make games!</p>
<p>In its current form I think this also has interesting implications for how programming is taught: I hesitate to elaborate any further on this given how likely it is that any commentary will be obsolete by tomorrow. But in the very near term, I can imagine that reading, analyzing, and even learning alongside chatGPT could make for interesting experiences in the classroom.</p>




<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>Incidentally, I couldn’t find a playable version like this one online. If you know of one please let me know and I’ll be sure to add a pointer!↩︎</p></li>
<li id="fn2"><p>At least I’m <a href="https://twitter.com/ammaar/status/1637830530216390658?s=20">not the only one</a> spending hours in the plural.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>games</category>
  <category>exposition</category>
  <guid>https://www.neeldhara.com/blog/13sheep/</guid>
  <pubDate>Sat, 25 Mar 2023 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Letters with Pandoc</title>
  <link>https://www.neeldhara.com/blog/pandoc-letters/</link>
  <description><![CDATA[ 





<p>Letter-writing season is around the corner. I recently adapted <a href="https://github.com/yangjiandong/myPandoc/tree/faf94dc26487005b03baa7a2d807b20b2a7f233f/demo/letter">this pandoc workflow</a> for generating PDF letters by only editing a markdown file. I only made the following minor changes to the original:</p>
<aside>
For this to work you will need <a href="https://pandoc.org">pandoc</a> and a TeX distribution installed. For a full-fledged TeX distribution check out something like <a href="https://www.tug.org/mactex/">MacTeX</a> and for a minimal variation, see <a href="https://yihui.org/tinytex/">TinyTeX</a>.
</aside>
<ol type="1">
<li><p>Included the <code>fontawesome5</code> package so I could add icons alongside the phone number, email, and website in the letterhead.</p></li>
<li><p>Changed <code>ThisULCornerWallPaper</code> to <code>CenterWallPaper</code> and added <code>wpYoffset</code> and <code>wpXoffset</code> so I could get a left margin on the logo (I suppose this <em>could</em> also be done by offsetting the logo in the <code>letterhead.pdf</code> file).</p></li>
</ol>
<p>Here’s what the output looks like with some random sample content:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/pandoc-letters/output.png" class="img-fluid figure-img" style="width:80.0%"></p>
<figcaption>Sample letter produced with the pandoc workflow</figcaption>
</figure>
</div>
<p>The markdown is very simple to edit — most of the information is up in the YAML header, and it looks like this:</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">author</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Fyodor Michailovitch Dostoevsky</span></span>
<span id="cb1-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">city</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Moscow</span></span>
<span id="cb1-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">from</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb1-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> By the Vladimirkirche</span></span>
<span id="cb1-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> care of Pryanischnikof, Grafengasse.</span></span>
<span id="cb1-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">affiliation1</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Add an affiliation</span></span>
<span id="cb1-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">affiliation2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Potential Additional Information</span></span>
<span id="cb1-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">contact</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> </span></span>
<span id="cb1-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> \faPhone \ +91 79 1234 1729</span></span>
<span id="cb1-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> \faGlobe \ https://www.google.com</span></span>
<span id="cb1-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> \faEnvelope \ nobody@nowhere.com</span></span>
<span id="cb1-12"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">to</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb1-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Michael</span></span>
<span id="cb1-14"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> Someplace</span></span>
<span id="cb1-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> with an address</span></span>
<span id="cb1-16"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">subject</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> An Update</span></span>
<span id="cb1-17"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">salutation</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> My dearest</span></span>
<span id="cb1-18"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">toname</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> brother</span></span>
<span id="cb1-19"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">customdate</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;"> 1838-8-9</span></span></code></pre></div>
<p>Write the body of the letter in markdown as usual, and generate the PDF by running:</p>
<pre><code>pandoc letter.md -o output.pdf --template=template.tex --pdf-engine=xelatex</code></pre>
<p>or have a makefile that looks like this:</p>
<pre><code>TEX = pandoc
FLAGS = --pdf-engine=xelatex

src1 = template.tex letter.txt
op1 = output

all : $(op1).pdf

$(op1).pdf : $(src1)
    $(TEX) $(filter-out $&lt;,$^ ) -o $@ --template=$&lt; $(FLAGS)</code></pre>
<p>For your first use, you would want to update the images for the letterhead and the signature, and optionally customize the fonts to your liking. <a href="https://github.com/neeldhara/pandoc-letters">Fork this repo</a> to make your own!</p>



 ]]></description>
  <category>pandoc</category>
  <category>workflows</category>
  <category>latex</category>
  <guid>https://www.neeldhara.com/blog/pandoc-letters/</guid>
  <pubDate>Sat, 26 Nov 2022 18:30:00 GMT</pubDate>
</item>
<item>
  <title>The Only Fair Ranking of IITs</title>
  <link>https://www.neeldhara.com/blog/iit-rankings/</link>
  <description><![CDATA[ 





<p>
Don’t like the ranking? <a href=".">Try again</a>.
</p>
<div class="callout callout-style-default callout-tip callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Methodology: adapted from <a href="https://sarielhp.org/cgi-bin/cs_ranking">here</a>.
</div>
</div>
<div class="callout-body-container callout-body">
<p>The program takes all the available knowledge in the universe and extrapolates a score for each IIT using state of the art algorithmic techniques (i.e., deep guessing). To resolve ties, the program also computes a secondary score which is a random number. The program next computes a weighted average of the two scores - the weight assigned to the first score is based on its scientific value and merit, and is thus zero, and the remaining weight is assigned to the secondary score (i.e., 1). The program then sort and output the departments in decreasing ordering of their weighted scores.</p>
</div>
</div>
<p><a href="https://sarielhp.org/cgi-bin/cs_ranking">Inspiration</a>  Check this page for a ranking of computer science departments.</p>
<hr>
<div class="cell">
<div class="sourceCode cell-code hidden" id="cb1" data-startfrom="26" data-source-offset="-1" style="background: #f1f3f5;"><pre class="sourceCode js code-with-copy"><code class="sourceCode javascript" style="counter-reset: source-line 25;"><span id="cb1-26"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> { shuffle } <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"./shuffle.js"</span></span>
<span id="cb1-27"></span>
<span id="cb1-28">arr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Kharagpur"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-29"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Bombay"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-30"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Madras"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-31"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Kanpur"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-32"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Delhi"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-33"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Guwahati"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-34"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Roorkee"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-35"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Ropar"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-36"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Bhubaneswar"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-37"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Gandhinagar"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-38"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Hyderabad"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-39"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Jodhpur"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-40"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Patna"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-41"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Indore"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-42"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Mandi"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-43"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT (BHU) Varanasi"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-44"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Palakkad"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-45"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Tirupati"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-46"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT (ISM) Dhanbad"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-47"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Bhilai"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-48"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Dharwad"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-49"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Jammu"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb1-50"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"IIT Goa"</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-51">x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">shuffle</span>(arr)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-52">y <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">document</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">getElementById</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"quarto-document-content"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-53"></span>
<span id="cb1-54">y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">innerHTML</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 2. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 3. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 4. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 5. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 6. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 7. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 8. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 9. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 10. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 11. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 12. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 13. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 14. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">13</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 15. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">14</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 16. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 17. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 18. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 19. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 20. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">19</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 21. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 22. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span>] <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;br&gt; 23. "</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> x[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-1-1" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-1-2" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-1-3" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-1-4" data-nodetype="declaration">

</div>
</div>
</div>
<div class="cell-output cell-output-display">
<div>
<div id="ojs-cell-1-5" data-nodetype="expression">

</div>
</div>
</div>
</div>



 ]]></description>
  <category>funda</category>
  <guid>https://www.neeldhara.com/blog/iit-rankings/</guid>
  <pubDate>Wed, 23 Nov 2022 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Exportober 2022</title>
  <link>https://www.neeldhara.com/blog/exportober/2022-tracker/</link>
  <description><![CDATA[ 





<section id="the-leaderboard" class="level2">
<h2 class="anchored" data-anchor-id="the-leaderboard">The Leaderboard</h2>
<iframe class="airtable-embed" src="https://airtable.com/embed/shrjgp87jlNqDMCy4?backgroundColor=yellow&amp;viewControls=on" frameborder="0" onmousewheel="" width="100%" height="533" style="background: transparent; border: 1px solid #ccc;">
</iframe>
</section>
<section id="the-tweets" class="level2">
<h2 class="anchored" data-anchor-id="the-tweets">The Tweets</h2>
<iframe class="airtable-embed" src="https://airtable.com/embed/shrwXyP8mGB3KH86i?backgroundColor=yellow&amp;viewControls=on" frameborder="0" onmousewheel="" width="100%" height="533" style="background: transparent; border: 1px solid #ccc;">
</iframe>
</section>
<section id="what-was-this-about-again" class="level2">
<h2 class="anchored" data-anchor-id="what-was-this-about-again">What was this about again?</h2>
<p>You can find the original announcement <a href="../2022/">here</a> and more specifics clarifying the format (or the lack of it) <a href="../about/">here</a>. Here’s the short version:</p>
<ul>
<li>Put up a piece of content everyday between 1st October and 30th October, with the possibility of skipping one day per week;</li>
<li>Post a link to your content on Twitter with #exportober</li>
<li>That’s it, actually. 🤷‍♀️</li>
</ul>
<p>Psst. It’s quite fine to sign up even if you’re reading this after the 1st of October. The automated tracking exercise here will stop after the 15th of November, so you can be a part of this by just contributing in this window. It certainly does’t <em>have</em> to be daily and it doesn’t <em>have</em> to be 30 things, although I found those to be useful default targets to work with for myself.</p>
<!-- ## Sign up! -->
<!-- While I'm not going to write a Twitter bot that will send you daily reminders over DM, I do hope to create a separate page for each registered participant at the end of the challenge that shows off just their entries in one place, so it's helpful to know who you are 😀 -->


</section>

 ]]></description>
  <category>exportober</category>
  <guid>https://www.neeldhara.com/blog/exportober/2022-tracker/</guid>
  <pubDate>Thu, 06 Oct 2022 18:30:00 GMT</pubDate>
</item>
<item>
  <title>SKJ</title>
  <link>https://www.neeldhara.com/blog/skj/</link>
  <description><![CDATA[ 





<p>This is the text of a short speech I gave at the farewell event for <a href="https://sudhirjain.info/">Prof.&nbsp;Sudhir Jain</a> as he left IITGN for BHU.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/skj/skj.jpg" class="img-fluid figure-img" style="width:87.0%"></p>
<figcaption>Prof.&nbsp;Jain at the farewell event held on the 3rd January, 2022.</figcaption>
</figure>
</div>
<p>You can find out more about Prof.&nbsp;Jain’s own take on the cultural foundations of IIT Gandhinagar <a href="https://iitgn.ac.in/about/cultural_foundations">here</a>, where he is in conversation with <a href="https://www.linkedin.com/in/achal-mehra-13037931/">Achal Mehra</a>.</p>
<hr>
<blockquote class="blockquote">
<p>Canadian astronaut Chris Hadfield has said that leadership is not about glorious crowning acts. It’s about keeping your team focused on a goal and motivated to do their best to achieve it, especially when the stakes are high and the consequences really matter. It is about laying the groundwork for others’ success, and then standing back and letting them shine. If that sounds familiar, I think it’s because we have lived this experience at IIT Gandhinagar, thanks to Prof.&nbsp;Jain.</p>
<p>Our guiding principles have been often unconventional — whether it’s about having students first, or choosing to trade short-term gains for the long-term vision. They have sometimes led to decisions that would seem quite inexplicable to anyone who did not have the context. Some of you might remember how early we started the undergraduate program in Computer Science, for example. Ok, so for the record, we started it quite late, at least according to conventional wisdom.</p>
<p>Crucially, these core values have always been articulated in collaboration, with inputs from all stakeholders, which is what enables our shared conviction in them once they have been established.</p>
<p>Prof.&nbsp;Jain’s vision for IIT Gandhinagar is as precise as it’s bold – he knew exactly what needed to be done for this place to emerge as a model institution. He had recently shared with us his roadmap for IITGN from a dozen years ago. This roadmap committed not to vague ideas but concrete goals, complete with numbers for metrics that are fraught with uncertainty. It’s absolutely stunning how everything panned out almost exactly according to plan!</p>
<p>Our narrative has many collaborators, including our students, faculty, and staff. And while some of us are relatively inexperienced, Prof.&nbsp;Jain’s trust in everyone has been hugely empowering. It manifests in many concrete ways – starting from wanting for students to be recognized as adults, to turning young colleagues into decision-makers… and this is why all of us have a deep sense of ownership for IITGN.</p>
<p>An environment that gives all of us the freedom to experiment and the leeway to fail is extremely enabling. This has led to a wide spectrum of wins, many that are quantifiable and others that are less tangible. If you want to get a sense of how good the times have been, just look around – the sheer beauty and the attention to detail that the campus embodies is an excellent symbolism for the inclusive, thoughtful, and innovative leadership that we have experienced. When it comes to how far we have come, I could go on… pretty much forever, so I’ll defer you to the website for more details.</p>
<p>It is impossible to imagine IITGN without you. This is your brainchild through and through. Despite knowing that you’ll not be distancing in spirit, we will miss having you nurture the institution in the hands-on manner that you have always done. Your passion for the IITGN mission – of being a breakout university while operating within the limitations and strengths of the IIT system – is contagious. I am sure you plan to double down on this even though you may have a few distractions going forward.</p>
<p>I recently watched Maanaadu, a movie based on the idea of a time loop. In such stories, the plot involves the protagonist experiencing the same day over and over again, and their goal, typically, is to find an exit. If there is one day that we could put into a time loop, it would be today, and there would be no need to get out of it.</p>
<p>In the meantime – on behalf of all of us, thank you.</p>
<p>Thank you for your commitment, trust, and friendship; for listening patiently, for leading tirelessly, and for fighting the good fight through tough times, and for the good times through tough fights – ok, I’m going to be out of time, here, clearly – so let me just say, thank you for everything.</p>
</blockquote>



 ]]></description>
  <category>iitgn</category>
  <guid>https://www.neeldhara.com/blog/skj/</guid>
  <pubDate>Thu, 22 Sep 2022 18:30:00 GMT</pubDate>
</item>
<item>
  <title>External Communications</title>
  <link>https://www.neeldhara.com/blog/comms/</link>
  <description><![CDATA[ 





<p>I finish seven years at IIT Gandhinagar today.</p>
<p>This year, I also concluded my stint with the Department of External Communications, which feels about as long. Indeed, little did I know that a casual remark that I had made during my interview<sup>1</sup>, about wanting to be a writer for as long as I can remember, was carefully noted — and magically my service responsibilities would end up being related to my childhood dream. A few days after I joined, I met <a href="https://www.linkedin.com/in/achal-mehra-13037931/">Achal Mehra</a>, who introduced me to <a href="https://iitgn.ac.in/about/newsletter"><em>Connections</em></a>: a four-page newsletter that went places every quarter. In my mind, that conversation kickstarted my collaboration with what everyone fondly calls “comms”. Seven years later, I’m here to report that the journey has been fun and fulfilling in equal measure.</p>
<p>Through this post, I’d like to introduce you to the comms team: if you have been to IITGN for an event, read about us in the press, have recieved a newsletter from us, visited our website, or followed our social media: these are the folks who work behind the scenes on these fronts. Being a part of this gang has been a huge inspiration: everyone is talented but always willing to learn; their hard work is driven by a sense of ownership; and there’s plenty of wit to help beat the heat :)</p>
<p>Here’s collection of some randomly chosen memories: my hat-tip to a stellar team.</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/comms/1.jpg" class="img-fluid figure-img"></p>
<figcaption>The External Communications Team. From left to right: Hatim, Dilip, Tej, Apeksha, Dhara, Divyangi, Yours Truly, Chandni, Vandana, Shivangi, Gaurav, and Devarsh.</figcaption>
</figure>
</div>
<section id="hatim" class="level2">
<h2 class="anchored" data-anchor-id="hatim">Hatim</h2>
<p><a href="https://www.linkedin.com/in/hatimsham/">Hatim</a> joined us in the summer of 2018 and worked with us for four years. This summer, he moved on to join the design unit at <a href="https://www.isdm.org.in/team">ISDM</a> as a Graphic Designer and Video Editor.</p>
<p>Hatim has had a creative flair from the get go. He’s been a part of several exciting projects, including being the person <a href="https://www.facebook.com/hatimsham/blog/pfbid02hWtj37tfFBSZiWmbe5yXTALMbDpG41YkGWtWZa4kxr25dysYdHnEjxZQMH6y5HcTl">behind the visuals</a> for Alok Kanungo’s book, <em>Glass Crafts in Northern India</em>. Also, <a href="https://twitter.com/iitgn/status/1285917964059869184">here’s a cool trailer</a> he put together very quickly for the ACM-W India Grad Cohort that I was involved in organizing in 2020.</p>
</section>
<section id="dilip" class="level2">
<h2 class="anchored" data-anchor-id="dilip">Dilip</h2>
<p><a href="https://www.linkedin.com/in/dilip-kashyap-49aaaaa0/">Dilip</a> joined us in the summer of 2018. He had a distinct passion for developing mobile and web applications, and indeed, he’s been a huge asset to the web vertical of the team. He’s been relentless in learning new things and has been <a href="https://dilipkashyap15.medium.com/">writing on Medium</a> too.</p>
<p>When we were organizing the ACM-India Annual event and the team was freaking out over having upwards of 1000 registrations, Dilip wrote a mobile app for us — literally overnight — which allowed us to send all participants a QR code that they simply had to show to get through physical registration. It saved us a ton of time. You can find out more about Dilip <a href="https://dilipkashyap07.github.io/">here</a>.</p>
</section>
<section id="tej" class="level2">
<h2 class="anchored" data-anchor-id="tej">Tej</h2>
<p><a href="https://www.linkedin.com/in/tej-bahadur-gurung-8b94232a/">Tej</a> joined us in the winter of 2016 as a web developer and has been my officemate. Tej is among the first points of contact for all new faculty at IITGN: their institutional profile pages are set up even before they actually set foot on campus. Tej’s name is synonymous with “website”. If anyone needs one done, whether it’s for their lab, or an event, he’s always been an email away. True to an appropriate mispronouciation of his name<sup>2</sup>, Tej has remarkable turnaround times, and seems to get things done as fast as you can spell them out.</p>
<p>One of my most memorable projects with Tej (along with Dilip, Divyangi, and the rest of the team) is the revamp of the main IITGN website. We went from this:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/comms/old.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>The old IITGN website, <a href="https://legacy.iitgn.ac.in">here</a>.</figcaption>
</figure>
</div>
<p>to this:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/comms/new.gif" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>The current IITGN website, <a href="https://www.iitgn.ac.in">here</a>.</figcaption>
</figure>
</div>
<p>in about a year. Despite several very well-intended warnings about how crazy this was, the team picked up the project with cautious courage, and pulled it off. I think I can say with some confidence that the IITGN website is easy on the eyes, and things are not hard to find.</p>
</section>
<section id="apeksha" class="level2">
<h2 class="anchored" data-anchor-id="apeksha">Apeksha</h2>
<p><a href="https://www.linkedin.com/in/srivastava-apeksha/">Apeksha</a> joined us in the summer of 2019, just on the heels of completing her MTech in Biological Engineering at IITGN, and stayed with the team for a year. At the time of joining, she was an avid consumer of popular science material, and aspired to make the research at IITGN more broady accessible with her writing. She was a freelance writer already, and was looking for an opportunity to spend some time writing full-time. Her stint with us resulted in a number of articles, and her growth during the time has been remarkable. You can find her writing on <a href="https://medium.com/@apeksha.0503">her Medium blog</a>.</p>
<p>The ACM-W India Grad Cohort event we did in 2020 was a virtual one, and in the tradition of Grad Cohorts, was not recorded. I am grateful that Apeksha stepped up at the time, offered to attend all the sessions, and <a href="https://medium.com/@apeksha.0503/the-acm-w-grad-cohort-2020-women-conquering-computing-online-ca085623e396">wrote</a> <a href="https://medium.com/@apeksha.0503/grad-cohort-2020-day-1-of-the-women-virtual-workshop-in-computing-opens-with-a-bang-56407c113ad">up</a> <a href="https://medium.com/@apeksha.0503/acm-w-grad-cohort-2020-day-2-a-perfect-combo-of-motivation-and-quality-advice-from-women-leaders-3f2c629e05e5">comprehensive</a> <a href="https://medium.com/@apeksha.0503/day-3-acm-w-grad-cohort-2020-concludes-with-strong-networking-opportunities-and-professional-bc8c78efbc33">summaries</a>.</p>
<p>She has now joined the Ph.D.&nbsp;program in the Humanities and Social Sciences and is currently researching cognitive aspects of science communication with <a href="https://en.wikipedia.org/wiki/Frederick_L._Coolidge.">Frederick Coolidge</a>.</p>
</section>
<section id="dhara" class="level2">
<h2 class="anchored" data-anchor-id="dhara">Dhara</h2>
<p><a href="https://www.linkedin.com/in/dhara-vora-1019/">Dhara</a> joined us in the summer of 2018, and immediately got to work on managing our social media channels. She also streamlined the process of collecting information: a lot of what we do revolves around robust archival, and IITGN being a happening place does not make this easy! We get dozens of emails every day announcing events of varying scales, updates of various kinds.</p>
<p>Anticipating that the volume would only get worse, we devised a system for manually cataloging every bit of news in a bunch of Airtable bases. The long-term vision was that the Airtable API exposes this data to anyone who needs it: the web team could draw from it and filter appropriately to display upcoming events, an archival team could write a report generating app that used this as the backend, and so forth. We even had a web app developed by a team of undergraduates that pulled data from these bases to show off upcoming events on a big screen.</p>
<p>Dhara now manually curates information from these databases and runs a weekly internal newsletter collating what’s happened and what’s coming up at IITGN: this has been a major value addition for many. She also serves up the raw data needed for our public <a href="https://iitgn.ac.in/about/newsletter">quarterly newsletter</a> and <a href="https://iitgn.ac.in/about/annualreports">annual reports</a> based on this system, which saves everyone a lot of time. Apart from all of this, she is in the driver’s seat for all our <a href="https://twitter.com/iitgn">major</a> <a href="https://www.facebook.com/iitgn.official">social</a> <a href="https://www.linkedin.com/school/indian-institute-of-technology-gandhinagar-iitgn-/">media</a> <a href="https://www.instagram.com/iit_gandhinagar/">channels</a>, and then some… and magically manages to stay on top of everything. You can <a href="https://medium.com/@voradhara46">find her writing on Medium</a>.</p>
</section>
<section id="divyangi" class="level2">
<h2 class="anchored" data-anchor-id="divyangi">Divyangi</h2>
<p><a href="https://www.linkedin.com/in/divyangi-chaudhari-404115140/">Divyangi</a> joined us in the summer of 2018 and worked with us for three years until the summer of 2021. She was a wizard when it came to scripting for automating tasks, and quickly became the go-to person for departments who were looking to improve their workflows.</p>
<p>IITGN runs on the Google ecosystem. Divyangi figured out several nice ways of bringing data from spreadsheets to frontends, generating reports, and so forth. She even ran a workshop on Google scripts and related tools as a part of an initiative coordinated by our Staff Development Cell.</p>
<p>Among the many projects Divyangi was involved in, one of my favorites was the backend for our rather popular <a href="https://srip.iitgn.ac.in/">Summer Research Internship Program</a>. The website is powered by WordPress, and provides various interfaces for both interns and mentors to keep track of their applications during the application phase (this runs into tens of thousands of records), and progress during the internship (updates from interns and feedback from mentors are all managed from here). Divyangi, together with Dilip, deeply customized the WordPress instance to provide a number of features that help with running a large-scale program smoothly, with most of the tedious tasks completely automated.</p>
</section>
<section id="chandni" class="level2">
<h2 class="anchored" data-anchor-id="chandni">Chandni</h2>
<p>Chandni joined us in the summer of 2019 for a year. She was already a very talented photographer at the time of joining us. As our events and activities grew in number and scale, we found very valuable support in Chandni’s presence. Check out her <a href="https://www.instagram.com/visi_lens/">Instagram</a> here!</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/comms/chand.png" class="img-fluid figure-img" style="width:70.0%"></p>
<figcaption>A sample of Chandni’s photography</figcaption>
</figure>
</div>
</section>
<section id="vandana" class="level2">
<h2 class="anchored" data-anchor-id="vandana">Vandana</h2>
<p><a href="https://www.linkedin.com/in/vandanay/">Vandana</a> joined us in the summer of 2017 in the role of a Communications and Media Officer for a year. During this time, she was working closely with local press and media, and ensuring that our stories are filed with them on a regular basis.</p>
<p>Vandana was already passionate about writing and had a keen eye for detail. She filled an important void at the time she joined and immediately setup various important foundations in the context of this role. She expanded our style guide, made a press kit, and developed a starting database of journalists that we could work with: these are all tools that the whole content team uses regularly to this day.</p>
<p>Her spirit of volunteerism meant that a lot of our content got reviewed and improved across the board: on the website, on our brochures, and so forth. This was also the time when we launched what I think is our best-kept secret: IITGN’s <a href="https://news.iitgn.ac.in">news blog</a>. Vandana, along with the rest of the team, setup a careful pipeline to ensure that everything we capture across press and social media gets a permanent home on the blog. She continues to pitch in remotely, even after moving on from her onsite role with us on campus.</p>
</section>
<section id="shivangi" class="level2">
<h2 class="anchored" data-anchor-id="shivangi">Shivangi</h2>
<p><a href="https://www.linkedin.com/in/shivangi-bhatt-365b4a38/">Shivangi</a> joined us in the summer of 2018 in the role of a Communications and Media Officer, picking up from where Vandana left off. She has been synonymous with media and press at IITGN, and is currently our main interface with the press. She has substantially expanded on our network of partners in press, and ensures that we have the visibility we deserve in the local and national news, and even beyond. She is especially diligent about ensuring that regionally-focused news is appropriately translated in the local languages whenever appropriate, a widely appreciated effort.</p>
<p>Shivangi’s style has been remarkably proactive: if anything at IITGN is newsworthy, she makes sure it’s covered. She draws on her substantial experience in the field to bring nuanced insights to the table, and these have served us very well in our overall communications and outreach strategy.</p>
<p>Beyond coordinating stories for the press, Shivangi also comprehensively tracks IITGN’s presence in the news and other public domains, is closely invovled in the production of the <a href="https://iitgn.ac.in/about/newsletter">quarterly newsletter</a> and <a href="https://iitgn.ac.in/about/annualreports">annual reports</a>, and our social media activities as well. Shivangi is, unsurprisingly, an amazing writer, and <a href="https://www.facebook.com/shivangi.bhatt.501/blog/pfbid0CB5AGAkotx6cuXnYdNKGqVWc9jE7p3DrodzKTYGGDymSDWC4fxCJNer6bUrLCpJol">here’s a performance of hers</a> in a SDC event that was among my favorites.</p>
</section>
<section id="gaurav" class="level2">
<h2 class="anchored" data-anchor-id="gaurav">Gaurav</h2>
<p><a href="https://www.linkedin.com/in/gauravvipul/">Gaurav</a> has been around for longer than I have, and he is a founding member of the team. He is among the most versatile people I know: not only does the scope of his work at IITGN go well beyond communications, even within communications his skills span a very wide range: he’s behind the camera, he’s the person behind the design and layouts for some of our best print collaterals, he’s directed and produced a number of videos, and I could go on and on.</p>
<p>I’ve freely relied on his mentorship: much of the growth that has happened within the team, especially in terms of creative efforts, is thanks to Gaurav’s experience and guidance.</p>
<p>If you pick up any of our booklets, there’s a good chance that Gaurav has been involved in engineering the layout and design. Among them, I’ll single out a couple for you to sample: the <em><a href="https://iitgn.ac.in/assets/pdfs/brochures/faculty-brochure.pdf">World Class Faculty</a></em> brochure looks especially lovely in print, and the <a href="https://sites.iitgn.ac.in/10/index.php">10 on 10</a> brochure has a bold aesthetic that was a crowd favorite when it was released for our 10-year celebration.</p>
</section>
<section id="devarsh" class="level2">
<h2 class="anchored" data-anchor-id="devarsh">Devarsh</h2>
<p><a href="https://www.instagram.com/dev_barbhaya/">Devarsh</a> joined us in the summer of 2017, with a background in creative film-making and theatre. He quickly became the go-to person when it came to anything to do with video or photography. Over the years here, he’s grown leaps and bounds in his craft and understanding of all aspects of the process — both work that happens on the field and in post.</p>
<p>Our YouTube presence was in its nascent stages when Devarsh joined. He’s single-handedly worked on <a href="https://www.youtube.com/channel/UCbOCAa_fRS1qEOknCmEHzVw">our channel</a> in mission mode from the get go, and it is largely thanks to his efforts that we have a fairly systematic video respository of most major events and talks on campus.</p>
<p>Devarsh has been involved in several memorable projects. Here’s <a href="https://www.youtube.com/embed/lZSAkpjsyZs">a video</a> that he shot for our first virtual convocation, which also happened to be among the first virtual convocation events to be held in India (as far as we know).</p>
</section>
<section id="nostalgia" class="level2">
<h2 class="anchored" data-anchor-id="nostalgia">Nostalgia</h2>
<p>Some of the early members of the team are not pictured. Apart from everyone above, I had the good fortune to have worked with: Ritu (among other things, was the curator for all the early editions of the quarterly newsletter, <em>Connections</em>, and our annual reports), Dayanand (our first communications and media officer), Maria (our first social media intern), and Khushbu (who took over from Maria and preceded Dhara on managing social media).</p>
<p>It would be remiss of me to not give a shout out to the faculty support we have enjoyed over the years. Several colleagues have played major roles in helping out on all aspects of our responsbilities. A special thanks to Achal Mehra, who brought extensive experience to the table, and has been forever generous with his time and advice, and <a href="https://twitter.com/iitgn/status/1163406174626050048">Vasco Trigo</a>, whose inputs for the whole team were extremely timely and valuable.</p>
<p>I’ll also take this opportunity to thank friends at the Communications department at Duke University — they hosted us in the very early days, and their detailed and candid tour of various operational aspects was massively helpful in setting up a lot of the foundations back here.</p>
<p>I walked into this gig more or less by accident. I should confess here that I didn’t have a 5-year vision from which I could work backwards to nicely chunked milestones. There were no OKRs or KPIs or whatever else the pros do. A few times, it’s occurred to us that we should have targets, strategies, and systems<sup>3</sup>. While we never articulated any as far as I can remember, I think we did have a tacitly shared goal: it was to ensure that everyone got what they needed from comms, and that we didn’t make any mistake twice. My biases notwithstanding, I would say we have largely succeded :)</p>
<p>My time with this team remains special forever.</p>


</section>


<div id="quarto-appendix" class="default"><section id="footnotes" class="footnotes footnotes-end-of-document"><h2 class="anchored quarto-appendix-heading">Footnotes</h2>

<ol>
<li id="fn1"><p>This was during the summer of 2015, with <a href="https://sudhirjain.info/">Prof.&nbsp;Sudhir Jain</a>.↩︎</p></li>
<li id="fn2"><p>Tez = fast in Hindi↩︎</p></li>
<li id="fn3"><p>Most people at IITGN know by now that ambushing me in a corridor is more effective than email, and meanwhile, the team gets things done by some magic that remains a mystery to me.↩︎</p></li>
</ol>
</section></div> ]]></description>
  <category>iitgn</category>
  <guid>https://www.neeldhara.com/blog/comms/</guid>
  <pubDate>Thu, 22 Sep 2022 18:30:00 GMT</pubDate>
</item>
<item>
  <title>Dog Bunny Puzzle</title>
  <link>https://www.neeldhara.com/blog/dogs-bunny-puzzle/</link>
  <description><![CDATA[ 





<section id="dog-bunny-a-cute-puzzle" class="level3">
<h3 class="anchored" data-anchor-id="dog-bunny-a-cute-puzzle">Dog Bunny: A Cute Puzzle</h3>
<p>Conrad Barski (<a href="https://twitter.com/lisperati"><span class="citation" data-cites="lisperati">@lisperati</span></a>)’s latest, <a href="http://www.dogbunnypuzzle.com/">Dog Bunny Puzzle</a>, had <a href="https://news.ycombinator.com/item?id=32884467">jumped to #1 on HN</a>. The puzzle presents the following somewhat minimalist interface:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/dogs-bunny-puzzle/puzzlescreenshot.png" class="img-fluid figure-img" style="width:77.0%"></p>
<figcaption>The Dogs Bunny Puzzle</figcaption>
</figure>
</div>
<p>If you haven’t played it yet, you might want to go ahead and <a href="http://www.dogbunnypuzzle.com/">give it a shot</a> first. Most people figured out the mechanics without any explicit instructions. A couple of things that may not be immediately clear, but typically discovered quickly within a few moves:</p>
<ul>
<li><p>The edges are labeled with conditions, and can be used only if <em>all</em> of the said conditions are met.</p></li>
<li><p>The bunny or dog icons may sometimes cover up what kind of location they are at. You can drag them away to find out!</p></li>
<li><p>Multiple animals can occupy the same spot at a time.</p></li>
<li><p>It is possible to get into a dead end, a situation from where no legal moves are possible. In the verison of the game that is available at the time of this writing, the game offers no sign that you might be in this situation. This may <a href="https://twitter.com/lokshtanov/status/1571597503795167232">however change</a>.</p></li>
</ul>
<p>After winging it on the puzzle, several questions seemed natural:</p>
<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-1-contents" aria-controls="callout-1" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
What’s the smallest number of moves to win?
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-1" class="callout-1-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p><a href="https://gist.github.com/wrbs/5824e9b17c55b5ad3d8467f93e12ed8b">Apparently 26.</a></p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-2-contents" aria-controls="callout-2" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Can you write a program to find a solution?
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-2" class="callout-2-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p><a href="https://github.com/polkerty/dog-bunny-puzzle-solver/blob/master/main.py">Yes</a> (Python) and <a href="http://hakank.org/picat/dogbunny_puzzle.pi">yes</a> (Picat).</p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-3-contents" aria-controls="callout-3" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Can a script generate more of these puzzles?
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-3" class="callout-3-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Indeed:</p>
<blockquote class="twitter-tweet blockquote" data-conversation="none">
<p lang="en" dir="ltr">
For those paying attention, yes I am two days late :(<br><br>FYI, I also have a program now that can create an infinite number of these puzzles at differing difficulty<br><br>How would you rate the puzzle I posted today?
</p>
— Conrad Barski (<span class="citation" data-cites="lisperati">@lisperati</span>) <a href="https://twitter.com/lisperati/status/1571232335043112960?ref_src=twsrc%5Etfw">September 17, 2022</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-4-contents" aria-controls="callout-4" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Are there connections with other well-known puzzles?
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-4" class="callout-4-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Why yes, check out the <a href="https://en.wikipedia.org/wiki/Wolf,_goat_and_cabbage_problem">Wolf puzzle</a> (as pointed out by <a href="https://twitter.com/RianNeogi/status/1571608738791817217"><span class="citation" data-cites="RianNeogi">@RianNeogi</span></a>) and this <a href="https://www.youtube.com/watch?v=ZCVAGb1ee8A">Numberphile video</a> about it.</p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note no-icon callout-titled">
<div class="callout-header d-flex align-content-center" data-bs-toggle="collapse" data-bs-target=".callout-5-contents" aria-controls="callout-5" aria-expanded="false" aria-label="Toggle callout">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Is the problem NP-complete?
</div>
<div class="callout-btn-toggle d-inline-block border-0 py-1 ps-1 pe-0 float-end"><i class="callout-toggle"></i></div>
</div>
<div id="callout-5" class="callout-5-contents callout-collapse collapse">
<div class="callout-body-container callout-body">
<p>Before you ask, <a href="https://twitter.com/gfredericks_/status/1571247392321671174">I am not the only one</a> who’s asking!</p>
</div>
</div>
</div>
<p>So the last question may strike you as a bit left-field, but that’s what I’m going to ramble about for the rest of this post :) It turns out that the answer is in the affirmative, and <a href="https://twitter.com/lokshtanov/status/1571588360254410752">here</a> is a lovely reduction by <a href="https://twitter.com/lokshtanov"><span class="citation" data-cites="lokshtanov">@lokshtanov</span></a> showing as much.</p>
</section>
<section id="the-reduction" class="level3">
<h3 class="anchored" data-anchor-id="the-reduction">The Reduction</h3>
<p>Let’s just set up the game as a computational problem just to be sure that we agree on the abstraction. In fact, we’ll be working with a simpler version that we will call <code>BunnyCarrot</code>.</p>
<div class="callout callout-style-default callout-tip no-icon callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-title-container flex-fill">
BunnyCarrot
</div>
</div>
<div class="callout-body-container callout-body">
<p>In the <code>BunnyCarrot</code> problem, the input is a simple undirected graph <img src="https://latex.codecogs.com/png.latex?G%20=%20(V,E)">, subsets <img src="https://latex.codecogs.com/png.latex?B"> and <img src="https://latex.codecogs.com/png.latex?C"> of <img src="https://latex.codecogs.com/png.latex?V"> indicating the initial positions of bunnies and carrots, and a (possibly empty) instruction <img src="https://latex.codecogs.com/png.latex?r_e"> for every <img src="https://latex.codecogs.com/png.latex?e%20%5Cin%20E">, which is a collection of conditions, <em>at least</em> one† of which must be true for the edge <img src="https://latex.codecogs.com/png.latex?e"> to be “active”.</p>
<p>The question is if there is a sequence of movements of bunnies along active edges such that at the end of the sequence, every bunny is located at one of the vertices from <img src="https://latex.codecogs.com/png.latex?C">.</p>
<p>† In the original version of the problem, we need <em>all</em> conditions associated with an edge to be satisfied, not at least one. The construction that we will describe can be easily adapted to this setting as well, but is simpler to describe for this variant :)</p>
</div>
</div>
<p>We are going to show that <code>BunnyCarrot</code> is NP-complete by reducing from <code>3SAT</code>. So let <img src="https://latex.codecogs.com/png.latex?%5Cphi%20:=%20%5C%7BC_1,%20%5Cldots,%20C_m%5C%7D"> be a collection of <img src="https://latex.codecogs.com/png.latex?m"> 3SAT clauses over variables <img src="https://latex.codecogs.com/png.latex?%5C%7Bx_1,%20%5Cldots,%20x_n%5C%7D">. The reduced instance of <code>BunnyCarrot</code> corresponding to <img src="https://latex.codecogs.com/png.latex?%5Cphi"> looks like this:</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/dogs-bunny-puzzle/reduction2.png" class="img-fluid figure-img" style="width:87.0%"></p>
<figcaption>A cartoon sketch of the reduced instance of BunnyCarrot from 3SAT.</figcaption>
</figure>
</div>
<p>What we have here is the following in terms of the structure of graph:</p>
<ul>
<li><p>a path <img src="https://latex.codecogs.com/png.latex?X"> on <img src="https://latex.codecogs.com/png.latex?m+2"> vertices, with the left most vertex in <img src="https://latex.codecogs.com/png.latex?B"> and the rightmost one in <img src="https://latex.codecogs.com/png.latex?C">;</p></li>
<li><p>a pair of vertices <img src="https://latex.codecogs.com/png.latex?(u_i,v_i)"> for every <img src="https://latex.codecogs.com/png.latex?i%20%5Cin%20%5Bn%5D">, and an edge between them, where all the <img src="https://latex.codecogs.com/png.latex?u_i">’s are in <img src="https://latex.codecogs.com/png.latex?B">’ — the vertex <img src="https://latex.codecogs.com/png.latex?u_i"> represents the literal <img src="https://latex.codecogs.com/png.latex?x_i"> while the vertex <img src="https://latex.codecogs.com/png.latex?v_i"> represents the literal <img src="https://latex.codecogs.com/png.latex?%5Coverline%7Bx_i%7D">;</p></li>
<li><p>a pair of vertices <img src="https://latex.codecogs.com/png.latex?p"> and <img src="https://latex.codecogs.com/png.latex?q"> in <img src="https://latex.codecogs.com/png.latex?C">, with <img src="https://latex.codecogs.com/png.latex?p"> adjacent to all <img src="https://latex.codecogs.com/png.latex?u_i">’s and <img src="https://latex.codecogs.com/png.latex?q"> adjacent to all <img src="https://latex.codecogs.com/png.latex?v_i">’s.</p></li>
</ul>
<p>Now here be the instructions associated with the edges:</p>
<ul>
<li><p>the edge to the <img src="https://latex.codecogs.com/png.latex?%5Cell">-th vertex on <img src="https://latex.codecogs.com/png.latex?X"> is active only if there is a bunny on at least one of the literals present in the clause <img src="https://latex.codecogs.com/png.latex?C_%7B%5Cell-1%7D">;</p></li>
<li><p>the edges between <img src="https://latex.codecogs.com/png.latex?u_i"> and <img src="https://latex.codecogs.com/png.latex?v_i"> are active only when there is a bunny on the leftmost vertex of <img src="https://latex.codecogs.com/png.latex?X">; and</p></li>
<li><p>finally, the edges incident on <img src="https://latex.codecogs.com/png.latex?p"> and <img src="https://latex.codecogs.com/png.latex?q"> are active only when there is a bunny on the rightmost vertex of <img src="https://latex.codecogs.com/png.latex?X">.</p></li>
</ul>
</section>
<section id="the-forward-direction" class="level3">
<h3 class="anchored" data-anchor-id="the-forward-direction">The Forward Direction</h3>
<p>We first claim that we can “win” this game if <img src="https://latex.codecogs.com/png.latex?%5Cphi"> has a satisfying assignment. Indeed, let <img src="https://latex.codecogs.com/png.latex?%5Ctau:%20%5C%7Bx_1,%5Cldots,x_n%5C%7D%20%5Crightarrow%20%5C%7B0,1%5C%7D"> be a truth assignment that satisfies all the clauses of <img src="https://latex.codecogs.com/png.latex?%5Cphi">. Then:</p>
<ol type="1">
<li><p>If <img src="https://latex.codecogs.com/png.latex?%5Ctau(x_i)%20=%200">, move the bunny on <img src="https://latex.codecogs.com/png.latex?u_i"> to <img src="https://latex.codecogs.com/png.latex?v_i">.</p></li>
<li><p>Move the bunny on the leftmost vertex of the path <img src="https://latex.codecogs.com/png.latex?X"> to the rightmost vertex: note that all edges are active because <img src="https://latex.codecogs.com/png.latex?%5Ctau"> is a satisfying assignment.</p></li>
<li><p>Move all bunnies on <img src="https://latex.codecogs.com/png.latex?u_i">’s to <img src="https://latex.codecogs.com/png.latex?p"> and those on <img src="https://latex.codecogs.com/png.latex?v_i">’s to <img src="https://latex.codecogs.com/png.latex?q">.</p></li>
</ol>
</section>
<section id="the-backward-direction" class="level3">
<h3 class="anchored" data-anchor-id="the-backward-direction">The Backward Direction</h3>
<p>Now suppose there is a winning sequence of moves <img src="https://latex.codecogs.com/png.latex?%5Csigma">. We will show that we can extract from this sequence a satisfying assignment for <img src="https://latex.codecogs.com/png.latex?%5Cphi">, which will firmly establish the equivalence of the generated instance of <code>BunnyCarrot</code> with the OG hard instance <img src="https://latex.codecogs.com/png.latex?%5Cphi">.</p>
<p>Note that to begin with, all the blue edges are inactive. Now, in the sequence <img src="https://latex.codecogs.com/png.latex?%5Csigma">, let us say that a step is <em>key</em> if it involves a bunny moving along the first edge of the path <img src="https://latex.codecogs.com/png.latex?X"> and <em>critical</em> if it involves a bunny moving along the last edge of the path <img src="https://latex.codecogs.com/png.latex?X">.</p>
<p>Suppose the <img src="https://latex.codecogs.com/png.latex?%5Cell">-th step is the first critical step in <img src="https://latex.codecogs.com/png.latex?%5Csigma">. Further, suppose that the <img src="https://latex.codecogs.com/png.latex?t">-th step is the <em>last</em> key step to occur <em>before</em> the <img src="https://latex.codecogs.com/png.latex?%5Cell">-th step. Notice that there must be at least one key step before a critical step — we must begin before we can end :)</p>
<p>Now, for all steps after the <img src="https://latex.codecogs.com/png.latex?t">-th step and before the <img src="https://latex.codecogs.com/png.latex?%5Cell">-th step, note that edges incident to <img src="https://latex.codecogs.com/png.latex?u_i"> and <img src="https://latex.codecogs.com/png.latex?v_i"> are <strong>inactive</strong> for all <img src="https://latex.codecogs.com/png.latex?i%20%5Cin%20%5Bn%5D">. This implies that every step between the <img src="https://latex.codecogs.com/png.latex?t">-th and <img src="https://latex.codecogs.com/png.latex?%5Cell">-th steps involves a bunny moving along <img src="https://latex.codecogs.com/png.latex?X">, and in particular, every edge in <img src="https://latex.codecogs.com/png.latex?X"> is crossed at least once in this phase of the game.</p>
<p>Let us note the positions of the bunnies who are on the <img src="https://latex.codecogs.com/png.latex?u_i">’s and <img src="https://latex.codecogs.com/png.latex?v_i">’s after the <img src="https://latex.codecogs.com/png.latex?t">-th step is executed. Observe that this naturally translates to an assignment on the variables as follows:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0A%5Cbegin%7Bequation*%7D%0A%20%20%20%20%5Ctau(x_i)%20=%0A%20%20%20%20%5Cbegin%7Bcases%7D%0A%20%20%20%20%20%201%20&amp;%20%5Ctext%7Bif%20%7D%20u_i%20%5Cin%20B,%5C%5C%0A%20%20%20%20%20%200%20&amp;%20%5Ctext%7Bif%20%7D%20v_i%20%5Cin%20B.%0A%20%20%20%20%5Cend%7Bcases%7D%0A%5Cend%7Bequation*%7D%0A"></p>
<p>We argue that <img src="https://latex.codecogs.com/png.latex?%5Ctau"> must in fact be a satisfying assignment.</p>
<p>Assume to the contrary: suppose some clause <img src="https://latex.codecogs.com/png.latex?C_k"> is, in fact, not satisfied by <img src="https://latex.codecogs.com/png.latex?%5Ctau">.</p>
<p>Then, we claim that the edge connecting the <img src="https://latex.codecogs.com/png.latex?k">-th and <img src="https://latex.codecogs.com/png.latex?(k+1)">-th vertices is not active.</p>
<p>As an example, suppose <img src="https://latex.codecogs.com/png.latex?C_k%20=%20%5C%7Bx_1,x_2,%5Coverline%7Bx_3%7D%5C%7D">. Since <img src="https://latex.codecogs.com/png.latex?%5Ctau"> does not satisfy <img src="https://latex.codecogs.com/png.latex?C_k">, it must be the case that:</p>
<ul>
<li><img src="https://latex.codecogs.com/png.latex?%5Ctau(x_1)%20=%200"> — and hence there is a bunny on <img src="https://latex.codecogs.com/png.latex?v_1">;</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Ctau(x_2)%20=%200"> — and hence there is a bunny on <img src="https://latex.codecogs.com/png.latex?v_2">;</li>
<li><img src="https://latex.codecogs.com/png.latex?%5Ctau(x_3)%20=%201"> — and hence there is a bunny on <img src="https://latex.codecogs.com/png.latex?u_3">.</li>
</ul>
<p>However, the condition for the edge to the <img src="https://latex.codecogs.com/png.latex?(k+1)">-th vertex on <img src="https://latex.codecogs.com/png.latex?X"> to be active is simply that there is a bunny present on at least one of the literals present in the clause <img src="https://latex.codecogs.com/png.latex?C_%7Bk%7D">, i.e, one of <img src="https://latex.codecogs.com/png.latex?u_1">, <img src="https://latex.codecogs.com/png.latex?u_2"> or <img src="https://latex.codecogs.com/png.latex?v_3">. However, because of the structure of the graph, and the fact that all edges incident on <img src="https://latex.codecogs.com/png.latex?p"> and <img src="https://latex.codecogs.com/png.latex?q"> are inactive at all times before the first critical step, observe that:</p>
<ul>
<li>If there is a bunny on <img src="https://latex.codecogs.com/png.latex?v_1">, there is no bunny on <img src="https://latex.codecogs.com/png.latex?u_1">.</li>
<li>If there is a bunny on <img src="https://latex.codecogs.com/png.latex?v_2">, there is no bunny on <img src="https://latex.codecogs.com/png.latex?u_2">.</li>
<li>If there is a bunny on <img src="https://latex.codecogs.com/png.latex?u_3">, there is no bunny on <img src="https://latex.codecogs.com/png.latex?v_3">.</li>
</ul>
<p>By our assumption that <img src="https://latex.codecogs.com/png.latex?%5Ctau"> falsifies <img src="https://latex.codecogs.com/png.latex?C_k">, <em>all</em> the premises above are true! So there is an edge on the path <img src="https://latex.codecogs.com/png.latex?X"> that is not active between the <img src="https://latex.codecogs.com/png.latex?t">-th and <img src="https://latex.codecogs.com/png.latex?%5Cell">-th steps, which violates our understanding that every edge was crossed between these steps. This is a contradiction, and hence <img src="https://latex.codecogs.com/png.latex?%5Ctau"> must indeed be a satisfying assignment.</p>
<p>I’ll just remark here that this construction can be modified so that every vertex in the graph has constant degree, and there is only one vertex in <img src="https://latex.codecogs.com/png.latex?C">. It can also be modified to change the “or” condition on the edges to an “and”, by simply separating the conditions out along multiedges.</p>
</section>
<section id="food-for-thought" class="level3">
<h3 class="anchored" data-anchor-id="food-for-thought">Food for thought</h3>
<p>Here are some more questions :)</p>
<div class="callout callout-style-simple callout-important no-icon">
<div class="callout-body d-flex">
<div class="callout-icon-container">
<i class="callout-icon no-icon"></i>
</div>
<div class="callout-body-container">
<ol type="1">
<li><p>What’s the complexity of this game when the underlying graph has some simple structure (e.g, a tree)?</p></li>
<li><p>Does the problem get harder if we introduce attacking entities like wolves?</p></li>
<li><p>Can we come up with an algorithm that runs in polynomial time on instances where there is a valid winning sequence of constant length?</p></li>
<li><p>Is the problem hard even for a constant number of bunnies?</p></li>
</ol>
</div>
</div>
</div>
<p>PS. Here’s <a href="https://twitter.com/neeldhara/status/1571522626526515202">a sketch of a slighty different reduction</a> from vertex cover. Thanks again to <a href="https://twitter.com/lokshtanov">Daniel</a> for sharing the reduction described here! Comments welcome here, or <a href="https://twitter.com/neeldhara/status/1571629379779973121">continue the conversation on Twitter</a>!</p>


</section>

 ]]></description>
  <category>puzzles</category>
  <category>exposition</category>
  <guid>https://www.neeldhara.com/blog/dogs-bunny-puzzle/</guid>
  <pubDate>Sun, 18 Sep 2022 18:30:00 GMT</pubDate>
</item>
<item>
  <title>On Teaching</title>
  <link>https://www.neeldhara.com/blog/on-teaching/</link>
  <description><![CDATA[ 





<!--
:::{.callout-note appearance="simple" icon="false"}
These are some parts of the teaching statment that I wrote roughly seven years ago, updated slightly in the interest of clarity and additional context.
::: -->
<blockquote class="blockquote">
<p><em>A teacher does not teach, a student learns.</em></p>
<p>— snippet from <a href="https://www.facebook.com/425094961174523/videos/5530977776968824/">this interview</a> of <a href="https://en.wikipedia.org/wiki/Zakir_Hussain_(musician)">Ustad Zakir Hussain</a></p>
</blockquote>
<p>I’ll pose some how/what/why questions in the context of teaching.</p>
<section id="how" class="level2 page-columns page-full">
<h2 class="anchored" data-anchor-id="how">How</h2>
<div class="page-columns page-full"><p>The last couple of decades, especially the last few years, have seen dramatic changes in how information is communicated. A lot of learning happens in online communities, for instance, question-and-answer websites like Quora and StackExchange. Thanks to folks who invest time on these platforms, expert help seems to be nearer than ever before. Specialized and snark-free communities on Discord/Slack/Telegram are enabling peer-to-peer learning at global scale. </p><div class="no-row-height column-margin column-container"><span class="margin-aside">I keep hearing that Quora is not what it used to be, but as long as <a href="https://www.quora.com/profile/Thomas-Cormen-1/">Thomas Cormen</a> is an active user, I am positive it remains a valuable resource.</span></div></div>
<div class="page-columns page-full"><p>Books are beginning to be injected with exciting new technology: <a href="https://codemirror.net/index.html">CodeMirror</a> makes code interactive and runnable, while tools like <a href="https://pythontutor.com/">PythonTutor</a> can help with visualizing what happens behind-the-scenes when code is executed. <a href="https://github.com/denysdovhan/wtfjs">Say</a> <a href="https://www.destroyallsoftware.com/talks/wat">what</a> <a href="https://wtfjs.com/">you</a> <a href="https://martin-thoma.com/javascript-wtf/">want</a> about JavaScript, but the interactivity that it brings to the written medium has helped make reading less passive. Some of my favorite interactive texts include <a href="https://seeing-theory.brown.edu/">Seeing Theory</a>, <a href="http://probmods.org/">Probabilistic Models of Cognition</a>, courses on <a href="https://brilliant.org/">Brilliant</a>, <a href="https://mathigon.org/">Mathigon</a>, and essays from <a href="https://ncase.me/">Nicky Case</a>, <a href="https://minutelabs.io/">Minute Labs</a>, and others on <a href="https://explorabl.es/">Explorables</a>.</p><div class="no-row-height column-margin column-container"><span class="margin-aside">The name “PythonTutor” is slightly misleading, since the website also lets you visualize code snippets written in C, C++, Java, and JavaScript.</span></div></div>
<div class="columns">
<div class="column" style="width:45%;">
<p>And finally there are the online courses. At the time of this writing, it has been just a little over two decades since <a href="https://en.wikipedia.org/wiki/MIT_OpenCourseWare">MIT’s Open Course Ware</a> opened to the public. The early hype around MOOCs roughly coincided with my years in college and graduate school. As far as I remember, it was quite the thrill to have free-flowing access to online lectures — “taught by the best” — for several of the courses I was supposed to be doing as a part of my curriculum.</p>
</div><div class="column" style="width:4%;">

</div><div class="column" style="width:51%;">
<p><a href="https://imgflip.com/i/6s9ym6"><img src="https://i.imgflip.com/6s9ym6.jpg" title="made at imgflip.com" width="100%"></a></p>
</div>
</div>
<p>All this is to say that I walked into a career involving a substantial teaching component with plenty of hesitation. The delivery was/is still largely confined to classroom settings in broadcast mode. It is not entirely clear what this format has to offer over YouTube. Basic interactivity is being increasingly solved with questions built into video players. Peer learning is quite doable with WhatsApp/Slack/Discord groups and local chapter meetups. Scale in the context of assessments is somewhat addressed by peer evaluation. And then there are all the things you can do on YouTube that you can’t do with traditional lectures: find a teacher whose style resonates, find an accent you understand, replay, play at 2x, 0.5x, binge watch, don’t watch…</p>
<div class="page-columns page-full"><p>So: what’s the incentive for <em>anyone</em> to show up in a classroom at a fixed time, especially when said time is 8AM? This question became particularly relevant during the pandemic years: once the novelty wore off, almost nobody† showed up to lectures. If I was a student, I’d likely do the same. This remains largely an open problem in my mind, but here are some pointers that have kept me motivated about the conventional format. </p><div class="no-row-height column-margin column-container"><span class="margin-aside">† Shout out to those of you accounting for the “almost”, thank you!</span></div></div>
<ol type="1">
<li>Classroom = theatre. I am increasingly treating it as a ground for practicing standup and <a href="https://twitter.com/neeldhara/status/1542606730701307904?ref_src=twsrc%5Etfw">magic</a> skills. I should admit that this isn’t easy for a clinically shy person like myself, but I got used to making a fool of myself fast — that’s served well. I imagine that some of the fun that comes out performance-first lectures is hard to recreate with recordings and notes.</li>
</ol>
<div class="columns">
<div class="column" style="width:45%;">
<blockquote class="twitter-tweet blockquote">
<p lang="en" dir="ltr">
Totally. It's almost always a performance, irrespective of the class size. And the more you rehearse, the better it goes. At least that's what works for me.
</p>
— Manu Awasthi (<span class="citation" data-cites="mnwsth">@mnwsth</span>) <a href="https://twitter.com/mnwsth/status/1562372066967359490?ref_src=twsrc%5Etfw">August 24, 2022</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div><div class="column" style="width:10%;">

</div><div class="column" style="width:45%;">
<blockquote class="twitter-tweet blockquote">
<p lang="en" dir="ltr">
Some musings on teaching from a lunch talk awhile back: <a href="https://t.co/19vOXpxcjs">https://t.co/19vOXpxcjs</a>
</p>
— Tim Roughgarden (<span class="citation" data-cites="Tim_Roughgarden">@Tim_Roughgarden</span>) <a href="https://twitter.com/Tim_Roughgarden/status/1379441864072429570?ref_src=twsrc%5Etfw">April 6, 2021</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
</div>
<ol start="2" type="1">
<li><p>In a classroom setting, I can nudge the audience to discover things for themselves. As far as I know, the interactivity in online materials can help with validating understanding, but not as much with developing it from first principles. My hope is for learners to walk out of a classroom with the confidence that they <em>came up</em> with parts of the material in the textbook on their own.</p>
<p>Again, this is hard to do in time-bound fashion, given that a lot of this kind of understanding comes from brooding and hours of messing around. I can only hope to convince the audience that the process is worth the trouble.</p></li>
<li><p>The opportunity to show that you care. For learners who may have struggles with and beyond the materials — classrooms, labs, and office hours afford opportunities for us to offer help.</p>
<p>This was a late realization for me personally: for the longest time, my own sense of self-doubt did not allow me to see that I could potentially be useful to someone else. While self-doubt remains, I have started to compartmentalize it enough to show up for others.</p></li>
</ol>
<p>All this said, I believe online and remote formats have substantial potential for making quality education accessible at scale, and that it is only a matter of time before classrooms in their most conventional forms either become obsolete or a ruse.</p>

<div class="no-row-height column-margin column-container"><div class="">
<blockquote class="twitter-tweet blockquote">
<p lang="en" dir="ltr">
I am going to attend college lectures from now on just to increase my attention span. The goal will be to sit for an hour without sleeping or getting distracted from mobile notifications.
</p>
— Priyansh Agarwal (<span class="citation" data-cites="Priyansh_31Dec">@Priyansh_31Dec</span>) <a href="https://twitter.com/Priyansh_31Dec/status/1566707282695847937?ref_src=twsrc%5Etfw">September 5, 2022</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div></div><div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.neeldhara.com/blog/on-teaching/calvin-21stcentury.jpg" class="img-fluid figure-img"></p>
<figcaption>Calvin on 21st Century Education</figcaption>
</figure>
</div>
</section>
<section id="what" class="level2 page-columns page-full">
<h2 class="anchored" data-anchor-id="what">What</h2>
<p>It is also increasingly challenging to formulate a curricula gets people to the bleeding edge starting from the foundations. For instance, there is a growing sentiment that <a href="http://nlpers.blogspot.in/2014/10/machine-learning-is-new-algorithms.html">Machine Learning is the new Algorithms</a> (or <a href="http://blog.geomblog.org/2014/10/algorithms-is-new-algorithms.html">maybe not</a>). On the other hand, the extent of involvement of “mathematics” in introductory CS courses is also <a href="https://twitter.com/boazbaraktcs/status/1561737094866804738">up</a> <a href="https://twitter.com/togelius/status/1561737958385917953">for</a> <a href="https://twitter.com/YannaiGonch/status/1561480166429302784">debate</a>.</p>

<div class="no-row-height column-margin column-container"><div class="">
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://www.explainxkcd.com/wiki/images/7/79/obsolete_technology.png" class="img-fluid figure-img"></p>
<figcaption>Cutting Edge</figcaption>
</figure>
</div>
</div></div><p>How much theory <a href="https://cstheory.stackexchange.com/questions/8761/what-can-i-do-to-supplement-my-theoretical-undergraduate-cs-curriculum-so-that-i">is needed</a> for competence in practice? How crucial is it to develop competencies that don’t have an immediately visible ROI? How frequently do we <a href="https://twitter.com/ramgopal_rao/status/1566428352398774272">rewrite the textbooks</a> based on developments in industry?</p>
<p>I once read a collection of answers to the question of what <em>every computer science graduate should know</em> on a Q&amp;A site. As an aspiring graduate myself, I figured I should know what I should know. Unfortunately, I remember it as a mostly unnerving experience: it was a list that started with Voronoi diagrams and ended with incompleteness theorems, and a <em>lot</em> of things in between.</p>
<p>From the other side of the fence, for whatever it’s worth — the answer to this question <a href="https://twitter.com/togelius/status/1561738432422023175">remains elusive</a>, mainly because I think it’s a context-heavy issue. For better or worse, <a href="https://twitter.com/benmschmidt/status/1562256566631518208">there is a growing interest in computer science</a>, and it will likely remain a non-trivial challenge to find an approach that is both maximally inclusive and sufficiently useful. I can only hope that between ruthless efficiency in teaching things driven purely by need and a curriculum flooded with random adventures, we can find an balance appropriate to our contexts!</p>
<!-- ![[Comments](https://cstheory.stackexchange.com/questions/8761/what-can-i-do-to-supplement-my-theoretical-undergraduate-cs-curriculum-so-that-i) on a question on cstheory.SE](cstheoryvpractice.png){width=70%} -->
</section>
<section id="why" class="level2 page-columns page-full">
<h2 class="anchored" data-anchor-id="why">Why</h2>
<p>Given that everything that needs to be explained has more or less been done and dusted really well on the interwebs, personally, this is hardest question of the lot. Not from my own POV, that’s the easy bit - <a href="https://dsanghi.blogspot.com/2014/08/why-i-want-to-be-professor.html">as pointed out here</a>, it’s fun to go through the idea exchange process with a captive audience, and in my experience at least one party is sufficiently triggered at the end of it (hopefully in a good way).</p>

<div class="no-row-height column-margin column-container"><div class="">
<blockquote class="blockquote">
<p>The satisfaction that you get when you are able to explain a concept to someone who did not know it earlier is immense. Sometimes it could be straightforward, and sometimes it could be frustrating. But the end point is always the same - a smile on the faces of those students. Money can buy all the books, but can’t buy that smile.</p>
<p>Prof Dheeraj Sanghi, <a href="https://dsanghi.blogspot.com/2014/08/why-i-want-to-be-professor.html">“Why I want to be a professor”</a></p>
</blockquote>
</div></div><div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://phdcomics.com/comics/archive/phd062613s.gif" class="img-fluid figure-img"></p>
<figcaption>On hope in teaching.</figcaption>
</figure>
</div>
<p>I am just not sure if we create enough of a net positive in a traditional classroom setup from a ROI perspective. Given the few good things that the internet has brought us, perhaps it is time to think beyond classrooms and focusing on making existing resources more accessible to everyone who’s interested.</p>



<div class="no-row-height column-margin column-container"><section id="join-the-conversation" class="level3">
<h3 class="anchored" data-anchor-id="join-the-conversation">Join the conversation</h3>
<blockquote class="twitter-tweet blockquote">
<p lang="en" dir="ltr">
New blog, new post:<a href="https://t.co/c2lEHM0lTI">https://t.co/c2lEHM0lTI</a><br><br>Meanwhile — happy teachers day to everyone!
</p>
— Neeldhara (<span class="citation" data-cites="neeldhara">@neeldhara</span>) <a href="https://twitter.com/neeldhara/status/1566800730001788929?ref_src=twsrc%5Etfw">September 5, 2022</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</section></div></section>

 ]]></description>
  <category>funda</category>
  <guid>https://www.neeldhara.com/blog/on-teaching/</guid>
  <pubDate>Sun, 04 Sep 2022 18:30:00 GMT</pubDate>
</item>
</channel>
</rss>
