<?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>Hamel&#39;s Blog</title>
<link>https://glittering-puffpuff-87102e.netlify.app/notes/</link>
<atom:link href="https://glittering-puffpuff-87102e.netlify.app/notes/index.xml" rel="self" type="application/rss+xml"/>
<description>Notes on applied AI engineering, machine learning, and data science.</description>
<image>
<url>https://user-images.githubusercontent.com/1483922/208359222-2b7e938e-27c4-4556-aacb-f5a81ce77b2d.png</url>
<title>Hamel&#39;s Blog</title>
<link>https://glittering-puffpuff-87102e.netlify.app/notes/</link>
</image>
<generator>quarto-1.9.38</generator>
<lastBuildDate>Sat, 11 Jul 2026 21:11:25 GMT</lastBuildDate>
<item>
  <title>CUDA Version Management</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/cuda.html</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<section id="problem" class="level2">
<h2 class="anchored" data-anchor-id="problem">Problem</h2>
<p>There are many libraries that only support specific versions of CUDA. Downgrading/upgrading CUDA can sometimes be tricky (especially downgrading). It’s often desirable to manage CUDA versions per project (instead of globally), without having to reach for Docker.</p>
</section>
<section id="solution" class="level2">
<h2 class="anchored" data-anchor-id="solution">Solution</h2>
<p>You can use <code>conda</code> to manage your CUDA versions! This allows you to isolate specific CUDA versions to specific environments rather than managing CUDA versions globally.</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">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>I’m using <a href="https://github.com/mamba-org/mamba">mamba</a> which has faster solvers than conda. Refer to <a href="https://mamba.readthedocs.io/en/latest/installation.html">the docs</a> for installation instructions.</p>
</div>
</div>
<p>Let’s say I want to downgrade to CUDA <code>11.7</code> in its own conda environment. First, I will create a new environment named <code>cuda11-7</code> with the following command:</p>
<div class="code-copy-outer-scaffold"><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="ex" style="color: null;
background-color: null;
font-style: inherit;">mamba</span> create <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n</span> cuda11-7 python=3.8</span>
<span id="cb1-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">mamba</span> activate cuda11-7</span></code></pre></div></div>
<p>Before I downgrade, we can check our CUDA version with the following command:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> nvcc <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">--version</span></span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">nvcc:</span> NVIDIA <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">R</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Cuda</span> compiler driver</span>
<span id="cb2-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Copyright</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2005-2022</span> NVIDIA Corporation</span>
<span id="cb2-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Built</span> on Wed_Sep_21_10:33:58_PDT_2022</span>
<span id="cb2-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Cuda</span> compilation tools, release 11.8, V11.8.89</span>
<span id="cb2-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Build</span> cuda_11.8.r11.8/compiler.31833905_0</span></code></pre></div></div>
<p>As you can see, I have CUDA version <code>11.8</code> but I want to downgrade to <code>11.7</code>. We can downgrade CUDA by using <a href="https://anaconda.org/nvidia/cuda-toolkit">cuda-toolkit</a>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">mamba</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-c</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nvidia/label/cuda-11.7.1"</span> cuda-toolkit</span></code></pre></div></div>
<p>This will take several minutes to complete. Next, recheck your CUDA version:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> nvcc <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">--version</span></span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">nvcc:</span> NVIDIA <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">R</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Cuda</span> compiler driver</span>
<span id="cb4-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Copyright</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2005-2022</span> NVIDIA Corporation</span>
<span id="cb4-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Built</span> on Wed_Jun__8_16:49:14_PDT_2022</span>
<span id="cb4-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Cuda</span> compilation tools, release 11.7, V11.7.99</span>
<span id="cb4-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Build</span> cuda_11.7.r11.7/compiler.31442593_0</span></code></pre></div></div>
<p>Next, you need to install the correct version of PyTorch for your CUDA version. It is crucial to install the right version of PyTorch that matches your CUDA version exactly. For example, if you want to install PyTorch with CUDA 11.7, you can use the following command:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">mamba</span> install pytorch torchvision torchaudio pytorch-cuda=11.7 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-c</span> pytorch <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-c</span> nvidia</span></code></pre></div></div>
<p>You can find PyTorch installation instructions <a href="https://pytorch.org/get-started/locally/">on this page</a>.</p>
<p>Viola! You have downgraded your CUDA version successfully. Note that this version of CUDA is isolated to this specific environment.</p>
<p>To make sure that everything is working correctly, make sure you can import torch and check the CUDA version from within Python:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> python <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-c</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"import torch; print(torch.version.cuda)"</span></span>
<span id="cb6-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">11.7</span></span></code></pre></div></div>
</section>
<section id="additional-resources" class="level2">
<h2 class="anchored" data-anchor-id="additional-resources">Additional Resources</h2>
<ul>
<li>Why does <code>nvcc --version</code> sometimes report a different CUDA version than <code>nvidia-smi</code>? See <a href="https://stackoverflow.com/a/53504578">this answer</a> on Stack Overflow.</li>
<li><a href="https://twitter.com/HamelHusain/status/1683868795532894209">Twitter discussion</a> on this topic.</li>
</ul>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/cuda.html</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Coding Agents</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/coding-agents/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-date-sort="1762066800000" data-listing-file-modified-sort="1762177930627" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="5" data-listing-word-count-sort="821" data-listing-title-sort="Amp" data-listing-filename-sort="amp.qmd">
<td>
<a href="../../notes/coding-agents/amp.html" class="title listing-title">Amp</a>
</td>
<td>
<span class="listing-description">Notes from reading the Amp manual</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/coding-agents/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Docker</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/docker/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p>Notes from the book <a href="https://www.manning.com/books/docker-in-action-second-edition?utm_source=google&amp;utm_medium=search&amp;utm_campaign=dynamicsearch&amp;gclid=CjwKCAjwmMX4BRAAEiwA-zM4JtyXLeFoALyh7xvEtg9B7nTbf3VeOFzo6Sdu119z94d6cll6XsbKgxoCRmMQAvD_BwE">Docker In Action</a></p>
<p><tocinline toc="{toc}">;</tocinline></p>
<section id="chapter-1" class="level1">
<h1>Chapter 1</h1>
<ul>
<li>Docker containers are faster than VMs to start, partly because they do NOT offer any hardware virtualization.
<ul>
<li>VMs provide hardware abstractions so you can run operating systems.</li>
</ul></li>
<li>Docker uses Linux <code>namespaces</code> and <code>cgropus</code>
<ul>
<li>Hamel: I don’t know what this is</li>
</ul></li>
</ul>
</section>
<section id="chapter-2" class="level1">
<h1>Chapter 2</h1>
<ul>
<li><p>Getting help:</p>
<ul>
<li><code>docker help cp</code></li>
<li><code>docker help run</code></li>
</ul></li>
<li><p>Linking containers: <code>docker run --link</code></p>
<ul>
<li>this is <a href="https://docs.docker.com/network/links/">apparently deprecated</a> per the docs</li>
<li>Opens a secure tunnel between two containers automatically</li>
<li>Also exposes environment variables and other things (see the docs)</li>
</ul></li>
<li><p><code>docker cp</code> copy files from a container to local filesystem</p></li>
<li><p>Detach an interactive container:</p>
<ul>
<li>Hold down <code>Control</code> and press <code>P</code> then <code>Q</code></li>
</ul></li>
<li><p>Get logs <code>docker logs &lt;container name&gt;</code></p>
<ul>
<li>Hamel: This is like <code>kubectl logs</code></li>
</ul></li>
<li><p>Run a new command in a running container <code>docker exec</code></p>
<ul>
<li><code>docker exec &lt;container_name&gt; ps</code> will run the <code>ps</code> command and emit that to stdout</li>
</ul></li>
<li><p>Rename a container with <code>docker rename &lt;current_name&gt; &lt;new_name&gt;</code></p></li>
<li><p><code>docker exec</code> run additional processes in an already running container</p></li>
<li><p><code>docker create</code> is the same as <code>docker run</code> except that the container is created in a stopped state.</p></li>
<li><p><code>docker run --read-only</code> allows you to run a container in a read only state, which you only need to do in special circumstances (you probably never need to use this). You can make exceptions to the read only constraint with the <code>-v</code> flag:</p></li>
</ul>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/docker/Docker-In-Action/6453FD28-1552-474C-9869-F6E01C6EC9C8.png" class="img-fluid"></p>
<ul>
<li>Override the entrypoint using the <code>--entrypoint</code> flag (this is discussed in part 2 of the book).</li>
</ul>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/docker/Docker-In-Action/276CD61C-3D6F-485A-8D88-8C2DD2EF8B5D.png" class="img-fluid"></p>
<section id="injecting-environment-variables" class="level3">
<h3 class="anchored" data-anchor-id="injecting-environment-variables">Injecting environment variables</h3>
<p>With the <code>--env</code> or <code>-e</code> flags.<br>
A nice trick to see all the environment variables in a docker container is to use the Unix command <code>env</code></p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/docker/Docker-In-Action/2070CA60-7C95-4BE8-B2C8-F68FF6B09C66.png" class="img-fluid"></p>
<p>Setting multiple environment variables: use <code>\</code> for multiline like this:</p>
<div class="code-copy-outer-scaffold"><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="ex" style="color: null;
background-color: null;
font-style: inherit;">docker</span> create <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-2">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--env</span> WORDPRESS_DB_HOST=<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>my database hostname<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--env</span> WORDPRESS_DB_USER=site_admin <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\</span></span>
<span id="cb1-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--env</span> WORDPRESS_DB_PASSWORD=MeowMix42 <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">\ </span></span>
<span id="cb1-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">wordpress:4</span></span></code></pre></div></div>
</section>
<section id="automatically-restarting-containers" class="level3">
<h3 class="anchored" data-anchor-id="automatically-restarting-containers">Automatically restarting containers</h3>
<p>Docker uses an exponential backoff strategy - double the previous time waiting until restarting.</p>
<p><code>docker run -d --restart always ...</code></p>
<p>See <a href="https://docs.docker.com/engine/reference/run/#restart-policies---restart">these restart policies</a></p>
<ul>
<li>no</li>
<li>on-failure[:max-retries]</li>
<li>always</li>
<li>unless-stopped</li>
</ul>
</section>
<section id="removing-containers-vs.-images" class="level3">
<h3 class="anchored" data-anchor-id="removing-containers-vs.-images">Removing containers vs.&nbsp;images</h3>
<p><strong>Containers are the actual instantiation of an image</strong>, just like how an object is an instantion of an instance of a class.</p>
<p><code>docker rm</code>: remove a container <code>docker rmi</code>: remove an image</p>
</section>
</section>
<section id="chapter-3" class="level1">
<h1>Chapter 3</h1>
<ul>
<li>Two ways to publish an image
<ul>
<li>Build locally, push image to registry</li>
<li>Make a <code>Dockerfile</code> and use DockerHub’s build system. <strong>This is preferred and considered to be safer, and DockerHub will mark your image as trusted if you do this</strong> because it is the only way to provide transparency to what is in your image.</li>
</ul></li>
<li>Search dockerhub by keyword , sorted descending by stars
<ul>
<li><code>docker search &lt;keyword&gt;</code></li>
<li>example: <code>docker search postgres</code></li>
</ul></li>
<li>Using Alternative registries
<ul>
<li><code>docker pull quay.io/dockerinaction/ch3_hello_registry:latest</code></li>
</ul></li>
</ul>
<section id="images-as-files" class="level3">
<h3 class="anchored" data-anchor-id="images-as-files">Images as files</h3>
<p>You can transport, save and load images as files! (You don’t have to push them to a registry).</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/docker/Docker-In-Action/AD7BCDC9-8130-45AE-89A9-DE5410EE845B.png" class="img-fluid"></p>
<p>You can then load the image:</p>
<p><code>docker load -i myfile.tar</code></p>
</section>
</section>
<section id="chapter-4-persistent-storage-.-shared-state-with-volumes" class="level1">
<h1>Chapter 4 Persistent Storage &amp;. Shared State with Volumes</h1>
<p><code>-v</code> and <code>--volume</code> are aliases</p>
<p><code>--volumes-from="&lt;container-name&gt;"</code> Mount all volumes from the given container</p>
<section id="different-kind-of-volumes" class="level3">
<h3 class="anchored" data-anchor-id="different-kind-of-volumes">Different kind of Volumes</h3>
<ol type="1">
<li>Bind mount - this is what you always use</li>
<li>Docker managed volume (2 kinds)
<ol type="1">
<li>Anonymous</li>
<li>Named volume (a special case of Anonymous)</li>
</ol></li>
</ol>
<p><a href="https://docs.docker.com/storage/volumes/">Use volumes | Docker Documentation</a> - Named vs.&nbsp;Anonymous volumes: <a href="https://medium.com/faun/what-are-anonymous-and-named-volumes-6cd787822a7d">article</a> - Hamel: maybe? You might use named volumes to persist data between containers.</p>
</section>
<section id="to-persist-data-with-named-volumes" class="level3">
<h3 class="anchored" data-anchor-id="to-persist-data-with-named-volumes">To persist data with named volumes</h3>
<p>Named volume is a kind of anonymous volume where the mount point is managed by Docker. Example of how you used a named volume:</p>
<ol type="1">
<li><p>Start container with a <strong>named volume</strong>: <code>docker run --name myDatabaseWithVolume -v appdata:/var/lib/mysql  mysql</code> save a table in the mysql database</p></li>
<li><p>Start a new container with the same <strong>named volume</strong> <code>docker run --name myDatabaseWithVolume2 -v appdata:/var/lib/mysql mysql</code> You should be able to see the same table you created in the last container b/c data has been persisted.</p></li>
</ol>
</section>
<section id="see-where-docker-anonymous-volumes-store-information" class="level3">
<h3 class="anchored" data-anchor-id="see-where-docker-anonymous-volumes-store-information">See where Docker anonymous volumes store information</h3>
<p>Unlike a bind mount, where you explicitly name the host location, docker will manage the storage location of anonymous volumes. But how do you know where the files are stored on the host?</p>
<p>You can use <code>docker inspect</code> command filtered for the <code>Volumes</code> key to find the storage location on the host.</p>
<p>Create a container with an anonymous volume. <code>docker run -v /some/location --name cass-shared alpine</code></p>
<p><code>docker inspect -f "{{json .Volumes}}" cass-shared</code></p>
<p>This will output a json blob which will show the mount points.</p>
</section>
<section id="other-things-you-didnt-know-about-volumes" class="level3">
<h3 class="anchored" data-anchor-id="other-things-you-didnt-know-about-volumes">Other things you didn’t know about volumes</h3>
<ul>
<li>when you mount a volume, it overrides any files already at that location
<ul>
<li>You can mount specific files which avoid this</li>
<li>if you specify a host directory that doesn’t exist Docker will create it for you
<ul>
<li>exception: If you are mounting a file instead of a directory and it doesn’t exist on the host, Docker will throw an error</li>
</ul></li>
</ul></li>
<li>you can mount a volume as read only <code>-v /source:/destination:ro</code>
<ul>
<li>see docs (there is this optional third argument for volumes)</li>
</ul></li>
</ul>
</section>
<section id="the-volumes-from-flag" class="level3">
<h3 class="anchored" data-anchor-id="the-volumes-from-flag">The <code>volumes-from</code> flag</h3>
<p>Allows you to share volumes with another container. When you use this flag, the same volumes are mounted into your container at the same location.</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/docker/Docker-In-Action/6B5A3266-48E5-4A8F-9051-651971AD8824.png" class="img-fluid"></p>
<p>Volumes are copied transitively, so this will automatically mount volumes that are also mounted this way from another container.</p>
<p><strong>Caveats</strong> - You cannot mount a shared volume to a different location within a container. This is a limitation of <code>--volumes-from</code> - If you have a collision in the destination mount point among several <code>volumes-from</code> only one volume will survive, which you can ascertain from <code>docker inpsect</code> - see above for how to use <code>docker inspect</code> - You cannot change the write permission of the volume, you inherit whatever the permission is in the source container.</p>
</section>
<section id="cleaning-up-volumes" class="level3">
<h3 class="anchored" data-anchor-id="cleaning-up-volumes">Cleaning up volumes</h3>
<p><code>-v</code> flag</p>
<p><code>docker rm -v</code> will delete any managed volumes referenced by the target container</p>
<p>However, if you delete all containers but forget a <code>-v</code> flag you will be left with an <strong>orphaned volume</strong>. This is bad b/c it takes up disk space until cleaned up. You have to run complicated cleanup steps to get rid of orphans.</p>
<p>Solution: There is none, <strong>its a good habit to use -v anytime you call docker rm</strong></p>
<p>Hamel: this means that- - Don’t use managed volumes unless you really need it - If you do use them, try to include makefiles that include <code>-v</code> as a part of things</p>
</section>
<section id="advanced-volume-stuff" class="level3">
<h3 class="anchored" data-anchor-id="advanced-volume-stuff">Advanced Volume Stuff</h3>
<ul>
<li>You can have a volume container p.&nbsp;72 so that you can reference <code>--volume-from</code> from all your containers.<br>
</li>
<li>Data-paced volume containers, you can pre-load volume containers with data p.&nbsp;73</li>
<li>You can change the behavior of currently running containers by mounting configuration files and application in volumes. In a way, Hamel</li>
</ul>
</section>
</section>
<section id="chapter-5-single-host-networking" class="level1">
<h1>Chapter 5 Single Host Networking</h1>
<ul>
<li>Terminology:
<ul>
<li>protocols: tcp, http</li>
<li>interfaces: IP addresses</li>
<li>ports: you know what this means
<ul>
<li>Customary ports:
<ul>
<li>HTTP: 80</li>
<li>MySQL: 3306</li>
<li>Memcached: 11211</li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<p>Discuss advanced networking and creating a network using the <code>docker network</code> command. Hamel: I don’t see an immediate use for this.</p>
<ul>
<li>Special container networks:
<ul>
<li><code>host</code>
<ul>
<li><code>docker run --network host</code> allows you to pretend like the host is your local machine, and you can expose any port and that will bind to the host.</li>
</ul></li>
<li><code>none</code>
<ul>
<li><code>docker run --network none</code> closes all connection to the outside world. This is useful for security.</li>
</ul></li>
</ul></li>
</ul>
<section id="exposing-ports" class="level3">
<h3 class="anchored" data-anchor-id="exposing-ports">exposing ports</h3>
<p><code>-p 8080</code> This binds port 8080 to a <strong>random</strong> port on the host! you can find the port that the container is bound to by <code>docker port &lt;image name&gt;</code> example: <code>docker run -p 8080 --name listener alpine</code> <code>docker port listener</code></p>
<p>This will give you output that looks like <code>container --&gt; host</code> (which is reverse the other nomenclature of <code>host:container</code></p>
<p><code>-p 8080:8080</code> this binds the container’s port to the host’s port 8080</p>
<p><code>-p 0.0.0.0:8080:8080/tcp</code> same as above but specifies the interface and the tcp protocol.</p>
<p>Syntax is <code>-p &lt;host-interface&gt;:&lt;host-port&gt;:&lt;target-port&gt;/&lt;protocol&gt;</code></p>
</section>
</section>
<section id="chapter-6-isolation" class="level1">
<h1>Chapter 6 Isolation</h1>
<section id="limit-resources-memory-cpu" class="level3">
<h3 class="anchored" data-anchor-id="limit-resources-memory-cpu">Limit resources: Memory, CPU,</h3>
<ul>
<li><code>-m</code> or <code>--memory</code>
<ul>
<li>number, where unit = b, k, m or g</li>
<li>memory limits are not reservations, just caps</li>
</ul></li>
<li><code>--cpu-shares</code>
<ul>
<li>is a weight you set that is used to calculate % of CPU usage allowed</li>
<li>% is calculated as weight / (sum of all weights)</li>
<li>only enforced when there is contention for a CPU</li>
</ul></li>
<li><code>--cpuset-cpus</code> : limits process to a specific CPU
<ul>
<li><code>docker run -d --cpuset-cpus 0</code> Restricts to CPU number 0</li>
<li>Can specify a list or <code>0,1,2</code> or a range <code>0-2</code></li>
</ul></li>
<li><code>--device</code>
<ul>
<li>mount your webcam: <code>docker run --device /dev/video0:/dev/video0</code></li>
</ul></li>
<li>Shared memory : Hamel this was too advanced for me</li>
</ul>
</section>
<section id="running-as-a-user" class="level3">
<h3 class="anchored" data-anchor-id="running-as-a-user">Running as a user</h3>
<ul>
<li>You can only inspect the default run-as User by creating or pulling the image
<ul>
<li>see p.&nbsp;113</li>
</ul></li>
<li>Change run-as user
<ul>
<li><code>docker run --user nobody</code></li>
<li><strong>The user has to exist in the image when doing this or you will get an error</strong>. The user will not be created automatically for you.</li>
<li>See available users:
<ul>
<li><code>docker run --rm busybox:latest awk -F: '$0=$1' /etc/passwd</code></li>
</ul></li>
</ul></li>
</ul>
</section>
<section id="privileged-containers-try-not-to-do-this" class="level3">
<h3 class="anchored" data-anchor-id="privileged-containers-try-not-to-do-this">Privileged Containers: TRY NOT TO DO THIS</h3>
<ul>
<li>This is how you run Docker-in-Docker</li>
<li>Priviliged containers <strong>have root privileges on the host</strong>.<br>
</li>
<li><code>--privilged</code> on <code>docker create</code> or <code>docker run</code></li>
</ul>
</section>
</section>
<section id="chapter-7-packaging-software" class="level1">
<h1>Chapter 7 packaging software</h1>
<p>Aside: cleaning up your docker environment</p>
<p><code>docker image prune -a</code> and <code>docker container prune</code></p>
<section id="recovering-changes-to-a-stopped-container" class="level3">
<h3 class="anchored" data-anchor-id="recovering-changes-to-a-stopped-container">Recovering changes to a stopped container</h3>
<p>I always thought you have to commit changes in order to preserve changes to an image you made in a container. This is not true (although committing changes is a good idea).</p>
<p><strong>Any changes you make to a container is saved even if the container is exited</strong></p>
<p>To recover changes to a container</p>
<ol type="1">
<li>Find the container (if you didn’t name it with <code>docker run --name</code> it will be named for you), using <code>docker ps -a</code></li>
<li>Start the container using <code>docker start -ai &lt;container_name&gt;</code> the <code>-ai</code> flags mean to attach and run interactively</li>
<li>Now you are in the container you can verify that everything you installed is still there!</li>
</ol>
<p>Note: if you run your container initially with <code>docker run --rm</code> this automatically removes your container upon exit, so this might not be recommended as your changes are not recoverable if you forget to commit</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/docker/Docker-In-Action/D79BAEDA-4071-4040-8B7B-2B864588FA9E.png" class="img-fluid"></p>
</section>
<section id="seeing-changes-to-a-container-from-the-base-image" class="level3">
<h3 class="anchored" data-anchor-id="seeing-changes-to-a-container-from-the-base-image">Seeing changes to a container from the base image</h3>
<p><code>docker diff &lt;container name&gt;</code> will output a long list of of file changes: - A: file added - D: file deleted - C: file changed</p>
</section>
<section id="other-tricks" class="level3">
<h3 class="anchored" data-anchor-id="other-tricks">Other tricks</h3>
<p>You can override the entry point to the container <strong>permanently</strong> by using the <code>--entrypoint</code> flag: <code>docker run --entrypoint</code></p>
</section>
<section id="understanding-images-layers" class="level3">
<h3 class="anchored" data-anchor-id="understanding-images-layers">Understanding Images &amp; Layers</h3>
<ul>
<li>files are stored in a Union file system, so they are stored in specific layers. The file system you are seeing as an end user are a union of all the layers. Each time a change is made to a union file system, that change is recorded on a new layer on top of all of the others. The “union” of all of those layers, or top-down view, is what the container (and user) sees when accessing the file system.
<ul>
<li>This means <strong>if you are not careful you can bloat the file system by making a bunch of unnecessary changes to add/delete files.</strong></li>
</ul></li>
<li><code>docker commit</code> commits the top-layer changes to an image, meaning all the files changes are saved.</li>
</ul>
<p><strong>See image size with</strong></p>
<p><code>docker images</code>. Even though you remove a file, the image size will increase! This is because of the Union File System</p>
<p><strong>See size of all layers</strong></p>
<p><code>docker history &lt;image name&gt;</code></p>
<p><strong>flatten an image</strong> This is kind of complicated, you can do this by exporting and importing the filesystem into a base image See pg. 140. BUT there is an experimental feature called <code>docker build --squash -t &lt;image&gt; .</code>You can enable experimental features by following these instructions: <a href="https://docs.docker.com/engine/reference/commandline/dockerd/#description">dockerd Docker Documentation</a>. For Mac, you can turn on experimental features by setting <code>experimental: true</code> in `settings&gt; Command Line &gt; enable experimental</p>
</section>
</section>
<section id="chapter-8-build-automation" class="level1">
<h1>Chapter 8 Build Automation</h1>
<ul>
<li>use <code>.dockerignore</code> to prevent certain files from being copied</li>
<li>You can set multiple environment variables at once in Dockerfile</li>
<li>You can use environment variables in the <code>LABEL</code> command
<ul>
<li>The metadata makes it clear that the environment variable substitution works. You can use this form of substitution in the ENV, ADD, COPY, WORKDIR, VOLUME, EXPOSE, and USER instructions.</li>
</ul></li>
</ul>
<pre class="docker"><code>ENV APPROOT "/app" APP "mailer.sh" VERSION "0.6"
LABEL base.name "Mailer Archetype" base.version "${VERSION}"</code></pre>
<ul>
<li>view metadata using the command <code>docker inspect &lt;image name&gt;</code></li>
</ul>
<section id="entrypoint-something-arugment-vs.-entrypoint-something-argument" class="level3">
<h3 class="anchored" data-anchor-id="entrypoint-something-arugment-vs.-entrypoint-something-argument">ENTRYPOINT something arugment vs.&nbsp;ENTRYPOINT [“something”, “argument”]</h3>
<p><strong>TLDR; use the ugly list approach</strong></p>
<p>There are two instruction forms <strong>shell form</strong> and <strong>exec form</strong> <a href="https://stackoverflow.com/questions/42805750/dockerfile-cmd-shell-versus-exec-form">docker - Dockerfile CMD shell versus exec form - Stack Overflow</a></p>
<p>The ENTRYPOINT instruction has two forms: the shell form and an exec form. The shell form looks like a shell command with whitespace-delimited arguments. The exec form is a string array where the first value is the command to execute and the remaining values are arguments. .</p>
<p><strong>Most importantly, if the shell form is used for ENTRYPOINT, then all other arguments provided by the CMD instruction or at runtime as extra arguments to docker run will be ignored. This makes the shell form of ENTRYPOINT less flexible.</strong></p>
<p>Other commands can use the <strong>exec form</strong> too! You must use the exec form when any of the arguments contain a whitespace:</p>
<pre class="docker"><code>FROM dockerinaction/mailer-base:0.6 
COPY ["./log-impl", "${APPROOT}"] 
RUN chmod a+x ${APPROOT}/${APP} &amp;&amp; \ chown example:example /var/log 
USER example:example 
VOLUME ["/var/log"]  # each value in this array will be created as a new volume definition
CMD ["/var/log/mailer.log"]</code></pre>
<p>Note: you usually don’t want to specify a volume at build time.</p>
</section>
<section id="cmd-vs.-entrypoint-you-should-really-try-to-always-use-both" class="level3">
<h3 class="anchored" data-anchor-id="cmd-vs.-entrypoint-you-should-really-try-to-always-use-both">CMD vs.&nbsp;ENTRYPOINT (You should really try to always use both!)</h3>
<p>CMD is actually an argument list for the <code>ENTRYPOINT</code>.</p>
<ul>
<li>Logically when you run a container it runs as <code>&lt;default shell program&gt; ENTRYPOINT CMD</code></li>
<li>You can override the <code>ENTRYPOINT</code> with <code>docker run --entrypoint</code>, and you can override commands by just passing commands to docker run : <code>docker run &lt;image name&gt; &lt;command&gt;</code></li>
</ul>
<pre class="docker"><code>FROM ubuntu

ENTRYPOINT [ "ls" ]
CMD ["-lah"]</code></pre>
<p>As you can see using ENTRYPOINT as well as CMD separately provides your downstream users with the most flexibility.</p>
</section>
<section id="copy-vs-add" class="level3">
<h3 class="anchored" data-anchor-id="copy-vs-add">COPY vs ADD</h3>
<p>Use COPY. ADD has additional functionality like ability to download from urls and decompress files, which proved opaque over time and you shouldn’t use it.</p>
</section>
<section id="onbuild" class="level3">
<h3 class="anchored" data-anchor-id="onbuild">ONBUILD</h3>
<p>The ONBUILD instruction defines instructions to execute if the resulting image is used as a base for another build. those ONBUILD instructions are executed after the FROM instruction and before the next instruction in a Dockerfile.</p>
<pre class="docker"><code>FROM busybox:latest 
WORKDIR /app RUN touch /app/base-evidence 
ONBUILD RUN ls -al /app</code></pre>
</section>
<section id="other-stuff" class="level3">
<h3 class="anchored" data-anchor-id="other-stuff">Other Stuff</h3>
<ul>
<li>You should always validate the presence of required environment variables in a startup shell script like <code>entrypoint.sh</code></li>
</ul>
</section>
<section id="docker-digests" class="level3">
<h3 class="anchored" data-anchor-id="docker-digests">Docker Digests</h3>
<p>Reference the exact SHA of a Container which is the only way to guarantee the image you are referencing has not changed. @ symbol followed by the digest.</p>
<p>Hamel: doesn’t look like a good way to find history of digests, but you can see the current SHA when you use <code>docker pull</code> , you can see the SHA as well if you call <code>docker images --digests</code></p>
<pre class="docker"><code>FROM debian@sha256:d5e87cfcb730...</code></pre>
</section>
</section>
<section id="chapter-10-skipped-ch-9" class="level1">
<h1>Chapter 10 (skipped Ch 9)</h1>
<ul>
<li>You can run your own customized registry. Simplest version can be hosted from a Docker Container!</li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># start a local registry on port 5000</span></span>
<span id="cb7-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">docker</span> run <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--name</span> personal_registry</span>
<span id="cb7-3"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">\ -p</span> 5000:5000 <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--restart</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>always </span>
<span id="cb7-4"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">\ registry:2</span></span>
<span id="cb7-5"></span>
<span id="cb7-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># push an image to the registry (using the same image that created the registry for convenience)</span></span>
<span id="cb7-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">docker</span> tag registry:2 localhost:5000/distribution:2 </span>
<span id="cb7-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">docker</span> push localhost:5000/distribution:2</span></code></pre></div></div>
<p>Note that <code>docker push</code> syntax is actually <code>docker push &lt;registry url&gt;/org/repo</code></p>
<p>This chapter discusses many more things which are skipped: - Centralized registries - Enhancements - Durable blog storage - Integrating through notifications</p>
</section>
<section id="chapter-11-docker-compose" class="level1">
<h1>Chapter 11 Docker Compose</h1>
<p>Docker compose for fastpages:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"3"</span></span>
<span id="cb8-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">services</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-3"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fastpages</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 class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&amp;fastpages</span></span>
<span id="cb8-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">working_dir</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;"> /data</span></span>
<span id="cb8-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">environment</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </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;"> INPUT_BOOL_SAVE_MARKDOWN=false</span></span>
<span id="cb8-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">context</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;"> ./_action_files</span></span>
<span id="cb8-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">dockerfile</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;"> ./Dockerfile</span></span>
<span id="cb8-10"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">image</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;"> fastpages-dev</span></span>
<span id="cb8-11"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">logging</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-12"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">driver</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;"> json-file</span></span>
<span id="cb8-13"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">options</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-14"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">max-size</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;"> 50m</span></span>
<span id="cb8-15"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">stdin_open</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 class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">true</span></span>
<span id="cb8-16"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tty</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 class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">true</span></span>
<span id="cb8-17"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">volumes</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-18"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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;"> .:/data/</span></span>
<span id="cb8-19"></span>
<span id="cb8-20"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">converter</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-21"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">&lt;&lt;</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 class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">*fastpages</span></span>
<span id="cb8-22"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">command</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;"> /fastpages/action_entrypoint.sh</span></span>
<span id="cb8-23"></span>
<span id="cb8-24"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">watcher</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-25"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">&lt;&lt;</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 class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">*fastpages</span></span>
<span id="cb8-26"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">command</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;"> watchmedo shell-command --command /fastpages/action_entrypoint.sh --pattern *.ipynb --recursive --drop</span></span>
<span id="cb8-27"></span>
<span id="cb8-28"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">jekyll</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-29"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">working_dir</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;"> /data</span></span>
<span id="cb8-30"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">image</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;"> hamelsmu/fastpages-jekyll</span></span>
<span id="cb8-31"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">restart</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;"> unless-stopped</span></span>
<span id="cb8-32"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ports</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-33"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4000:4000"</span></span>
<span id="cb8-34"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">volumes</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb8-35"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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;"> .:/data/</span></span>
<span id="cb8-36"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">    command</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">: </span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb8-37">     bash -c "gem install bundler</span>
<span id="cb8-38">     &amp;&amp; jekyll serve --trace --strict_front_matter"</span></code></pre></div></div>
<p>The above uses YAML anchors: <a href="https://confluence.atlassian.com/bitbucket/yaml-anchors-960154027.html">YAML anchors - Atlassian Documentation</a></p>
<p>Start a particular service: <code>docker-compose up &lt;service name&gt;</code> Rebuild a service <code>docker-compose build &lt;service name&gt;</code></p>
<p>You can express dependencies with <code>depends_on</code> which is useful for compose to know which services to restart or start in a specified order.</p>
<p>See examples of Docker Compose files on p 243</p>
<section id="scaling-up-wdocker-compose" class="level3">
<h3 class="anchored" data-anchor-id="scaling-up-wdocker-compose">Scaling Up w/Docker Compose</h3>
<p>That’s right you don’t need docker swarm. This example uses <a href="https://github.com/dockerinaction/ch11_coffee_api/blob/master/docker-compose.yml">ch11_coffee_api/docker-compose.yml at master · dockerinaction/ch11_coffee_api · GitHub</a></p>
<ol type="1">
<li>Get list of containers that are currently providing the service.</li>
</ol>
<p><code>docker-compose ps coffee</code></p>
<pre><code>          Name                 Command       State            Ports
----------------------------------------------------------------------------
ch11_coffee_api_coffee_1   ./entrypoint.sh   Up      0.0.0.0:32768-&gt;3000/tcp</code></pre>
<ol start="2" type="1">
<li>Scale it up with <code>docker-compose up --scale</code></li>
</ol>
<p><code>docker-compose up --scale coffee=5</code></p>
<p>When you run <code>docker-compose ps coffee</code>:</p>
<pre><code>docker-compose ps coffee                                                                                                                         ✔
          Name                 Command       State            Ports
----------------------------------------------------------------------------
ch11_coffee_api_coffee_1   ./entrypoint.sh   Up      0.0.0.0:32768-&gt;3000/tcp
ch11_coffee_api_coffee_2   ./entrypoint.sh   Up      0.0.0.0:32769-&gt;3000/tcp
ch11_coffee_api_coffee_3   ./entrypoint.sh   Up      0.0.0.0:32771-&gt;3000/tcp
ch11_coffee_api_coffee_4   ./entrypoint.sh   Up      0.0.0.0:32770-&gt;3000/tcp
ch11_coffee_api_coffee_5   ./entrypoint.sh   Up      0.0.0.0:32772-&gt;3000/tcp</code></pre>
<p>Note that the coffee service binds to port <code>0</code> on your host, which is an <strong>ephemeral port</strong>, which just means that your host machine assigns the service to a random port. This is required if you plan on using <code>docker compose up --scale</code></p>
<p>The service was bound to port 0 on the host with</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">coffee</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb11-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">build</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;"> ./coffee</span></span>
<span id="cb11-3"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">user</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;"> 777:777</span></span>
<span id="cb11-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">restart</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;"> always</span></span>
<span id="cb11-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">expose</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb11-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3000</span></span>
<span id="cb11-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ports</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb11-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"0:3000"</span></span>
<span id="cb11-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span></code></pre></div></div>
<ol start="3" type="1">
<li>Load balancer</li>
</ol>
<p>Problem with this kind of scaling is you don’t know the ports in advance , and you don’t want to hit these individual endpoints, you need a load balancer. This <a href="https://pspdfkit.com/blog/2018/how-to-use-docker-compose-to-run-multiple-instances-of-a-service-in-development/#adding-a-load-balancer">blog post</a> shows you how to luse NGINX as a load balancer.</p>
<p>You will need something like this in your compose file</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb12-1"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">nginx</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-2"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">image</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;"> nginx:latest</span></span>
<span id="cb12-3"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">volumes</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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;"> ./nginx.conf:/etc/nginx/nginx.conf:ro</span></span>
<span id="cb12-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">depends_on</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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;"> pspdfkit</span></span>
<span id="cb12-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ports</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4000:4000"</span></span></code></pre></div></div>
</section>
<section id="templating-docker-compose-files" class="level3">
<h3 class="anchored" data-anchor-id="templating-docker-compose-files">Templating Docker Compose Files</h3>
<p>You can read about this here: <a href="https://docs.docker.com/compose/extends/">Share Compose configurations between files and projects | Docker Documentation</a>, allows you to override certain things from a base compose file.</p>
</section>
</section>
<section id="chapter-12-clusters-wmachine-swarm" class="level1">
<h1>Chapter 12 Clusters w/Machine &amp; Swarm</h1>
<p>Hamel: I skipped this completely</p>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/docker/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>FastHTML</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-date-sort="1748502000000" data-listing-file-modified-sort="1752533266478" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="4" data-listing-word-count-sort="716" data-listing-title-sort="Building Annotation Apps with FastHTML" data-listing-filename-sort="annotation-apps.qmd">
<td>
<a href="../../notes/fasthtml/annotation-apps.html" class="title listing-title">Building Annotation Apps with FastHTML</a>
</td>
<td>
<span class="listing-description">Notes from Isaac’s talk on building annotation apps in FastHTML</span>
</td>

</tr>

<tr data-index="1" data-listing-date-sort="1728630000000" data-listing-file-modified-sort="1752533266478" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="4" data-listing-word-count-sort="647" data-listing-title-sort="Concurrency For Starlette Apps (e.g FastAPI / FastHTML)" data-listing-filename-sort="concurrency.ipynb">
<td>
<a href="../../notes/fasthtml/concurrency.html" class="title listing-title">Concurrency For Starlette Apps (e.g FastAPI / FastHTML)</a>
</td>
<td>
<span class="listing-description">Concurreny fundamentals for Python web apps</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/fasthtml/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>GitHub Actions</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/actions/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table caption-top">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">Title</th>
<th data-quarto-table-cell-role="th">Description</th>
</tr>
</thead>
<tbody class="list">
</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/actions/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>How to learn</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/how-to-learn/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<section id="mindshift" class="level1">
<h1>Mindshift</h1>
<p>I read the book <a href="https://www.amazon.com/Mindshit-Obstacles-Learning-Discover-Potential/dp/1101982853">Mindshift</a> and it was unituitively so good that I decided to take this class. As a parent, I learned a bunch of things that I think will be beneficial to my children’s education.</p>
<p>Notes from class <a href="https://www.coursera.org/learn/learning-how-to-learn">Learning how to learn</a>. These notes are for me and may not make sense for others.</p>
<section id="focused-vs-diffused-mode" class="level2">
<h2 class="anchored" data-anchor-id="focused-vs-diffused-mode">Focused vs Diffused Mode</h2>
<p>You can not access focus and diffused mode simultaneously.</p>
<p>People have tried to access diffuse mode of thinking by bringing themselves to the point of sleep and waking up just as they fall asleep. For example, Salvador Dali - holding keys in your hand, and let the sound of keys falling the ground wake you up.</p>
<p>Exercise, going for a walk good way to access diffuse thinking. You must take notes right away b/c diffuse thoughts may evaporate very fast.</p>
</section>
<section id="procrastination-memory-and-sleep" class="level2">
<h2 class="anchored" data-anchor-id="procrastination-memory-and-sleep">Procrastination Memory and Sleep</h2>
<p>They advocate the Pomodoro technique to combating procrastination. Its like HITT.</p>
<p>Periodic relaxation (every ~ 30 minutes) is important for accessing your diffuse mode. “Its important for the mortar to dry”.</p>
<p>Spaced repetition (like Anki) is important for building memory. i</p>
<p><strong>Go over what you want to learn about right before you go to sleep</strong>, this will substantially improve the chances you will dream about it and form new connections about the subject.</p>
<p>Exercise can help create new neurons in your hippocampus (new neurons can be created there in adulthood) and help them survive longer.</p>
</section>
<section id="writing-tips-diffuse-mode" class="level2">
<h2 class="anchored" data-anchor-id="writing-tips-diffuse-mode">Writing Tips Diffuse Mode</h2>
<p>Diffuse mode is very important for writing. Editing is like focus mode and creating ideas is diffuse mode. Some rules of thumb: - Do not outline, make a mind map - Do not edit while you are writing (this is really hard to do -&gt; turn off monitor and just write).https://writeordie.com - app that forces you to stay in diffuse mode. You really cannot look at the screen. - Repeating again, do not look at screen while you are writing! Only when editing.</p>
</section>
<section id="chunking" class="level2">
<h2 class="anchored" data-anchor-id="chunking">Chunking</h2>
<p>“Tying your shoes”. Best chunks are subconscious. Spoken language is the best example of chunking. You have to practice to build chunks, you cannot just observe. You have to perform the task yourself.</p>
<p>You should scan a chapter before you read it: section headings, pictures, etc. This can help you build chunks.</p>
</section>
<section id="illusions-of-competence" class="level2">
<h2 class="anchored" data-anchor-id="illusions-of-competence">Illusions of competence</h2>
<p>Right after you read something, look away and repeat to yourself what you recall. You can also draw a concept map. The recall process actually improves memory.</p>
<p>Recall is better than re-reading. Re-reading is effective when you let time pass so you get spaced repetition. You need to test yourself to make sure you are competent. Recall is a form of testing.</p>
<p>Recall outside your place of study to strengthen your memory. This is because you can get queues from where you are studying.</p>
</section>
<section id="deliberate-practice" class="level2">
<h2 class="anchored" data-anchor-id="deliberate-practice">Deliberate Practice</h2>
<p>Focus on the bits that you find difficult. Interleaving is important, meaning learning different subjects or even sections within one subject at once. Thomas S. Khun discovered that two types of people tend to make scientific breakthroughs: (1) young people (2) those who are trained in another discipline.</p>
</section>
<section id="procrastination-and-memory" class="level2">
<h2 class="anchored" data-anchor-id="procrastination-and-memory">Procrastination and Memory</h2>
<p>You have already learned about the Pomodoro technique. There are other techniques.</p>
<p>Focus on the process, not the product. Don’t focus on completing the homework, focus on the process that leads you to complete the homework. Process is the small chunks of time to chip away at the task. This is the idea behind the Pomodoro. Your only goal is to finish the Pomodoro, for example.</p>
</section>
<section id="juggling-life-and-learning" class="level2">
<h2 class="anchored" data-anchor-id="juggling-life-and-learning">Juggling Life and Learning</h2>
<p>You should make to-do list the night before for the next day and write it down. This will allow your subconscious to work on how it will conquer that task. Furthermore, writing it down will allow you to free it from working memory.</p>
<p>Plan your quitting time is important.</p>
</section>
</section>
<section id="ultralearning" class="level1">
<h1>Ultralearning</h1>
<p>Notes from the book <a href="https://a.co/d/iAK87J4">Ultralearning</a></p>
<ol type="1">
<li>Metalearning - draw a map of what you want to learn.</li>
<li>Metalinguistic awareness - learn js, os</li>
<li>Project based (learn by doing)+ drills on weaknesses</li>
<li>50-60 min learning per day</li>
<li>Learn my emulation</li>
<li>Cold retrieval is best. “Rewrite notebook from memory”</li>
<li>Fast feedback, hopefully corrective/meta</li>
<li>Build intuition by anchoring to your own example, visualization</li>
<li>Explain it to someone who has no expertise (Feynman), write about it.</li>
<li>Experiment with learning
<ol type="1">
<li>Copy -&gt; Create</li>
<li>Compare methods</li>
<li>Explore extremes (move to country to learn language, take test first, etc)</li>
</ol></li>
<li>Pick difficult projects that are a leap above your abilities</li>
<li>Competition: do something unique that you cannot compare to others, but after sufficient competency, compete!</li>
</ol>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/how-to-learn/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Jupyter</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/jupyter/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-file-modified-sort="1752533266484" data-listing-reading-time-sort="1" data-listing-word-count-sort="23" data-listing-title-sort="Fix Jupyter CUDA cache" data-listing-filename-sort="Fix Jupyter CUDA cache.qmd">
<td>
<a href="../../notes/jupyter/Fix Jupyter CUDA cache.html" class="title listing-title">Fix Jupyter CUDA cache</a>
</td>
<td>
<span class="listing-description">A situation where you get GPU OOM in Jupyter</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/jupyter/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>K8s</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/k8s/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-categories="Szhz" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="13" data-listing-word-count-sort="2544" data-listing-title-sort="Basics" data-listing-filename-sort="02-Basics.qmd">
<td>
<a href="../../notes/k8s/02-Basics.html" class="title listing-title">Basics</a>
</td>
<td>
<span class="listing-description">K8s fundamentals</span>
</td>

</tr>

<tr data-index="1" data-categories="Szhz" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="11" data-listing-word-count-sort="2059" data-listing-title-sort="Secrets" data-listing-filename-sort="03-Secrets.qmd">
<td>
<a href="../../notes/k8s/03-Secrets.html" class="title listing-title">Secrets</a>
</td>
<td>
<span class="listing-description">How to handle secrets in K8s</span>
</td>

</tr>

<tr data-index="2" data-listing-file-modified-sort="1752533266509" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Storage" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/k8s/storage/index.html" class="title listing-title">Storage</a>
</td>
<td>
<span class="listing-description">Notes on pod storage</span>
</td>

</tr>

<tr data-index="3" data-listing-file-modified-sort="1752533266507" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Scaling" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/k8s/scaling/index.html" class="title listing-title">Scaling</a>
</td>
<td>
<span class="listing-description">How to horizontally scale resources</span>
</td>

</tr>

<tr data-index="4" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="6" data-listing-word-count-sort="1154" data-listing-title-sort="StatefulSet" data-listing-filename-sort="12-StatefulSet.qmd">
<td>
<a href="../../notes/k8s/12-StatefulSet.html" class="title listing-title">StatefulSet</a>
</td>
<td>
<span class="listing-description">A special kind of controller for Pods</span>
</td>

</tr>

<tr data-index="5" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="4" data-listing-word-count-sort="658" data-listing-title-sort="Jobs &amp; CronJobs" data-listing-filename-sort="13-JobsCron.qmd">
<td>
<a href="../../notes/k8s/13-JobsCron.html" class="title listing-title">Jobs &amp; CronJobs</a>
</td>
<td>
<span class="listing-description">Ad-hoc and scheduled workloads</span>
</td>

</tr>

<tr data-index="6" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="4" data-listing-word-count-sort="652" data-listing-title-sort="Rollouts" data-listing-filename-sort="14-RolloutsRollbacks.qmd">
<td>
<a href="../../notes/k8s/14-RolloutsRollbacks.html" class="title listing-title">Rollouts</a>
</td>
<td>
<span class="listing-description">The mechanics of what happens when you update a Podspec or create a deployment.</span>
</td>

</tr>

<tr data-index="7" data-listing-file-modified-sort="1752533266503" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Helm" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/k8s/helm/index.html" class="title listing-title">Helm</a>
</td>
<td>
<span class="listing-description">Helm Charts</span>
</td>

</tr>

<tr data-index="8" data-listing-file-modified-sort="1752533266506" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Multi-Container Pods" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/k8s/multi_container_pods/index.html" class="title listing-title">Multi-Container Pods</a>
</td>
<td>
<span class="listing-description">Notes on multi-container pods</span>
</td>

</tr>

<tr data-index="9" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="6" data-listing-word-count-sort="1077" data-listing-title-sort="Developer tips" data-listing-filename-sort="18-Developer.qmd">
<td>
<a href="../../notes/k8s/18-Developer.html" class="title listing-title">Developer tips</a>
</td>
<td>
<span class="listing-description">Tips on working with Kubernetes.</span>
</td>

</tr>

<tr data-index="10" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="3" data-listing-word-count-sort="493" data-listing-title-sort="Pod restart vs. replacement" data-listing-filename-sort="19-Pod-Lifecycle.qmd">
<td>
<a href="../../notes/k8s/19-Pod-Lifecycle.html" class="title listing-title">Pod restart vs.&nbsp;replacement</a>
</td>
<td>
<span class="listing-description">What’s the difference b/w a restart and a replacement?</span>
</td>

</tr>

<tr data-index="11" data-listing-file-modified-sort="1752533266485" data-listing-reading-time-sort="5" data-listing-word-count-sort="948" data-listing-title-sort="Probes" data-listing-filename-sort="20-Health-Check.qmd">
<td>
<a href="../../notes/k8s/20-Health-Check.html" class="title listing-title">Probes</a>
</td>
<td>
<span class="listing-description">Understand readiness and liveness probes, and how that iteracts with Helm to protect you against…</span>
</td>

</tr>

<tr data-index="12" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="2" data-listing-word-count-sort="258" data-listing-title-sort="Requesting resources" data-listing-filename-sort="22a-Resource-Requests.qmd">
<td>
<a href="../../notes/k8s/22a-Resource-Requests.html" class="title listing-title">Requesting resources</a>
</td>
<td>
<span class="listing-description">How to request resources for your workloads</span>
</td>

</tr>

<tr data-index="13" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="5" data-listing-word-count-sort="970" data-listing-title-sort="Resource Limits" data-listing-filename-sort="22-Resource-Limits.qmd">
<td>
<a href="../../notes/k8s/22-Resource-Limits.html" class="title listing-title">Resource Limits</a>
</td>
<td>
<span class="listing-description">Protect your apps with resource limits.</span>
</td>

</tr>

<tr data-index="14" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="10" data-listing-word-count-sort="1862" data-listing-title-sort="Logging" data-listing-filename-sort="23-Logging.qmd">
<td>
<a href="../../notes/k8s/23-Logging.html" class="title listing-title">Logging</a>
</td>
<td>
<span class="listing-description">Logging with the EFK stack</span>
</td>

</tr>

<tr data-index="15" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="2" data-listing-word-count-sort="355" data-listing-title-sort="Monitoring" data-listing-filename-sort="24-monitoring.qmd">
<td>
<a href="../../notes/k8s/24-monitoring.html" class="title listing-title">Monitoring</a>
</td>
<td>
<span class="listing-description">Monitoring with Prometheus</span>
</td>

</tr>

<tr data-index="16" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="15" data-listing-word-count-sort="2901" data-listing-title-sort="Ingress" data-listing-filename-sort="25-Ingress.qmd">
<td>
<a href="../../notes/k8s/25-Ingress.html" class="title listing-title">Ingress</a>
</td>
<td>
<span class="listing-description">Routing beyond services</span>
</td>

</tr>

<tr data-index="17" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="1" data-listing-word-count-sort="174" data-listing-title-sort="Cluster Components" data-listing-filename-sort="26-cluster.qmd">
<td>
<a href="../../notes/k8s/26-cluster.html" class="title listing-title">Cluster Components</a>
</td>
<td>
<span class="listing-description">A list of terms used in the context of a K8s cluster.</span>
</td>

</tr>

<tr data-index="18" data-listing-file-modified-sort="1752533266507" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Security" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/k8s/security/index.html" class="title listing-title">Security</a>
</td>
<td>
<span class="listing-description">Security In K8s</span>
</td>

</tr>

<tr data-index="19" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="12" data-listing-word-count-sort="2317" data-listing-title-sort="Workload Placement" data-listing-filename-sort="27-workload-placement.qmd">
<td>
<a href="../../notes/k8s/27-workload-placement.html" class="title listing-title">Workload Placement</a>
</td>
<td>
<span class="listing-description">How to control which nodes run your workloads</span>
</td>

</tr>

<tr data-index="20" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="4" data-listing-word-count-sort="769" data-listing-title-sort="Auto Scaling" data-listing-filename-sort="28-auto-scaling.qmd">
<td>
<a href="../../notes/k8s/28-auto-scaling.html" class="title listing-title">Auto Scaling</a>
</td>
<td>
<span class="listing-description">Automatic horizontal scaling</span>
</td>

</tr>

<tr data-index="21" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="1" data-listing-word-count-sort="158" data-listing-title-sort="Preemption" data-listing-filename-sort="29-preemption.qmd">
<td>
<a href="../../notes/k8s/29-preemption.html" class="title listing-title">Preemption</a>
</td>
<td>
<span class="listing-description">Protecting resources with preemption and priorities</span>
</td>

</tr>

<tr data-index="22" data-listing-file-modified-sort="1752533266495" data-listing-reading-time-sort="19" data-listing-word-count-sort="3741" data-listing-title-sort="Random TILs" data-listing-filename-sort="99-Random.qmd">
<td>
<a href="../../notes/k8s/99-Random.html" class="title listing-title">Random TILs</a>
</td>
<td>
<span class="listing-description">Misc notes about K8s</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/k8s/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>LLMs</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/llm/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-file-modified-sort="1752533266620" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Inference" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/inference/index.html" class="title listing-title">Inference</a>
</td>
<td>
<span class="listing-description">Notes on inference for LLMs</span>
</td>

</tr>

<tr data-index="1" data-listing-file-modified-sort="1752533266621" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="OpenAI" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/openai/index.html" class="title listing-title">OpenAI</a>
</td>
<td>
<span class="listing-description">Notes on using OpenAI</span>
</td>

</tr>

<tr data-index="2" data-listing-file-modified-sort="1770834927196" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Evals" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/evals/index.html" class="title listing-title">Evals</a>
</td>
<td>
<span class="listing-description">Notes on evals</span>
</td>

</tr>

<tr data-index="3" data-listing-file-modified-sort="1752533266616" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Fine-tuning" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/finetuning/index.html" class="title listing-title">Fine-tuning</a>
</td>
<td>
<span class="listing-description">Notes on fine-tuning LLMs</span>
</td>

</tr>

<tr data-index="4" data-listing-file-modified-sort="1752533267193" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Function Calling" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/tools/index.html" class="title listing-title">Function Calling</a>
</td>
<td>
<span class="listing-description">Notes on function calling with LLMs</span>
</td>

</tr>

<tr data-index="5" data-listing-file-modified-sort="1760735313248" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="RAG" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/rag/index.html" class="title listing-title">RAG</a>
</td>
<td>
<span class="listing-description">Notes on Retrieval Augmented Generation (RAG)</span>
</td>

</tr>

<tr data-index="6" data-listing-file-modified-sort="1752533266620" data-listing-reading-time-sort="1" data-listing-word-count-sort="18" data-listing-title-sort="Open Office Hours" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/llm/officehours/index.html" class="title listing-title">Open Office Hours</a>
</td>
<td>
<span class="listing-description">Notes from LLM Office Hours</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/llm/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Linux</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/linux/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table caption-top">
<thead>
<tr class="header">
<th data-quarto-table-cell-role="th">Title</th>
<th data-quarto-table-cell-role="th">Description</th>
</tr>
</thead>
<tbody class="list">
</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/linux/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>ML Serving</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/serving/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<section id="types-of-optimization" class="level2">
<h2 class="anchored" data-anchor-id="types-of-optimization">Types of Optimization</h2>
<table class="caption-top table">
<colgroup>
<col style="width: 28%">
<col style="width: 71%">
</colgroup>
<thead>
<tr class="header">
<th>Category</th>
<th style="text-align: left;">Notes/Examples</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Hardware Upgrades</td>
<td style="text-align: left;">CPUs vs GPUs</td>
</tr>
<tr class="even">
<td>Inference Servers</td>
<td style="text-align: left;">Batching requests, replica/worker management</td>
</tr>
<tr class="odd">
<td>Model Optimization</td>
<td style="text-align: left;">Quantization, pruning, distillation, flash attention</td>
</tr>
<tr class="even">
<td>Compilers</td>
<td style="text-align: left;">Kernel fusion, hardware-specific optimization, portability (hardware &amp; runtimes)</td>
</tr>
</tbody>
</table>
<p>This table is inspired by <a href="https://www.youtube.com/watch?v=ZOWjOxC80qw">this talk</a> where <a href="https://twitter.com/marksaroufim">Mark Saurofim</a> outlines categories of optimization relevant to model serving.</p>
<p>When considering model serving, the discussion tends to be focused on inference servers. However, one underrated topic is the importance ML compilers play (which is discussed in later sections).</p>
</section>
<section id="inference-servers" class="level2">
<h2 class="anchored" data-anchor-id="inference-servers">Inference Servers</h2>
<p>Below are the inference servers I would pay attention to. Nvidia Triton seems to be the most popular/robust according to ~20+ professionals I’ve spoken with.</p>
<ol type="1">
<li>Torch Serve</li>
<li>TFServe</li>
<li>KServe</li>
<li>Nvidia Triton</li>
</ol>
<p>Here are detailed notes with code examples on inference servers I’ve explored. I explore two inference servers: <a href="tfserving/">TFServing</a> and <a href="torchserve/">TorchServe</a>, as well as a general-purpose REST API server for model serving with <a href="fastapi/">fastapi</a>.</p>
<div id="listing-infserve" class="quarto-listing quarto-listing-container-table">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-file-modified-sort="1752533267198" data-listing-reading-time-sort="3" data-listing-word-count-sort="587" data-listing-title-sort="TF Serving" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/serving/tfserving/index.html" class="title listing-title">TF Serving</a>
</td>
<td>
<span class="listing-description">TensorFlow Serving</span>
</td>

</tr>

<tr data-index="1" data-listing-file-modified-sort="1752533267222" data-listing-reading-time-sort="3" data-listing-word-count-sort="525" data-listing-title-sort="TorchServe" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/serving/torchserve/index.html" class="title listing-title">TorchServe</a>
</td>
<td>
<span class="listing-description">Notes on TorchServe</span>
</td>

</tr>

<tr data-index="2" data-listing-file-modified-sort="1752533267197" data-listing-reading-time-sort="4" data-listing-word-count-sort="653" data-listing-title-sort="FastAPI" data-listing-filename-sort="index.ipynb">
<td>
<a href="../../notes/serving/fastapi/index.html" class="title listing-title">FastAPI</a>
</td>
<td>
<span class="listing-description">Serving models with FastAPI</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div>
</section>
<section id="ml-compilers" class="level2">
<h2 class="anchored" data-anchor-id="ml-compilers">ML Compilers</h2>
<section id="why-you-should-care-about-compilers" class="level3">
<h3 class="anchored" data-anchor-id="why-you-should-care-about-compilers">Why You Should Care About Compilers</h3>
<p>From <a href="https://huyenchip.com/2021/09/07/a-friendly-introduction-to-machine-learning-compilers-and-optimizers.html">this blog post</a>:</p>
<ol type="1">
<li>Computing on edge devices can save you tons of money (and potentially complexity).</li>
<li>Re-writing models to work on edge devices is costly b/c that requires specialists to execute – good compilers can make this easy or obviate that transition by helping you translate your high-level framework code into hardware-specific code.</li>
<li>Sometimes, cloud computing is not an option (you have to run on a device).</li>
<li>New types of architectures can perform very poorly on hardware without the right compilers, even when those models are significantly smaller and simpler than established models. One example is shared by Google <a href="https://dl.acm.org/doi/pdf/10.1145/3317550.3321441">researchers who tried to implement capsule networks</a>.</li>
<li>Translating framework code to various backend hardware is a non-trivial problem, as illustrated in the below graph (growing number of frameworks + hardware/devices):</li>
</ol>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/serving/2023-02-13-17-10-43.png" class="img-fluid figure-img"></p>
<figcaption>From Chip Huyen’s <a href="https://huyenchip.com/2021/09/07/a-friendly-introduction-to-machine-learning-compilers-and-optimizers.html">A Freindly Introduction to Machine Learning Compilers</a></figcaption>
</figure>
</div>
</section>
<section id="terminology" class="level3">
<h3 class="anchored" data-anchor-id="terminology">Terminology</h3>
<p>It’s easy to get lost in the terminology of compilers. Here are some terms that are important to understand:</p>
<ul>
<li><strong>Kernel Fusion</strong>: this is the process of combining multiple operations into a single operation. For example, a convolution followed by a ReLU can be combined into a single operation.</li>
<li><strong>Intermediate Representation (IR)</strong>: The IR is a representation of a model that’s independent of a framework like Pytorch. These IRs are often JSON, YAML, or a string that encodes model structure, weights, and so on. These IRs are eventually translated into programs that can be executed and are often optimized toward specific hardware.</li>
<li><strong>Graph Lowering</strong>: This is the process of translating one IR to another. For example, a model represented in the ONNX IR can be lowered to a model in <a href="https://developer.nvidia.com/tensorrt">TensorRT IR</a>. The reason for doing this is to translate one IR to one that allows a specific compiler to perform domain/hardware-specific optimizations. Different compilers can optimize different types of things and offer different goals. For example, ONNX’s primary goal is to be a portable IR, while TensorRT’s primary goal is to optimize for inference. The reason it’s called Graph lowering is that a model be represented as a graph, and you “lower” the graph representation consecutively towards something that can be made into machine code. Compilers can process IRs in different phases such that the IR is simplified/optimized, that a back-end will use to generate machine code.</li>
<li><strong>Front-End</strong>: This refers to part of the <a href="https://en.wikipedia.org/wiki/Compiler">Compiler Stack</a> that translates a programming language into an IR.</li>
<li><strong>Back-End</strong>: This refers to part of the <a href="https://en.wikipedia.org/wiki/Compiler">Compiler Stack</a> that translates an IR into machine code. You can compose different front-ends with different back-ends through “middle-ends” that translate IRs from one to another (also known as “lowering” or “graph lowering”).</li>
<li><strong>Graph Breaks</strong>: When you represent a model as a graph via an intermediate representation (IR) there are pieces of code that might not fit into a graph form, like if/else statements. When this happens, you will have a graph break, where you will have to split your program into several graphs. Only the parts that can be represented as a graph can usually be optimized by the compiler. Depending on the framework you are using, either your or the framework will have to stitch all the graphs together in a way that represents the original program. Graph breaks usually incur a performance penalty, so it’s important to minimize them.</li>
</ul>
</section>
</section>
<section id="common-sources-of-confusion" class="level2">
<h2 class="anchored" data-anchor-id="common-sources-of-confusion">Common Sources of Confusion</h2>
<section id="the-compiler-stack" class="level3">
<h3 class="anchored" data-anchor-id="the-compiler-stack">The Compiler Stack</h3>
<p>It can often be ambiguous when someone refers to a compiler if they are referring to a front-end that generates the IR, the back-end that generates/executes the code, or the entire compiler stack as a whole. For example, ONNX has both an intermediate representation IR and a runtime. The IR is a specification (a string) that allows you to represent a model in a way that’s independent of a framework. The <a href="https://onnxruntime.ai/">ONNX Runtime</a> is a backend that allows you to execute models represented by the ONNX IR on a variety of hardware and from various languages (Python, C++, Java, JS, etc.).</p>
<p>The term “compiler” is often overloaded. Understanding the context in which the term is used can be helpful for understanding documentation. For example, <a href="https://pytorch.org/tutorials/intermediate/dynamo_tutorial.html">Torch Dynamo</a> is a front-end (often referred to as a “graph acquisition tool”) that produces an IR. The user can then lower this IR to a back-end to another compiler stack like C++ (for CPUs) or <a href="https://openai.com/blog/triton/">OpenAI Triton</a> (for GPUs) that eventually gets executed.</p>
</section>
<section id="nvidia-vs-openai-triton" class="level3">
<h3 class="anchored" data-anchor-id="nvidia-vs-openai-triton">Nvidia vs OpenAI Triton</h3>
<p><a href="https://developer.nvidia.com/nvidia-triton-inference-server">Triton by Nvidia</a> is an inference server. <a href="https://github.com/openai/triton">Triton by OpenAI</a> is a high-level CUDA programming language and compiler stack. The two are not related.</p>
</section>
<section id="training-torchdyamo-jit-triton" class="level3">
<h3 class="anchored" data-anchor-id="training-torchdyamo-jit-triton">Training: TorchDyamo + JIT + Triton</h3>
<p>Compilers are often thought of as optimizations for inference. However, there are compilers that help with training too. The most notable these days is <a href="https://pytorch.org/docs/master/dynamo/">TorchDynamo + JIT Compiler</a>. TorchDynamo is a front-end that allows you to capture a PyTorch model as an IR<sup>1</sup>. Since this front-end is maintained by the Pytorch team, it is going to have the greatest support for Pytorch models. The best thing about the TorchDynamo+JIT stack is that it seamlessly handles graph breaks for you (stitches various subgraphs together for you, etc). The JIT compiler supplants the CPython interpreter that normally “eagerly” runs your PyTorch code for faster execution<sup>2</sup>. It works by dynamically modifying Python bytecode right before it is executed. All you have to do is to call one line of code: <code>torch.compile(...)</code> to see the benefits. Andrej Karpathy is using this in his NanoGPT tutorials:</p>
<blockquote class="twitter-tweet blockquote">
<p lang="en" dir="ltr">
This is so underrated! Ridiculous speedup by calling <code>torch.compile(...)</code> <br><br>Code: <a href="https://t.co/9mMGGyEcfz">https://t.co/9mMGGyEcfz</a><br><br>Related blog posts:<br>1. <a href="https://t.co/JOLZ8BQdet">https://t.co/JOLZ8BQdet</a><br>2. <a href="https://t.co/ci8KAzLW1p">https://t.co/ci8KAzLW1p</a> (this blog by <a href="https://twitter.com/marksaroufim?ref_src=twsrc%5Etfw"><span class="citation" data-cites="marksaroufim">@marksaroufim</span></a> is a real gem, BTW) <a href="https://t.co/E0oRVC4Ow8">https://t.co/E0oRVC4Ow8</a>
</p>
— Hamel Husain (<span class="citation" data-cites="HamelHusain">@HamelHusain</span>) <a href="https://twitter.com/HamelHusain/status/1622822879170818050?ref_src=twsrc%5Etfw">February 7, 2023</a>
</blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>The JIT Compiler can theoretically leverage different backends for execution, but at this time, the paved path is to use the <a href="https://dev-discuss.pytorch.org/t/torchinductor-a-pytorch-native-compiler-with-define-by-run-ir-and-symbolic-shapes/747">TorchInductor</a> which lowers the IR to the <a href="https://github.com/openai/triton">OpenAI Triton</a> backend. So the entire “compiler stack” looks like this:</p>
<ol type="1">
<li>TorchDynamo acquires a PyTorch model as an IR (FX graphs, multiple graphs if there are graph breaks)</li>
<li>The JIT Compiler lowers the FX Graph (through other intermediate compiler stacks) to TorchInductor</li>
<li>TorchInductor lowers the IR to OpenAI-Triton for GPU or C++ for CPU</li>
<li>OpenAI Triton compiles the IR and executes it (perhaps by first passing it to some other back-end like CUDA)</li>
</ol>
<p>That is a lot of steps! While the end-user doesn’t necessarily need to be aware of all these steps, the documentation on <a href="https://pytorch.org/docs/master/dynamo/">Torch Dynamo</a> can be really confusing unless you are aware of these different things.</p>
</section>
</section>
<section id="notes-on-specific-compiler-stacks" class="level2">
<h2 class="anchored" data-anchor-id="notes-on-specific-compiler-stacks">Notes on Specific Compiler Stacks</h2>
<section id="tensorrt" class="level3">
<h3 class="anchored" data-anchor-id="tensorrt">TensorRT</h3>
<p>This is a compiler/execution environment. Unlike the JIT (just-in-time), it is an AOT (ahead-of-time) compiler. It is compatible with PyTorch via <a href="https://github.com/pytorch/TensorRT">torch-TensorRT</a>. From <a href="https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html">the docs</a>: TensorRT’s primary means of importing a trained model from a framework is through the&nbsp;ONNX&nbsp;interchange format, so you need to convert your model to ONNX before getting to TensorRT (this happens automatically when you use torch-TensorRT).</p>
</section>
<section id="onnx" class="level3">
<h3 class="anchored" data-anchor-id="onnx">ONNX</h3>
<p>ONNX is mainly focused on portability. ONNX provides its own set of ops that are cross-platform and can be run on an ONNX Runtime. The <a href="https://onnxruntime.ai/">ONNX runtime</a> provides clients in many languages, like Python, C, C++, Java, JS, etc., allowing you to load a model for either inferencing or training. There are hardware-specific clients that are optimized for OS (i.e., Linux, Windows, Mac, etc.), Hardware acceleration (CUDA, CoreML) and so forth. You can select a client from here: https://onnxruntime.ai/.</p>
<p>You can construct your computation graphs with ONNX’s built-in ops; However, this is an impractical way to build a model. In practice, you want to use your favorite ML framework like PyTorch or Tensorflow and use a converter to convert that model to ONNX like <a href="https://pytorch.org/docs/master/onnx.html#avoiding-pitfalls">torch.onnx</a></p>
<section id="pytorch-considerations" class="level4">
<h4 class="anchored" data-anchor-id="pytorch-considerations">Pytorch Considerations</h4>
<p>However, there is no free lunch. For PyTorch, there is a long list of <a href="https://pytorch.org/docs/master/onnx.html#limitations">limitations</a> and <a href="https://pytorch.org/docs/master/onnx.html#avoiding-pitfalls">gotchas</a> where things can go wrong. You must be careful when exporting a model and should test the exported ONNX model against the native model for consistency. The exported model looks like a JSON file that describes the graph along with weights.</p>
<p><code>torch.onnx</code> relies on <a href="https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html">TorchScript</a> to export the model into an IR. You have to either use <code>Tracing</code> or <code>Scripting</code> depending upon the control flow in your model.</p>
<ul>
<li><strong>Tracing:</strong> If there is no control flow (if statements, loops, etc.) then use Tracing. Tracing works by recording the model during execution. If you have dynamic elements in your graph, then they will be recorded as constants.<br>
</li>
<li><strong>Scripting</strong>: If there is control flow, you want to use Scripting instead.</li>
<li><strong>Mixed</strong>: if there are modules in your code that do not have control flow and others that do, you can compile these modules separately with either Tracing or Scripting and then combine them into a single model.</li>
</ul>
<p>Read the <a href="https://pytorch.org/tutorials/beginner/Intro_to_TorchScript_tutorial.html#mixing-scripting-and-tracing">TorchScript Tutorial</a> and <a href="https://pytorch.org/docs/master/onnx.html#tracing-vs-scripting">Tracing vs.&nbsp;Scripting</a> to learn more.</p>
</section>
<section id="use-torch-tensorrt-instead-of-onnx" class="level4">
<h4 class="anchored" data-anchor-id="use-torch-tensorrt-instead-of-onnx">Use Torch-TensorRT instead of ONNX</h4>
<p>I talked to a trusted source on the Pytorch team, and they said that TorchScript is not actively maintained and that I should look at <a href="https://pytorch.org/TensorRT/">pytorch - TensorRT</a> instead.</p>
</section>
</section>
<section id="openai-triton" class="level3">
<h3 class="anchored" data-anchor-id="openai-triton">OpenAI Triton</h3>
<p>Only for GPUs, from <a href="https://www.youtube.com/watch?v=ppWKVg-VxmQ">this talk</a>:</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/serving/2023-02-09-15-41-02.png" class="img-fluid"></p>
</section>
<section id="apachetvm" class="level3">
<h3 class="anchored" data-anchor-id="apachetvm">ApacheTVM</h3>
<p><a href="https://tvm.apache.org/">ApacheTVM</a> is a compiler that seems to have one of the widest ranges of hardware support.</p>
</section>
<section id="adaptive-compilers-tvm" class="level3">
<h3 class="anchored" data-anchor-id="adaptive-compilers-tvm">Adaptive Compilers (TVM)</h3>
<p><a href="https://tvm.apache.org/docs/reference/api/python/autotvm.html">autoTVM</a>, part of <a href="https://tvm.apache.org/">ApacheTVM</a> compiler framework are part of a class of compilers that are adaptive that run tests on hardware and automatically try to optimize it for the hardware by trying many different graph configurations. From Chip’s <a href="https://huyenchip.com/2021/09/07/a-friendly-introduction-to-machine-learning-compilers-and-optimizers.html">intro to compilers</a>:</p>
<blockquote class="blockquote">
<p>autoTVM measures the actual time it takes to run each path it goes down, which gives it ground truth data to train a cost model to predict how long a future path will take. The pro of this approach is that because the model is trained using the data generated during runtime, it can adapt to any type of hardware it runs on. The con is that it takes more time for the cost model to start improving.</p>
</blockquote>
<blockquote class="blockquote">
<p>One example is when Apple released their M1 chips in Nov 2020. M1 is an ARM-based system on a chip, and ARM architectures are more or less well-understood. However, M1 still has a lot of novel components of its ARM implementation and requires significant optimization to make various ML models run fast on it. A month after the release, <a href="https://venturebeat.com/ai/octoml-optimizes-apache-tvm-for-apples-m1-beats-core-ml-4-by-29/">folks at OctoML showed that the optimization made by autoTVM is almost 30% faster than hand-designed optimization by Apple’s Core ML team</a>.</p>
</blockquote>
<p>Quote from a compiler expert:</p>
<blockquote class="blockquote">
<p>Pros of dynamic compilers is that we maximize performance across a broader set of models/ops. Downside of dynamic compilers is search time. AutoTVM generally takes hours, even more than a day to compile because it’s trying every possible combination.</p>
</blockquote>
<p>ML can also be used to optimize the computation graph, or “ML is optimizing ML”. Below is an illustration from Chen, et.al; <a href="https://arxiv.org/pdf/1802.04799.pdf">TVM: An Automated End-to-End Optimizing Compiler for Deep Learning</a>, where they comment that:</p>
<blockquote class="blockquote">
<p>Possible optimizations form a large space, so we use an ML-based cost model to find optimized operators.</p>
</blockquote>
<p>Adaptive compilers are interesting because they do not depend on hand-coded rules like traditional compilers and seem more user-friendly and generalizable to new kinds of hardware. Another adaptive compiler is cuDNN autotune, which you can enable with <code>torch.backends.cudnn.benchmark=True</code>, but apparently this only works with convolutions. The drawback of adaptive compilers is that they can take a long time to “learn” or “search” for good optimizations. However, you can amortize the cost of optimizing the model over many devices on that hardware, and can even take that checkpoint as a starting point for future tuning sessions.</p>
<p>I find adaptive compilation more exciting and promising as a future direction in compilers.</p>
</section>
<section id="wasm" class="level3">
<h3 class="anchored" data-anchor-id="wasm">WASM</h3>
<p>Targeting WASM would theoretically enable you to work on any device that can run a browser - and many devices/hardware can run browsers! However, one drawback is that it’s still slow. See <a href="https://huyenchip.com/2021/09/07/a-friendly-introduction-to-machine-learning-compilers-and-optimizers.html">this blog post</a> for a more detailed discussion.</p>
</section>
</section>
<section id="people-to-follow" class="level2">
<h2 class="anchored" data-anchor-id="people-to-follow">People to follow</h2>
<p>If you want to learn more about compilers, I recommend following these people:</p>
<ul>
<li><a href="https://twitter.com/clattner_llvm">Chris Lattner</a>: watch what he is building at <a href="https://www.modular.com/">Modular</a></li>
<li><a href="https://twitter.com/cHHillee">Horace He</a></li>
<li><a href="https://twitter.com/marksaroufim">Mark Saroufim</a></li>
</ul>
</section>
<section id="resources" class="level2">
<h2 class="anchored" data-anchor-id="resources">Resources</h2>
<ol type="1">
<li>I learned a lot by reading <a href="https://huyenchip.com/2021/09/07/a-friendly-introduction-to-machine-learning-compilers-and-optimizers.html">this great article from Chip Huyen</a>.</li>
<li><a href="https://dl.acm.org/doi/pdf/10.1145/3317550.3321441">This post-mortem</a> of trying to get capsule networks to work on modern hardware illuminates the importance of compilers.</li>
</ol>
<hr>



</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 IR is called FX, and Inductor (another compiler) translates FX graphs to be executed in one of two environments: OpenAI Triton for GPU and C++/OpenMP for CPU. The docs call inductor a backend, but it is really a middle-layer that lowers the IR to another compiler stack.↩︎</p></li>
<li id="fn2"><p>Pytorch uses the python interpreter because PyTorch is natively “eager mode” and allows for dynamism and python control flows (which is why people love it because it’s very hackable or debuggable).↩︎</p></li>
</ol>
</section></div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/serving/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/217966403-9c594af0-ef6e-4fe0-a245-eb902ed8c9eb.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Prompt engineering</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/prompt-eng/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-file-modified-sort="1752533267195" data-listing-reading-time-sort="1" data-listing-word-count-sort="1" data-listing-title-sort="Course" data-listing-filename-sort="index.qmd">
<td>
<a href="../../notes/prompt-eng/course/index.html" class="title listing-title">Course</a>
</td>
<td>
<span class="listing-description">Notebooks from the <a href="https://learn.deeplearning.ai/">deeplearning.ai</a> course</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/prompt-eng/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Python Concurrency</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/concurrency.html</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p>Understand the world of Python concurrency: threads, processes, coroutines and asynchronous programming with a realistic examples.</p>
<p>See this <a href="https://python.hamel.dev/concurrency">blog article</a>.</p>



 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/concurrency.html</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Quarto</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/quarto/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-file-modified-sort="1752533267195" data-listing-reading-time-sort="2" data-listing-word-count-sort="331" data-listing-title-sort="Listings from data" data-listing-filename-sort="listings-from-data.qmd">
<td>
<a href="../../notes/quarto/listings-from-data.html" class="title listing-title">Listings from data</a>
</td>
<td>
<span class="listing-description">Example of how to generate listings for external blog posts</span>
</td>

</tr>

<tr data-index="1" data-listing-file-modified-sort="1752533267195" data-listing-reading-time-sort="1" data-listing-word-count-sort="101" data-listing-title-sort="Merge listings" data-listing-filename-sort="merging.qmd">
<td>
<a href="../../notes/quarto/merging.html" class="title listing-title">Merge listings</a>
</td>
<td>
<span class="listing-description">Merge listings from multiple sources</span>
</td>

</tr>

<tr data-index="2" data-listing-file-modified-sort="1752533267195" data-listing-reading-time-sort="4" data-listing-word-count-sort="601" data-listing-title-sort="Syntax Highlighting" data-listing-filename-sort="highlighting.qmd">
<td>
<a href="../../notes/quarto/highlighting.html" class="title listing-title">Syntax Highlighting</a>
</td>
<td>
<span class="listing-description">How to customize the style and definitions for syntax highlighting in Quarto, including adding new…</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/quarto/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Video Editing</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/video_editing.html</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<section id="davinci-resolve" class="level2">
<h2 class="anchored" data-anchor-id="davinci-resolve">Davinci Resolve</h2>
<section id="use-playhead-as-a-cutting-tool" class="level3">
<h3 class="anchored" data-anchor-id="use-playhead-as-a-cutting-tool">Use Playhead as A Cutting Tool</h3>
<p>Youtube Tutorial: https://www.youtube.com/watch?v=yh77878QDVE His playlist: https://www.youtube.com/playlist?list=PLL6tMzF36ox2c–SNKiifuP8kEFh80wPu</p>
<p>CMD + B -&gt; “Blade” CMD + SHIFT + <code>[</code> or <code>]</code> to cut to location</p>
</section>
<section id="talking-head-circle-thingy" class="level3">
<h3 class="anchored" data-anchor-id="talking-head-circle-thingy">Talking Head Circle Thingy</h3>
<p>Here is a <a href="https://www.youtube.com/watch?v=lqh00nfr-UU">circular camera filter</a> with OBS, which might be easier than DVR.</p>
<p>You can crop <a href="https://www.youtube.com/watch?v=YLbo2OTTF6w">like this</a></p>
</section>
<section id="pause" class="level3">
<h3 class="anchored" data-anchor-id="pause">Pause</h3>
<p>You can add pause recording as a hotkey in OBS</p>
</section>
</section>
<section id="other-tools-to-look-into" class="level2">
<h2 class="anchored" data-anchor-id="other-tools-to-look-into">Other tools to look into</h2>
<ol type="1">
<li><a href="https://www.descript.com/">Descript</a></li>
<li><a href="https://runwayml.com/">RunwayML</a></li>
<li><a href="https://www.capcut.com/">capcut</a> - from Rajeev</li>
<li><a href="https://www.adobe.com/products/premiere">Adobe Premiere</a></li>
<li><a href="https://frame.io/">Frame</a> - Video collaboration that you use for Upwork etc</li>
<li><a href="https://www.epidemicsound.com/music/">Epidemic Sound - Sound by mood (Sanyam)</a></li>
<li><a href="https://artlist.io/">Cayla - Artlist</a></li>
<li><a href="https://www.premiumbeat.com/">Cayla - Premium Beat</a></li>
</ol>
<p>Cayla recommmends 1080p / 24 FPS for Youtube</p>


</section>

 ]]></description>
  <category>video-editing</category>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/video_editing.html</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>Web Scraping</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/web-scraping/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-listing-file-modified-sort="1752533267222" data-listing-reading-time-sort="2" data-listing-word-count-sort="254" data-listing-title-sort="Browser requests to code" data-listing-filename-sort="browser-to-python.qmd">
<td>
<a href="../../notes/web-scraping/browser-to-python.html" class="title listing-title">Browser requests to code</a>
</td>
<td>
<span class="listing-description">An amazing hack for turning web requests in your browser into reusable python code with a few…</span>
</td>

</tr>

<tr data-index="1" data-listing-file-modified-sort="1752533267225" data-listing-reading-time-sort="4" data-listing-word-count-sort="602" data-listing-title-sort="Transcribe &amp; Diarize Videos" data-listing-filename-sort="transcribe-diarize.qmd">
<td>
<a href="../../notes/web-scraping/transcribe-diarize.html" class="title listing-title">Transcribe &amp; Diarize Videos</a>
</td>
<td>
<span class="listing-description">Generate transcriptions of videos with speaker labels.</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/web-scraping/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>dbt</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/dbt/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p>These are notes on how to use <a href="https://www.getdbt.com/">dbt</a>, an increasingly popular data ELT tool (yes it’s called ELT nowadays, not ETL). Here is <a href="https://docs.getdbt.com/docs/introduction">a refernce</a> to read more about dbt.</p>
<section id="setup" class="level2">
<h2 class="anchored" data-anchor-id="setup">Setup</h2>
<ul>
<li>Setting up dbt cloud to work with BigQuery is pretty tricky using their docs. I found this <a href="https://www.youtube.com/playlist?list=PL0QYlrC86xQlp-eOGzGllDxYese4Ki_6A">playlist</a> to be better.</li>
<li>I tried the quickstart but didn’t really benefit much from it. I found <a href="https://courses.getdbt.com/courses/take/fundamentals">this course</a> and it was much better.</li>
</ul>
</section>
<section id="building-your-first-model" class="level2">
<h2 class="anchored" data-anchor-id="building-your-first-model">Building your first model</h2>
<p>We can run the below query in BigQuery, which is a data transformation using SQL.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> customers <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb1-2"></span>
<span id="cb1-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb1-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> customer_id,</span>
<span id="cb1-5">        first_name,</span>
<span id="cb1-6">        last_name</span>
<span id="cb1-7"></span>
<span id="cb1-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> dbt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>tutorial.jaffle_shop.customers</span>
<span id="cb1-9"></span>
<span id="cb1-10">),</span>
<span id="cb1-11"></span>
<span id="cb1-12">orders <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb1-13"></span>
<span id="cb1-14">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb1-15">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> order_id,</span>
<span id="cb1-16">        user_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> customer_id,</span>
<span id="cb1-17">        order_date,</span>
<span id="cb1-18">        status</span>
<span id="cb1-19"></span>
<span id="cb1-20">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> dbt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>tutorial.jaffle_shop.orders</span>
<span id="cb1-21"></span>
<span id="cb1-22">),</span>
<span id="cb1-23"></span>
<span id="cb1-24">customer_orders <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb1-25"></span>
<span id="cb1-26">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb1-27">        customer_id,</span>
<span id="cb1-28"></span>
<span id="cb1-29">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">min</span>(order_date) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> first_order_date,</span>
<span id="cb1-30">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">max</span>(order_date) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> most_recent_order_date,</span>
<span id="cb1-31">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>(order_id) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> number_of_orders</span>
<span id="cb1-32"></span>
<span id="cb1-33">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> orders</span>
<span id="cb1-34"></span>
<span id="cb1-35">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">group</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">by</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb1-36"></span>
<span id="cb1-37">),</span>
<span id="cb1-38"></span>
<span id="cb1-39"></span>
<span id="cb1-40">final <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb1-41"></span>
<span id="cb1-42">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb1-43">        customers.customer_id,</span>
<span id="cb1-44">        customers.first_name,</span>
<span id="cb1-45">        customers.last_name,</span>
<span id="cb1-46">        customer_orders.first_order_date,</span>
<span id="cb1-47">        customer_orders.most_recent_order_date,</span>
<span id="cb1-48">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">coalesce</span>(customer_orders.number_of_orders, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> number_of_orders</span>
<span id="cb1-49"></span>
<span id="cb1-50">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> customers</span>
<span id="cb1-51"></span>
<span id="cb1-52">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">left</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">join</span> customer_orders <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">using</span> (customer_id)</span>
<span id="cb1-53"></span>
<span id="cb1-54">)</span>
<span id="cb1-55"></span>
<span id="cb1-56"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> final</span></code></pre></div></div>
<p>Save the above SQL into dbt cloud as <code>models/dim_customers.sql</code>. You can preview it but also run <code>dbt run</code>, which will create a view. If we look at the detailed logs you will see something that looks like this:</p>
<pre><code> create or replace view `analytics-392917`.`dbt_hhusain`.`dim_customers`
  OPTIONS()
  as with customers as (
    ...</code></pre>
<p>If we navigate to BigQuery, we will see this view:</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/dbt/notes_imgs/2023-07-15-11-51-41.png" class="img-fluid"></p>
<p>If you want to create a table instead of a view, you have to edit the config block, which is special dbt code at the top of the SQL file:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--models/dim_customers.sql</span></span>
<span id="cb3-2">{{</span>
<span id="cb3-3">    config(</span>
<span id="cb3-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">materialized</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;">'table'</span></span>
<span id="cb3-5">    )</span>
<span id="cb3-6">}}</span></code></pre></div></div>
<p>Now if you run <code>dbt run</code> again, you will see from the logs that it creates a table instead of a view:</p>
<pre><code>create or replace table `analytics-392917`.`dbt_hhusain`.`dim_customers`
    ...</code></pre>
<p>Now we can see that the view is now a table named <code>dim_customers</code>:</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/dbt/notes_imgs/2023-07-15-11-58-56.png" class="img-fluid"></p>
<p>When you run <code>dbt run</code>, it runs all models in your project. If you only want to run a specific model, you can run <code>dbt run --select dim_customers</code>.</p>
</section>
<section id="modularity" class="level2">
<h2 class="anchored" data-anchor-id="modularity">Modularity</h2>
<p>We can break up the above SQL into separate files. We can create a file called <code>models/stg_customers.sql</code> and paste the following SQL into it:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> customers <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb5-2"></span>
<span id="cb5-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb5-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> customer_id,</span>
<span id="cb5-5">        first_name,</span>
<span id="cb5-6">        last_name</span>
<span id="cb5-7"></span>
<span id="cb5-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> dbt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>tutorial.jaffle_shop.customers</span>
<span id="cb5-9">)</span>
<span id="cb5-10"></span>
<span id="cb5-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> customers</span></code></pre></div></div>
<p>We can do the same thing with orders and create the file <code>models/stg_orders.sql</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> orders <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb6-2"></span>
<span id="cb6-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb6-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> order_id,</span>
<span id="cb6-5">        user_id <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> customer_id,</span>
<span id="cb6-6">        order_date,</span>
<span id="cb6-7">        status</span>
<span id="cb6-8"></span>
<span id="cb6-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> dbt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>tutorial.jaffle_shop.orders</span>
<span id="cb6-10"></span>
<span id="cb6-11">),</span>
<span id="cb6-12"></span>
<span id="cb6-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> orders</span></code></pre></div></div>
<p>We can now refactor <code>models/dim_customers.sql</code> to use the above two files:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">--models/dim_customers.sql</span></span>
<span id="cb7-2">{{</span>
<span id="cb7-3">    config(</span>
<span id="cb7-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">materialized</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;">'table'</span></span>
<span id="cb7-5">    )</span>
<span id="cb7-6">}}</span>
<span id="cb7-7"></span>
<span id="cb7-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> customers <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb7-9">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> {{ <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ref</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'stg_customers'</span>) }}</span>
<span id="cb7-10">),</span>
<span id="cb7-11"></span>
<span id="cb7-12">orders <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb7-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> {{ <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ref</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'stg_orders'</span>) }}</span>
<span id="cb7-14">),</span>
<span id="cb7-15"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">..</span>.</span></code></pre></div></div>
<p>Now if we run <code>dbt run</code>, we will see that it creates the <code>stg_customers</code> and <code>stg_orders</code> views and then creates the <code>dim_customers</code> table.</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/dbt/notes_imgs/2023-07-17-09-09-50.png" class="img-fluid"></p>
<p>If you look at the lineage view in the dbt cloud, you will see that <code>dim_customers</code> depends on <code>stg_customers</code> and <code>stg_orders</code>:</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/dbt/notes_imgs/2023-07-17-09-13-55.png" class="img-fluid"></p>
</section>
<section id="naming-conventions" class="level2">
<h2 class="anchored" data-anchor-id="naming-conventions">Naming Conventions</h2>
<ol type="1">
<li>Sources: raw data that is already loaded - usually comes from a data loader like Fivetran.</li>
<li>Staging: 1:1 with source tables, but with some transformations</li>
<li>Intermediate: models between staging and final tables.</li>
<li>Fact: Things that are occurring or already occurred (e.g.&nbsp;sales, orders, etc.)</li>
<li>Dimension: Things that describe facts (e.g., customers, products, etc.)</li>
</ol>
<p>We can let these conventions inform folder structure:</p>
<pre><code>├── models
    └── marts
        └── core
            └── dim_customers.sql  
    └── staging
        └── jaffle_shop
            ├── stg_customers.sql
            └── stg_orders.sql </code></pre>
<p>We can change sections of our <code>dbt_project.yml</code> file to reflect this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb9-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jaffle_shop'</span></span>
<span id="cb9-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</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 class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'1.0.0'</span></span>
<span id="cb9-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">config-version</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb9-4"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb9-5"></span>
<span id="cb9-6"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">models:</span></span>
<span id="cb9-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">  jaffle_shop:</span></span>
<span id="cb9-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    # Applies to all files under models/example/</span></span>
<span id="cb9-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    marts:</span></span>
<span id="cb9-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">      core:</span></span>
<span id="cb9-11"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">        +materialized: table</span></span>
<span id="cb9-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">    staging:</span></span>
<span id="cb9-13"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">      +materialized: view</span></span></code></pre></div></div>
<p>Now we know that everything in the <code>staging</code> folder will be a view and everything in the <code>marts/core</code> folder will be a table.</p>
</section>
<section id="sources" class="level2">
<h2 class="anchored" data-anchor-id="sources">Sources</h2>
<p>You want to make sure your dbt models don’t break when your table names to change. You can use sources to do this. We can create a file called <code>models/staging/jaffle_shop/src_jaffle_shop.yml</code> and paste the following into it:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb10-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb10-2"></span>
<span id="cb10-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sources</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb10-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> jaffle_shop</span></span>
<span id="cb10-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">database</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;"> dbt-tutorial</span></span>
<span id="cb10-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">schema</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;"> jaffle_shop</span></span>
<span id="cb10-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tables</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb10-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> customers</span></span>
<span id="cb10-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> orders</span></span></code></pre></div></div>
<p>Now we can update <code>models/staging/jaffle_shop/stg_customers.sql</code> to use the source using the <code>source()</code> function. The arguments to the <code>source</code> function are (<code>name</code>, <code>table_name</code>):</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb11-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> customers <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb11-2"></span>
<span id="cb11-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb11-4">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">id</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> customer_id,</span>
<span id="cb11-5">        first_name,</span>
<span id="cb11-6">        last_name</span>
<span id="cb11-7"></span>
<span id="cb11-8">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> {{ <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">source</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'jaffle_shop'</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'customers'</span>) }}</span>
<span id="cb11-9"></span>
<span id="cb11-10">)</span></code></pre></div></div>
<p>When you configure sources, you get a green node in the lineage graph.</p>
<section id="source-freshness" class="level3">
<h3 class="anchored" data-anchor-id="source-freshness">Source freshness</h3>
<p>The freshness config can be added to <code>models/staging/jaffle_shop/src_jaffle_shop.yml</code>, and must reference a field in the table via <code>loaded_at_field</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb12-2"></span>
<span id="cb12-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sources</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> jaffle_shop</span></span>
<span id="cb12-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">database</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;"> dbt-tutorial</span></span>
<span id="cb12-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">schema</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;"> jaffle_shop</span></span>
<span id="cb12-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tables</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> customers</span></span>
<span id="cb12-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> orders</span></span>
<span id="cb12-10"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">loaded_at_field</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;"> _etl_loaded_at</span></span>
<span id="cb12-11"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">freshness</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb12-12"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">warn_after</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 class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">period</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;"> hour</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span>
<span id="cb12-13"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">error_after</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 class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">period</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;"> hour</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>In the above example, the freshness applies to the <code>orders</code> table. You can run the <code>dbt source freshness</code> command to see the freshness of your sources:</p>
<pre><code>&gt; dbt source freshness
...
17:52:22  1 of 1 WARN freshness of jaffle_shop.orders .................................... [WARN in 1.32s]
17:52:22  Finished </code></pre>
</section>
</section>
<section id="tests" class="level2">
<h2 class="anchored" data-anchor-id="tests">Tests</h2>
<p>There are two kinds of tests: <code>Singular</code> and <code>Generic</code>.</p>
<p>Singular tests are one-offs that are specific to data.</p>
<p>Generic includes the following four tests <code>unique</code>, <code>not_null</code>, <code>accepted_values</code>, <code>relationships</code>. There are dbt packages that expand this.</p>
<section id="generic-tests" class="level3">
<h3 class="anchored" data-anchor-id="generic-tests">Generic Tests</h3>
<p>We can add a <code>unique</code> test to <code>models/staging/jaffle_shop/stg_jaffe_shop.sql</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb14-1">version: <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb14-2"></span>
<span id="cb14-3">models:</span>
<span id="cb14-4">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> name: stg_customers</span>
<span id="cb14-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">columns</span>: </span>
<span id="cb14-6">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> name: customer_id</span>
<span id="cb14-7">        tests:</span>
<span id="cb14-8">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">unique</span></span>
<span id="cb14-9">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> not_null</span>
<span id="cb14-10">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> name: stg_orders</span>
<span id="cb14-11">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">columns</span>:</span>
<span id="cb14-12">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> name: order_id</span>
<span id="cb14-13">        tests:</span>
<span id="cb14-14">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">unique</span></span>
<span id="cb14-15">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> not_null</span>
<span id="cb14-16">      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> name: status</span>
<span id="cb14-17">        tests:</span>
<span id="cb14-18">          <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> accepted_values:</span>
<span id="cb14-19">              <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">values</span>:</span>
<span id="cb14-20">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> completed</span>
<span id="cb14-21">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> shipped</span>
<span id="cb14-22">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> returned</span>
<span id="cb14-23">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> return_pending</span>
<span id="cb14-24">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> placed</span></code></pre></div></div>
<p>You can run the test by calling</p>
<p><code>dbt test</code></p>
<p>You can also test a specific model by calling:</p>
<p><code>dbt test --models stg_customers</code></p>
</section>
<section id="singular-tests" class="level3">
<h3 class="anchored" data-anchor-id="singular-tests">Singular Tests</h3>
<p>We can add a test in <code>tests/assert_positive_total_for_payments.sql</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">with</span> payments <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> (</span>
<span id="cb15-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> {{ <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ref</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'stg_payments'</span>) }}</span>
<span id="cb15-3">)</span>
<span id="cb15-4"></span>
<span id="cb15-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb15-6">    order_id,</span>
<span id="cb15-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sum</span>(amount) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> total_amount</span>
<span id="cb15-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">from</span> payments</span>
<span id="cb15-9"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">group</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">by</span> order_id</span>
<span id="cb15-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">having</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">not</span>(total_amount <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="callout callout-style-default callout-important 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">
Important
</div>
</div>
<div class="callout-body-container callout-body">
<p>If there are any rows returned, the test will fail. You can see this by looking at the detailed logs of the test.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode sql code-with-copy"><code class="sourceCode sql"><span id="cb16-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">select</span></span>
<span id="cb16-2">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> failures,</span>
<span id="cb16-3">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</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="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> should_warn,</span>
<span id="cb16-4">      <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</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="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">as</span> should_error</span>
<span id="cb16-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">..</span>.</span></code></pre></div></div>
</div>
</div>
<p>It knows that this file is a test because of the configuration at the root of the project <code>dbt_project.yml</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb17-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test-paths</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 class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tests"</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb17-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span></code></pre></div></div>
<section id="test-commands" class="level4">
<h4 class="anchored" data-anchor-id="test-commands">Test Commands:</h4>
<ul>
<li><code>dbt test</code> to runs all generic and singular tests in your project.</li>
<li><code>dbt test --select test_type:generic</code> to run only generic tests in your project.</li>
<li><code>dbt test --select test_type:singular</code> to run only singular tests in your project.</li>
</ul>
</section>
</section>
<section id="testing-sources" class="level3">
<h3 class="anchored" data-anchor-id="testing-sources">Testing Sources</h3>
<p>You can test sources in the yaml file that configures the source, or as a separate file in the test path. If we want to add a test to <code>models/staging/jaffle_shop/src_jaffle_shop.yml</code>, we can add the following:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb18-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">version</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb18-2"></span>
<span id="cb18-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">sources</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-4"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">  </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> jaffle_shop</span></span>
<span id="cb18-5"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">database</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;"> dbt-tutorial</span></span>
<span id="cb18-6"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">schema</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;"> jaffle_shop</span></span>
<span id="cb18-7"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">    </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tables</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-8"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> customers</span></span>
<span id="cb18-9"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">columns</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-10"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> id</span></span>
<span id="cb18-11"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tests</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-12"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </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;"> unique</span></span>
<span id="cb18-13"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </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;"> not_null</span></span>
<span id="cb18-14"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span></span>
<span id="cb18-15"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">      </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> orders</span></span>
<span id="cb18-16"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">columns</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-17"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">name</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;"> id</span></span>
<span id="cb18-18"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">            </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tests</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-19"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </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;"> unique              </span></span>
<span id="cb18-20"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">              </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;"> not_null</span></span>
<span id="cb18-21"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">loaded_at_field</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;"> _etl_loaded_at</span></span>
<span id="cb18-22"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">        </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">freshness</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb18-23"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">warn_after</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 class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">period</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;"> hour</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span>
<span id="cb18-24"><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">          </span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">error_after</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 class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</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 class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</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 class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">period</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;"> hour</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>We can execute this test with <code>dbt test</code> or just test sources with the command: <code>dbt test --select source:jaffle_shop</code>.</p>
</section>
</section>
<section id="dbt-build" class="level2">
<h2 class="anchored" data-anchor-id="dbt-build"><code>dbt build</code></h2>
<p><code>dbt run</code> runs your models <code>dbt test</code> runs your tests</p>
<p><code>dbt build</code> combines the two. However, there is an issue with run followed by test, b/c what if a test fails? There is a chicken/egg problem. <code>dbt build</code> goes one layer at a time and executes tests followed by runs.</p>
</section>
<section id="documentation" class="level2">
<h2 class="anchored" data-anchor-id="documentation">Documentation</h2>
<p>You can add documentation to your models through same yaml file you use to define your tests in. You can add a <code>description</code> in various places, as demonstrated below:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode diff code-with-copy"><code class="sourceCode diff"><span id="cb19-1">version: 2</span>
<span id="cb19-2"></span>
<span id="cb19-3">models:</span>
<span id="cb19-4">  - name: stg_customers</span>
<span id="cb19-5"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+    description: one unique customer per row</span></span>
<span id="cb19-6">    columns: </span>
<span id="cb19-7">      - name: customer_id</span>
<span id="cb19-8"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+        description: the primary key for stage customers</span></span>
<span id="cb19-9">        tests:</span>
<span id="cb19-10">          - unique</span>
<span id="cb19-11">          - not_null</span>
<span id="cb19-12">  - name: stg_orders</span>
<span id="cb19-13"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+    description: on order per customer</span></span>
<span id="cb19-14">    columns:</span>
<span id="cb19-15">      - name: order_id</span>
<span id="cb19-16"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+        description: the primary key for stg_orders</span></span>
<span id="cb19-17">        tests:</span>
<span id="cb19-18">          - unique</span>
<span id="cb19-19">          - not_null</span>
<span id="cb19-20">      - name: status</span>
<span id="cb19-21">        tests:</span>
<span id="cb19-22">          - accepted_values:</span>
<span id="cb19-23">              values:</span>
<span id="cb19-24">                - completed</span>
<span id="cb19-25">                - shipped</span>
<span id="cb19-26">                - returned</span>
<span id="cb19-27">                - return_pending</span>
<span id="cb19-28">                - placed</span></code></pre></div></div>
<p>You can add more long-form documentation in the form of doc blocks:</p>
<p>We will create a new file named <code>/models/staging/jaffle_shop/order_status_jaffe_shop.md</code> and paste the following into it:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode markdown code-with-copy"><code class="sourceCode markdown"><span id="cb20-1">{% docs order_status %}</span>
<span id="cb20-2">    </span>
<span id="cb20-3">One of the following values: </span>
<span id="cb20-4"></span>
<span id="cb20-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> status         <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> definition                                       <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span></span>
<span id="cb20-6"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|----------------|--------------------------------------------------|</span></span>
<span id="cb20-7"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> placed         <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> Order placed, not yet shipped                    <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span></span>
<span id="cb20-8"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> shipped        <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> Order has been shipped, not yet been delivered   <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span></span>
<span id="cb20-9"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> completed      <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> Order has been received by customers             <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span></span>
<span id="cb20-10"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> return pending <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> Customer indicated they want to return this item <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span></span>
<span id="cb20-11"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> returned       <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span> Item has been returned                           <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">|</span></span>
<span id="cb20-12"></span>
<span id="cb20-13">{% enddocs %}</span></code></pre></div></div>
<p>We can now add this to our <code>stg_orders</code> model above</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode diff code-with-copy"><code class="sourceCode diff"><span id="cb21-1">...</span>
<span id="cb21-2">  - name: stg_orders</span>
<span id="cb21-3">    description: on order per customer</span>
<span id="cb21-4">    columns:</span>
<span id="cb21-5">      - name: order_id</span>
<span id="cb21-6">        description: the primary key for stg_orders</span>
<span id="cb21-7">        tests:</span>
<span id="cb21-8">          - unique</span>
<span id="cb21-9">          - not_null</span>
<span id="cb21-10">      - name: status </span>
<span id="cb21-11"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">+        description: '{{ doc("order_status") }}'</span></span>
<span id="cb21-12">        tests:</span>
<span id="cb21-13">...</span></code></pre></div></div>
<section id="generating-documentation" class="level3">
<h3 class="anchored" data-anchor-id="generating-documentation">Generating Documentation</h3>
<p>You have to run the command <code>dbt docs generate</code> to re-generate the docs. You can then find the descriptions you added on the docs page:</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/dbt/notes_imgs/2023-07-17-17-50-58.png" class="img-fluid"></p>
<p>The doc block is rendered as well:</p>
<p><img src="https://glittering-puffpuff-87102e.netlify.app/notes/dbt/notes_imgs/2023-07-17-17-53-36.png" class="img-fluid"></p>
</section>
</section>
<section id="deployment" class="level2">
<h2 class="anchored" data-anchor-id="deployment">Deployment</h2>
<p>You can run your dbt project in dev or production so that you can test your changes before you deploy it.</p>
<ol type="1">
<li>commit your code to the main branch.</li>
<li>Under the <code>deploy</code> menu, create an environment in dbt cloud, I created one called <code>Deployment</code>. There is already a <code>Development</code> environment by default.</li>
<li>Under the <code>deploy</code> menu, create a job. Configure the triggers as desired.</li>
<li>Under the <code>deploy</code> menu, select jobs and then select the job you just created. Click <code>run now</code> to run the job.</li>
</ol>
<p>This is kind of like Airflow in the sense that this will orchestrate your data pipelines to run.</p>
<div class="callout callout-style-default callout-warning 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">
<span class="screen-reader-only">Warning</span>Environments
</div>
</div>
<div class="callout-body-container callout-body">
<p>I couldn’t quite figure out how to configure environments. I followed the video but the user interface wasn’t the same. I wasn’t sure how to make such that you can only deploy to production from the main branch. This is worth investigating further.</p>
</div>
</div>
</section>
<section id="example-dbt-project" class="level2">
<h2 class="anchored" data-anchor-id="example-dbt-project">Example dbt project</h2>
<p>An <a href="https://github.com/hamelsmu/dbt-project/tree/main">example dbt project</a> that has the code snippets used in this tutorial.</p>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/dbt/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>fastai</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/fastai/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->








<div class="quarto-listing quarto-listing-container-table" id="listing-listing">
<table class="quarto-listing-table table">
<thead>
<tr>

<th>
Title
</th>

<th>
Description
</th>

</tr>
</thead>
<tbody class="list">

<tr data-index="0" data-categories="ZmFzdGFp" data-listing-file-modified-sort="1752533266476" data-listing-reading-time-sort="8" data-listing-word-count-sort="1486" data-listing-title-sort="Fundamentals" data-listing-filename-sort="01_fundamentals.qmd">
<td>
<a href="../../notes/fastai/fundamentals.html" class="title listing-title">Fundamentals</a>
</td>
<td>
<span class="listing-description">fastai fundamentals</span>
</td>

</tr>

<tr data-index="1" data-categories="ZmFzdGFp" data-listing-file-modified-sort="1752533266476" data-listing-reading-time-sort="14" data-listing-word-count-sort="2785" data-listing-title-sort="Image Classification" data-listing-filename-sort="02_cv.qmd">
<td>
<a href="../../notes/fastai/cv.html" class="title listing-title">Image Classification</a>
</td>
<td>
<span class="listing-description">basic image classification</span>
</td>

</tr>

<tr data-index="2" data-categories="ZmFzdGFp" data-listing-file-modified-sort="1752533266476" data-listing-reading-time-sort="1" data-listing-word-count-sort="87" data-listing-title-sort="Data" data-listing-filename-sort="03_data.ipynb">
<td>
<a href="../../notes/fastai/data.html" class="title listing-title">Data</a>
</td>
<td>
<span class="listing-description">Notes on the the DataBlock api.</span>
</td>

</tr>

</tbody>
</table>
<div class="listing-no-matching d-none">No matching items</div>
</div> ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/fastai/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>pandoc filters</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/pandoc/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p>Two python packages</p>
<div>

</div>
<ul>
<li><a href="http://scorreia.com/software/panflute/">panflute</a> - recommended</li>
<li><a href="https://github.com/jgm/pandocfilters">pandocfilters</a></li>
</ul>
<p>The <a href="https://pandoc.org/filters.html">tutorial</a> on pandoc filters can help you get oriented to the general idea. If rolling your own filters, you probably want to use the JSON filters. Furthermore you can understand the pandoc AST by using the <code>-t native</code> flag (examples of this are shown later).</p>
<section id="the-minimal-notebook" class="level2">
<h2 class="anchored" data-anchor-id="the-minimal-notebook">The minimal notebook</h2>
<p>Here is minimal notebook we are working with:</p>
<p><code>json title="minimal.ipynb" {  "cells": [   {    "cell_type": "markdown",    "metadata": {},    "source": [     "## A minimal notebook"    ]   },   {    "cell_type": "markdown",    "metadata": {},    "source": [     "&lt;MyTag&gt;&lt;/MyTag&gt;"    ]   },   {    "cell_type": "code",    "execution_count": 1,    "metadata": {},    "outputs": [     {      "name": "stdout",      "output_type": "stream",      "text": [       "2\n"      ]     }    ],    "source": [     "# Do some arithmetic\n",     "print(1+1)"    ]   }  ],  "metadata": {   "interpreter": {    "hash": "42fd40e048e0585f88ec242f050f7ef0895cf845a8dd1159352394e5826cd102"   },   "kernelspec": {    "display_name": "Python 3.9.7 ('base')",    "language": "python",    "name": "python3"   },   "language_info": {    "codemirror_mode": {     "name": "ipython",     "version": 3    },    "file_extension": ".py",    "mimetype": "text/x-python",    "name": "python",    "nbconvert_exporter": "python",    "pygments_lexer": "ipython3",    "version": "3.9.7"   }  },  "nbformat": 4,  "nbformat_minor": 4 }</code></p>
</section>
<section id="minimal-ipynb-to-md-converstion-with-pandoc" class="level2">
<h2 class="anchored" data-anchor-id="minimal-ipynb-to-md-converstion-with-pandoc">Minimal ipynb to md converstion with pandoc</h2>
<pre><code>$ pandoc --to gfm minimal.ipynb
&lt;div class="cell markdown"&gt;

## A minimal notebook

&lt;/div&gt;

&lt;div class="cell markdown"&gt;

&lt;MyTag&gt;&lt;/MyTag&gt;

&lt;/div&gt;

&lt;div class="cell code" execution_count="1"&gt;

``` python
# Do some arithmetic
print(1+1)
```

&lt;div class="output stream stdout"&gt;

    2

&lt;/div&gt;

&lt;/div&gt;</code></pre>
</section>
<section id="minimal-ipynb-to-md-converstion-with-quarto" class="level2">
<h2 class="anchored" data-anchor-id="minimal-ipynb-to-md-converstion-with-quarto">Minimal ipynb to md converstion with quarto</h2>
<pre><code>$ quarto render minimal.ipynb --to gfm
pandoc
  to: gfm+footnotes+tex_math_dollars-yaml_metadata_block
  output-file: minimal.md
  standalone: true
  default-image-extension: png
  filters:
    - crossref

Output created: minimal.md</code></pre>
<p>This creates</p>
<pre><code>
## A minimal notebook

&lt;MyTag&gt;&lt;/MyTag&gt;

``` python
# Do some arithmetic
print(1+1)
```

    2</code></pre>
<p>Running Pandoc With those Extensions</p>
<p>running pandoc with <code>--standalone --to gfm+footnotes+tex_math_dollars-yaml_metadata_block</code> still adds the divs and looks different than quarto. Somewhere, maybe quarto is removing the divs. We can see the <code>Div</code> elements in the AST when we explore panflute in the sections below.</p>
</section>
<section id="how-to-use-panflute" class="level2">
<h2 class="anchored" data-anchor-id="how-to-use-panflute">How to use panflute</h2>
<p>The <a href="https://github.com/sergiocorreia/panflute-filters">examples</a> are helpful.</p>
<p>This filter places <code>CodeOutput</code> blocks around code as well as changes the codefence to have <code>file=script.py</code> in order to hack the code fence.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#!/Users/hamel/opt/anaconda3/bin/python</span></span>
<span id="cb4-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#flute.py</span></span>
<span id="cb4-3"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> typing <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> Text</span>
<span id="cb4-4"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> panflute <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb4-5"><span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">from</span> logging <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> warning</span>
<span id="cb4-6"></span>
<span id="cb4-7"></span>
<span id="cb4-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> increase_header_level(elem, doc):</span>
<span id="cb4-9">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span>(elem) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> CodeBlock <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">and</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span>(elem.parent.prev) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> CodeBlock:</span>
<span id="cb4-10">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> ([RawBlock(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;CodeOutput&gt;"</span>), elem, RawBlock(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;/CodeOutput&gt;"</span>)])</span>
<span id="cb4-11">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">elif</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span>(elem) <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> CodeBlock:</span>
<span id="cb4-12">        elem.classes <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;">'file=script.py'</span>]</span>
<span id="cb4-13"></span>
<span id="cb4-14"></span>
<span id="cb4-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> main(doc<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;">None</span>):</span>
<span id="cb4-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> run_filter(increase_header_level, doc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>doc)</span>
<span id="cb4-17"></span>
<span id="cb4-18"></span>
<span id="cb4-19"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">__name__</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;">"__main__"</span>:</span>
<span id="cb4-20">    main()</span></code></pre></div></div>
<p>This is how we can use this filter and see the rendered output:</p>
<pre><code>$ pandoc --to gfm minimal.ipynb --filter "flute.py"
&lt;div class="cell markdown"&gt;

## A minimal notebook

&lt;/div&gt;

&lt;div class="cell markdown"&gt;

&lt;MyTag&gt;&lt;/MyTag&gt;

&lt;/div&gt;

&lt;div class="cell code" execution_count="1"&gt;

``` file=script.py
# Do some arithmetic
print(1+1)
```

&lt;div class="output stream stdout"&gt;

&lt;CodeOutput&gt;

    2

&lt;/CodeOutput&gt;

&lt;/div&gt;

&lt;/div&gt;</code></pre>
<p>Note: we could probably replace the inner div with the <code>output</code> class with <code>&lt;CodeOutput&gt;</code> tag</p>
<p>Just for completeness, this is the schema of the minimal notebook using the <code>--to native</code> flag <strong>prior to</strong> applying the filter:</p>
<pre><code>$pandoc --to native minimal.ipynb
[ Div
    ( "" , [ "cell" , "markdown" ] , [] )
    [ Header
        2
        ( "a-minimal-notebook" , [] , [] )
        [ Str "A" , Space , Str "minimal" , Space , Str "notebook" ]
    ]
, Div
    ( "" , [ "cell" , "markdown" ] , [] )
    [ Para
        [ RawInline (Format "html") "&lt;MyTag&gt;"
        , RawInline (Format "html") "&lt;/MyTag&gt;"
        ]
    ]
, Div
    ( ""
    , [ "cell" , "code" ]
    , [ ( "execution_count" , "1" ) ]
    )
    [ CodeBlock
        ( "" , [ "python" ] , [] )
        "# Do some arithmetic\nprint(1+1)"
    , Div
        ( "" , [ "output" , "stream" , "stdout" ] , [] )
        [ CodeBlock ( "" , [] , [] ) "2\n" ]
    ]
]</code></pre>
<p>And <strong>after applying the filter</strong>:</p>
<pre><code>$pandoc --to native minimal.ipynb --filter flute.py
[ Div
    ( "" , [ "cell" , "markdown" ] , [] )
    [ Header
        2
        ( "a-minimal-notebook" , [] , [] )
        [ Str "A" , Space , Str "minimal" , Space , Str "notebook" ]
    ]
, Div
    ( "" , [ "cell" , "markdown" ] , [] )
    [ Para
        [ RawInline (Format "html") "&lt;MyTag&gt;"
        , RawInline (Format "html") "&lt;/MyTag&gt;"
        ]
    ]
, Div
    ( ""
    , [ "cell" , "code" ]
    , [ ( "execution_count" , "1" ) ]
    )
    [ CodeBlock
        ( "" , [ "file=script.py" ] , [] )
        "# Do some arithmetic\nprint(1+1)"
    , Div
        ( "" , [ "output" , "stream" , "stdout" ] , [] )
        [ RawBlock (Format "html") "&lt;CodeOutput&gt;"
        , CodeBlock ( "" , [] , [] ) "2\n"
        , RawBlock (Format "html") "&lt;/CodeOutput&gt;"
        ]
    ]
]</code></pre>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/pandoc/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
<item>
  <title>programming languages</title>
  <link>https://glittering-puffpuff-87102e.netlify.app/notes/programming-languages/</link>
  <description><![CDATA[ 

<!-- Content inserted at the beginning of body tag -->
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PKGWQMKL" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->




<p>High level takeaways after completing the <a href="https://www.coursera.org/learn/programming-languages">3-Part Coursera class Programming Languages</a> with Dan Grossman.</p>
<p>Your GitHub repo for this class (private) <a href="https://github.com/hamelsmu/programming-languages-class">is here</a>.</p>
<section id="sml-standard-ml-part-a" class="level2">
<h2 class="anchored" data-anchor-id="sml-standard-ml-part-a">SML (Standard ML) Part A</h2>
<ul>
<li>You setup vim to have an IDE for this. See notes in the VIM section below.</li>
<li>ML is a statically typed language with magical <strong>type inference</strong> that works really well. It automatically determines the types and is very intuitive and helpful.</li>
<li>Learned how to use recursion everywhere instead of loops, particularly with <code>hd</code>, <code>tl</code> and <code>cons</code>.</li>
<li>Local variable binding with <code>let</code> is very important (which also allows you to bind local/private functions as well)</li>
<li><code>cons</code> allows you to append to the beginning of a list</li>
<li>There is an option type that is <code>NONE</code> or <code>SOME v</code></li>
<li>This language doesn’t encourage mutation, which is a feature. Otherwise, you can use a reference which is like a pointer to mutate a variable.</li>
<li><strong>pattern matching with a case expression</strong>: This is one of the coolest things that I learned, and something similar <a href="https://www.python.org/dev/peps/pep-0636/">is coming to Python v 3.10</a>.
<ul>
<li>You can have nested patterns</li>
<li>You can pattern match against function arguments which allow for really nice syntax for achieving multiple dispatch type of functionality.. (not sure about python)</li>
<li>You can pattern match against types as well as data structures.</li>
<li>You can have constants in there as well.</li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode ml code-with-copy"><code class="sourceCode ocaml"><span id="cb1-1">case name </span>
<span id="cb1-2">     NameType name =&gt; ...</span>
<span id="cb1-3">   | (first, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MyLastName"</span>) =&gt; ...</span>
<span id="cb1-4">   | (first, last) =&gt; ...</span>
<span id="cb1-5">   | name =&gt; ...</span>
<span id="cb1-6">   | _ =&gt; ...</span></code></pre></div></div></li>
<li><strong>Tail recursion</strong> with accumulators. Ex- factorial</li>
<li>The <code>fn</code> keyword is used to define <strong>anonymous functions</strong>.</li>
<li>ML uses <code>lexical scope</code> which means function is evaluated in the environment where the function was defined. <code>dynamic scope</code>, which is usually not desired, is the alternative where the function is evaluated in the in the environment it is called.</li>
<li><strong>Closure</strong> - the call stack has a “pair” that is the (function, environment when the function was defined). This pair is called the <code>closure</code>. The call stack has a snapshot of what the environment looked like at the time the function was defined.</li>
<li><code>fold</code> is like reduce.</li>
<li>ML supports <strong>function composition</strong> like this with the keyword <code>o</code>: <code>f1 o f2 o f3</code>
<ul>
<li>best to do a val binding to avoid unnecessary wrapping: <code>val newfunc = f1 o f2</code></li>
<li>with <code>o</code> you apply functions from right to left so <code>f1 o f2 x</code> is the same as <code>f1(f2(x))</code> there is an alternative that is left to right called the <code>pipeline operator</code>.</li>
</ul></li>
<li><strong>Currying and partial application</strong>
<ul>
<li>Universal way to make a func curryable: <code>ml   fun myfunc x       let fun f2 (z) = z           fun f1 (y) = f2(y)       begin           f1       end</code></li>
<li>ML has first class support for currying so you don’t have to do the above hack.</li>
</ul></li>
<li>ML supports mutual recursion just like <code>let-rec</code> in racket.</li>
</ul>
</section>
<section id="racket-part-b" class="level2">
<h2 class="anchored" data-anchor-id="racket-part-b">Racket (Part B)</h2>
<p>Racket is related to Lisp and Scheme. Everything is a function. Parenthesis for everything. The position of parenthesis changes the meaning of the code.</p>
<ul>
<li>Racket has dynamic typing, unlike SML.</li>
<li>Thunks: Wrap a function in a zero argument function to delay evaluation. Applications:
<ul>
<li>Streams: the function will return a tuple of (value, func), and when you call func it will return (value, func) so you get one value at a time. This is not specific to Racket.</li>
<li>Lazy evaluation: You can use thunks to delay execution like a promise to a later time. This is an example of lazy evalution that doesn’t actually evaluate anything until being forced to:</li>
</ul></li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode racket code-with-copy"><code class="sourceCode racket"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>my-delay f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mcons <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#f</span> f<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">define</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;"> </span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>my-force th<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-4"></span>
<span id="cb2-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mcar th<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mcdr th<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">begin</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>set-mcar! th <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">#t</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>set-mcdr! th <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">((</span>mcdr th<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>mcdr th<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))))</span></span></code></pre></div></div>
<p>Racket allows you use <strong>macros</strong> that will evaluate before the code is run and that will “expand” into valid racket syntax.</p>
<p>You implemented your own small programming language. This used recursive calls to evluate expressions with the base case being the values (Integer, strings, etc). - Interperter: write a program in another language A that takes programs in B and produces answers directly. A better term would be “evaluator”. - Compiler: write program in another language A that takes programs in B and produces an equivalent program in langauage C. A better term here would be “translator”.</p>
<p>Closures: for lexical scope, the interpreter has a stack of tuples. The tuples are (1) the function to be called (2) the environment, which contains the value of all variables at the time the function was defined. You also have to track the arguments for the function seperately, so you can evaluate the arguments in the environment the function was run in.</p>
</section>
<section id="ruby-part-c" class="level2">
<h2 class="anchored" data-anchor-id="ruby-part-c">Ruby (Part C)</h2>
<p>I didn’t spend too much time some concepts I was mostly familiar with this.</p>
<ul>
<li><p>Ruby is OOP, dynamically typed.</p></li>
<li><p>Ruby is pure OOP, even top level functions and variables are part of the built-in <code>Object</code> class.</p></li>
<li><p>They have fastcore like shortcuts for getters and setters:</p></li>
</ul>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb3-1"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">attr_reader</span> <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:y</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:z</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># defines getters </span></span>
<span id="cb3-2"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">attr_accessor</span> <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:x</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># defines getters and setters</span></span></code></pre></div></div>
<p>newlines are important. The syntax can change without them.</p>
<p>Dynamic class definitions. The following code will result in <code>Class</code> with the methods <code>foo</code> and <code>bar</code>! The second one doesn’t override the first one!</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode rb code-with-copy"><code class="sourceCode ruby"><span id="cb4-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Class</span></span>
<span id="cb4-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> foo</span>
<span id="cb4-3">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-6"></span>
<span id="cb4-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Class</span></span>
<span id="cb4-8">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> bar</span>
<span id="cb4-9">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-11"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
<section id="blocks" class="level3">
<h3 class="anchored" data-anchor-id="blocks">Blocks</h3>
<p>They also have a very convenient lambda like thing called <code>Blocks</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb5-1">sum <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="cb5-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</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;">.each</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> sum <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+=</span> x </span>
<span id="cb5-3">               <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">puts</span> sum <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>You can use Blocks to make accumulators too, and even use <code>inject</code> to initialize the accumulator:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb6-1">sum <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>,<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</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;">.inject</span>(<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="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span>acc,elt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> acc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> elt <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>To use blocks in a method, you will have to look that up in the docs. This involves the <code>yield</code> keyword. For example, this code will print “hi” 3 times:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb7-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> foo x </span>
<span id="cb7-2">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> x </span>
<span id="cb7-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">yield</span> </span>
<span id="cb7-4">   <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> </span>
<span id="cb7-5">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">yield</span> </span>
<span id="cb7-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">yield</span> </span>
<span id="cb7-7">   <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span> </span>
<span id="cb7-8"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span> </span>
<span id="cb7-9"></span>
<span id="cb7-10">foo (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">true</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;">puts</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hi"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> </span>
<span id="cb7-11">foo (<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">false</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;">puts</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hi"</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p><code>Blocks</code> are not first class functions even though they kind of look like lambdas. Lets say you wanted to map over an array but wanted to return an array of functions instead of values. The way to do this is to use the keyword <code>lambda</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb8-1">c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> a<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.map</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{|</span>x<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{|</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> y<span class="op" style="color: #5E5E5E;
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;"># wrong, a syntax error</span></span>
<span id="cb8-2"></span>
<span id="cb8-3">c <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> a<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.map</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{|</span>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;">lambda</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{|</span>y<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;=</span> y<span class="op" style="color: #5E5E5E;
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;"># this will work</span></span></code></pre></div></div>
<section id="subclassing" class="level4">
<h4 class="anchored" data-anchor-id="subclassing">Subclassing</h4>
<ul>
<li><code>super</code> calls the same method in the parent class. You dont have to do super.method_name(), just <code>super</code>.</li>
<li>Instance variables are preceeded with <code>@</code></li>
</ul>
<p>Child classes are defined like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb9-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Child</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Parent</span></span>
<span id="cb9-2"> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb9-3"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div></div>
</section>
</section>
<section id="typing" class="level3">
<h3 class="anchored" data-anchor-id="typing">Typing</h3>
<p>They discussed the various ways different type systems are constructed. The interface idiom, that is familar to you from Golang (but not specific to Golang) was introduced.</p>
<hr>
</section>
</section>
<section id="vim" class="level2">
<h2 class="anchored" data-anchor-id="vim">VIM</h2>
<p>For the Standard ML programming language I decided to force myself to use vim. I added the following things to my <code>.vimrc</code> to make it manageable. Note the plugin <code>jez/vim-better-sml</code></p>
<pre><code>" from https://github.com/jez/vim-as-an-ide
set nocompatible

inoremap &lt;C-e&gt; &lt;C-o&gt;A


filetype off

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

Plugin 'VundleVim/Vundle.vim'

" ----- Making Vim look good ------------------------------------------
Plugin 'altercation/vim-colors-solarized'
Plugin 'tomasr/molokai'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'

" ----- Vim as a programmer's text editor -----------------------------
Plugin 'scrooloose/nerdtree'
Plugin 'jistr/vim-nerdtree-tabs'
Plugin 'vim-syntastic/syntastic'
Plugin 'xolox/vim-misc'
Plugin 'xolox/vim-easytags'
Plugin 'majutsushi/tagbar'
Plugin 'ctrlpvim/ctrlp.vim'
" ----- Working with Git ----------------------------------------------
Plugin 'airblade/vim-gitgutter'
Plugin 'tpope/vim-fugitive'
Plugin 'Raimondi/delimitMate'
Plugin 'jez/vim-better-sml'
Plugin 'christoomey/vim-tmux-navigator'
Plugin 'benmills/vimux'
call vundle#end()

filetype plugin indent on

set number
set ruler
set showcmd
set incsearch
set hlsearch
set backspace=indent,eol,start

syntax on
set mouse=a</code></pre>


</section>

 ]]></description>
  <guid>https://glittering-puffpuff-87102e.netlify.app/notes/programming-languages/</guid>
  <pubDate>Sat, 11 Jul 2026 21:11:25 GMT</pubDate>
  <media:content url="https://user-images.githubusercontent.com/1483922/208359430-f55d7503-3a98-4875-a35c-16314c9439d0.png" medium="image" type="image/png"/>
</item>
</channel>
</rss>
