<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Usually Pragmatic</title>
	<description>Just a digital garden of my own.</description>
    <link>https://www.usuallypragmatic.com</link>
    <atom:link href="https://www.usuallypragmatic.com/feed.xml" rel="self" type="application/rss+xml" />
  	
    
      <item>
        <title>Product Thinking in an AI World</title>
        <description>&lt;p&gt;I’m writing this in mid-2024. GPT-4, Claude 3.5-Sonnet, and Google Gemini 1.5 Pro are the world’s leading LLM models, and the ever rumored Llama-3-400B is supposedly just around the corner.&lt;/p&gt;

&lt;p&gt;The LLMs are wildly capable: they don’t just write sonnets, or teach you about history, but they’ve even turned into amazing coding assistants. Sure, they still hallucinate sometimes, but most of the time it’s not worse than your average person (or stack overflow answer).&lt;/p&gt;

&lt;p&gt;The problem is that no one knows what the future is going to bring–will RAG rule the day? will we need new models with flexible depth-of-compute as per Yann LeCun? will the scaling laws finally fizzle out? or will we simply run out of voltage transformers?–just that it’s going to happen soon. And with tens, if not hundreds, of billions of dollars in play, the mega AI labs feel like behemoths, ready to wipe out entire business models in a glance, or at least a model update.&lt;/p&gt;

&lt;p&gt;So what do you do if you still want to play in this space?&lt;/p&gt;

&lt;p&gt;The way I see it, there are three main options: find a defensible niche, adapt at the edge, or build foundations.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3 id=&quot;find-a-defensible-niche&quot;&gt;Find a defensible niche&lt;/h3&gt;

&lt;p&gt;There are some industries that are hard to enter, or might be too small to be worth it for the big players, or require some kind of specialized knowledge, infrastructure, or process to tackle. Think industries like healthcare (especially with HIPAA), defense tech (clearances, govt contracting), or autonomy (specialized training datasets).&lt;/p&gt;

&lt;p&gt;The fundamental bet here is that the extra barriers to entry will give you enough headroom to establish a sustainable business.&lt;/p&gt;

&lt;h3 id=&quot;adapt-at-the-edge&quot;&gt;Adapt at the edge&lt;/h3&gt;

&lt;p&gt;If you’ve got the network for it (or the dedicated manpower, or connections, or pre-existing business lines), it might be possible to build a reactive business. That is, to always be on the look out for “the next step” and to simply build out the new products faster than your competition (once it’s clear what they should be!).&lt;/p&gt;

&lt;p&gt;This is a road of constant exploration and vigilence. It means you’ll need to do a lot of networking, outreach, and learning, and probably also have your own internal AI R&amp;amp;D effort, even if only for the second-order benefits of improved market insight. You’ll probably also end up sponsoring events and truly trying to build a community. After all, you won’t know precisely where the next product signal will come from… only that you’ll have to find and act on it faster than your competitors.&lt;/p&gt;

&lt;h3 id=&quot;build-foundations&quot;&gt;Build foundations&lt;/h3&gt;

&lt;p&gt;There are &lt;em&gt;a lot&lt;/em&gt; of people within the AI space. I just got back from Seattle, where CVPR broke 12,000 attendees. And yet, that’s a small fraction of the population. For everyone right now pushing the edge of AI systems, there are a thousand more who know they should care, who know they’ll need it, and who wish it was within their reach, but who simply don’t know how to get started. How to put the pieces together and make things happen.&lt;/p&gt;

&lt;p&gt;Building foundational tools–note! not foundational models!–for these people will be a great way to bring value and earn happy customers. But what counts as a foundational tool?&lt;/p&gt;

&lt;p&gt;The operative question is, for any particular customer segment,&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“what can you build that will embody the lessons-learned from the experts-at-the-edge, so that your customer can build their own systems successfully, and without needing to pay the cost to learn those same lessons first-hand?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My favorite example here is not a software product at all, but the bodies of documents we call &lt;em&gt;building codes&lt;/em&gt;. Many lessons have been learned over the years about fire safety, earthquake sturdiness, handicap accessibility, and more, and the beauty of building codes is that they oblivate the need for individual builders to learn those impossibly-many items for themselves. Instead, they establish a standard framework of “18 inches on-center”s and “standard weight Schedule 40 wrought iron”s that empower the end users to put the pieces together for themselves faster, and more confidently and easily, than would otherwise be possible.&lt;/p&gt;

&lt;p&gt;Of course, this works for software just as well. “Build the systems that let people build systems” is a time-honored strategy.&lt;/p&gt;
</description>
        <pubDate>Mon, 24 Jun 2024 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/essays/Product-Thinking-in-an-AI-World.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/essays/Product-Thinking-in-an-AI-World.html</guid>
      </item>
    
      <item>
        <title>Python decorators for fun and profit</title>
        <description>&lt;p&gt;Two python functions:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_status_and_execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;running function &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__qualname__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You might want to wrap them like:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;status_printing_add&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print_status_and_execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Which is &lt;em&gt;kind of&lt;/em&gt; ok, except that now you have to change all your code wherever you used to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt; to use the new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;status_printing_add&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Instead, you can just decorate the function definition of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt; like so:
&lt;!--more--&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_status_and_execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;running function &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__qualname__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_status_and_execute&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And now every instance of add behaves as if it is automatically transformed:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add(a, b) -&amp;gt; print_status_and_execute(add)(a, b)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can even make decorators themselves depend on arguments, though it requires an extra level of abstraction:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_n_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;decorator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwargs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decorator&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print_n_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Or do fancier things, like create and maintain extra data structures available to their context across function calls:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;memoize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;prev_res&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev_res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev_res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;prev_res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mem&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memoize&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fibb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fibb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fibb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
</description>
        <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/blog/2024-04-22-Python-decorators-for-fun-and-profit.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/blog/2024-04-22-Python-decorators-for-fun-and-profit.html</guid>
      </item>
    
      <item>
        <title>Course Notes -- Fast.ai</title>
        <description>&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;

&lt;p&gt;I’ve been meaning to run through the &lt;a href=&quot;https://course.fast.ai/&quot;&gt;Fast.ai&lt;/a&gt; course on practical deep learning for about a year now, since I first learned of it, and it’s finally time. As usual, I’ll be burning down through this quickly, and thankfully have a pretty deep background in the gnarlier, more mathematical aspects of the field… (I’ve derived and implemented backprop by hand a number of times, and most recently on the professional side, was SVP product for a startup building LLM Inference HW, so I’ve become quite familiar with the underlying theory and architectures).&lt;/p&gt;

&lt;p&gt;But now it’s time to roll my sleeves up and learn the hands-on tools.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I’ll be using this space to track and update any particularly interesting things I learn along the way.&lt;/p&gt;

&lt;h3 id=&quot;part-1&quot;&gt;Part 1&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;My goal here will be to go through the fast.ai Part 1 sequence and produce and deploy an ML model accessible directly from this project page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Things I learned:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/yt-dlp/yt-dlp&quot;&gt;yt-dlp&lt;/a&gt; is a &lt;em&gt;great&lt;/em&gt; command line tool for downloading youtube videos. Highly useful for making it easy to adjust playback speed (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;]&lt;/code&gt; keyboard shortcuts) with &lt;a href=&quot;https://mpv.io/&quot;&gt;mpv&lt;/a&gt; (a close analog to mplayer with good mac support).&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://timm.fast.ai/&quot;&gt;timm&lt;/a&gt; is a pytorch-based deep learning library collecting a number of pre-existing image models.&lt;/li&gt;
  &lt;li&gt;I cannot believe I hadn’t encountered &lt;a href=&quot;https://docs.python.org/3/library/functools.html#functools.partial&quot;&gt;python’s functools.partial()&lt;/a&gt; before. I’ve been used to this sort of functionality since my days messing around with making a solver for &lt;a href=&quot;https://qntm.org/files/hatetris/hatetris.html&quot;&gt;hateris&lt;/a&gt; in haskell ages ago, and I’ve always rolled my own in python using lambda functions. &lt;em&gt;But of course&lt;/em&gt; there’s a built-in for that now.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://i]pywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html&quot;&gt;ipywidgets.interact&lt;/a&gt; is another major quality of life improvement. However, as a reminder to myself, this &lt;em&gt;is not enabled by default&lt;/em&gt; in jupyterlab.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.usuallypragmatic.com/blog/2024-04-22-Python-decorators-for-fun-and-profit.html&quot;&gt;Python decorators&lt;/a&gt;, which have been on my “to-learn” list &lt;em&gt;forever&lt;/em&gt;, and have finally drifted to the top.&lt;/li&gt;
  &lt;li&gt;The use of &lt;a href=&quot;https://realpython.com/python-asterisk-and-slash-special-parameters/&quot;&gt;* and /&lt;/a&gt; in python argument lists in order to enforce the allowable order of positional vs keyword arguments.&lt;/li&gt;
  &lt;li&gt;Nice to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log()&lt;/code&gt; for reducing the domain of distributions. (But more important to just be aware of, and interrogate, your data distributions!)&lt;/li&gt;
  &lt;li&gt;Somehow, I missed that list comprehensions in python also extend to dictionaries and sets! Cute.&lt;/li&gt;
  &lt;li&gt;I had not encountered the book &lt;a href=&quot;https://wesmckinney.com/book/&quot;&gt;Python for Data Analysis&lt;/a&gt; before, but it’s a solid resource on some of the internals and tools (especially in pandas) that I was less familiar with.&lt;/li&gt;
  &lt;li&gt;I was not previously familiar with &lt;a href=&quot;https://www.sympy.org/en/index.html&quot;&gt;SymPy&lt;/a&gt; at all. Seems legit.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Random Forests:&lt;/strong&gt; I had &lt;em&gt;heard&lt;/em&gt; of these before, but never actually &lt;em&gt;learned&lt;/em&gt; them. To be honest, I’m a little disappointed. The process is cute, elegant, and simple. But damnit, it’s about as crude as a blunt rock. Chop your dataset into random subsets, each with a random subset of all of the features, and train a bunch of decision trees (one on each subset of your data). For predicting, take the average value of all of them. Or maybe the mode, depending on whether you want a quantized result or not. It works, but it’s literally just duct-taping random shit together. Though sometimes, that’s all you need.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2011.11156v1.pdf&quot;&gt;Test Time Augmentation&lt;/a&gt; is a cute trick that seems especially amenable to image models for potentially improving output accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;part-1---project&quot;&gt;Part 1 - Project&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;This is a transformer-based number-classifier, trained on MNIST. More details about the specific architecture I experimented with below. To use, draw a digit 0-9, and click submit.&lt;/em&gt;&lt;/p&gt;

&lt;div style=&quot;margin-left: 5%; display: flex; justify-content: center; align-items: start; gap: 5%;&quot;&gt;
    &lt;canvas id=&quot;userInput&quot; style=&quot;display: flex; flex-direction: column; gap: 10px; border: 2px solid black; aspect-ratio: 1 / 1; width: 60%;&quot;&gt;&lt;/canvas&gt;
    &lt;div style=&quot;display: flex; flex-direction: column; gap: 10px;&quot;&gt;
        &lt;button id=&quot;clearButton&quot;&gt;Clear&lt;/button&gt;
        &lt;button id=&quot;saveButton&quot;&gt;Save&lt;/button&gt;
        &lt;button id=&quot;submitButton&quot;&gt;Submit&lt;/button&gt;
        &lt;div id=&quot;prob0&quot;&gt;
            0: 0%
        &lt;/div&gt;
        &lt;div id=&quot;prob1&quot;&gt;1: &lt;/div&gt;
        &lt;div id=&quot;prob2&quot;&gt;2: &lt;/div&gt;
        &lt;div id=&quot;prob3&quot;&gt;3: &lt;/div&gt;
        &lt;div id=&quot;prob4&quot;&gt;4: &lt;/div&gt;
        &lt;div id=&quot;prob5&quot;&gt;5: &lt;/div&gt;
        &lt;div id=&quot;prob6&quot;&gt;6: &lt;/div&gt;
        &lt;div id=&quot;prob7&quot;&gt;7: &lt;/div&gt;
        &lt;div id=&quot;prob8&quot;&gt;8: &lt;/div&gt;
        &lt;div id=&quot;prob9&quot;&gt;9: &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;script type=&quot;text/javascript&quot;&gt;
    // create canvas element and append it to document body
    const canvas = document.getElementById(&quot;userInput&quot;);
    canvas.width = 560;
    canvas.height = 560;

    // get canvas 2D context
    const context = canvas.getContext(&apos;2d&apos;);
    
    document.addEventListener(&apos;mousemove&apos;, draw);
    document.addEventListener(&apos;mousedown&apos;, startDrawing);
    document.addEventListener(&apos;mouseout&apos;, stopDrawing);
    document.addEventListener(&apos;mouseup&apos;, stopDrawing);
    document.addEventListener(&apos;touchstart&apos;, startDrawing);
    document.addEventListener(&apos;touchmove&apos;, draw);
    document.addEventListener(&apos;touchend&apos;, stopDrawing);

    let isDrawing = false;

    function getMousePos(canvas, event) {
        var rect = canvas.getBoundingClientRect();
        return {
            x: (event.clientX - rect.left) / (rect.right - rect.left) * canvas.width,
            y: (event.clientY - rect.top) / (rect.bottom - rect.top) * canvas.height
        };
    }

    function startDrawing(event) {
        isDrawing = true;
        //var pos = getMousePos(canvas, event);
        // context.fillStyle = &quot;#000000&quot;;
        // context.fillRect(pos.x, pos.y, 4, 4);
        draw(event);
    }

    function draw(event) {
        if (!isDrawing) return;

        context.lineWidth = 30;
        context.lineCap = &apos;round&apos;;

        var pos = getMousePos(canvas, event);
        context.lineTo(pos.x, pos.y);
        context.stroke();
        context.beginPath();
        context.moveTo(pos.x, pos.y);
    }

    function stopDrawing() {
        isDrawing = false;
        context.beginPath();
    }

    function getTinyImageURL() {
        var tmpCanvas = document.createElement(&apos;canvas&apos;);
        var tmpCtx = tmpCanvas.getContext(&apos;2d&apos;);

        tmpCanvas.width = 560;
        tmpCanvas.height = 560;

        var w = tmpCanvas.width;
        var h = tmpCanvas.height;

        var tmpCanvas2 = document.createElement(&apos;canvas&apos;);
        var tmpCtx2 = tmpCanvas2.getContext(&apos;2d&apos;);
        tmpCanvas2.width = 560;
        tmpCanvas2.height = 560;

        var destCanvas = document.createElement(&apos;canvas&apos;);
        var destCtx = destCanvas.getContext(&apos;2d&apos;);
        destCanvas.width = 28;
        destCanvas.height = 28;

        tmpCtx.drawImage(canvas, 0, 0, w / 2, h / 2);
        tmpCtx2.drawImage(tmpCanvas, 0, 0, w / 2, h / 2, 0, 0, w / 4, h / 4);
        tmpCtx.clearRect(0, 0, w, h);
        tmpCtx.drawImage(tmpCanvas2, 0, 0, w / 4, h / 4, 0, 0, w / 8, h / 8);
        tmpCtx2.clearRect(0, 0, w, h);
        tmpCtx2.drawImage(tmpCanvas, 0, 0, w / 8, h / 8, 0, 0, w / 16, h / 16);
        destCtx.drawImage(tmpCanvas2, 0, 0, w / 16, h / 16, 0, 0, w / 20, h / 20);

        return destCanvas.toDataURL(&apos;image/png&apos;);
    }

    function updateProbabilities() {
        const dataURL = getTinyImageURL();
        const payload = {data: dataURL};
        fetch(&apos;https://mnistbyhand-carpdiem.replit.app/predict/&apos;, {
            method: &apos;POST&apos;,
            headers: {
                &apos;Content-Type&apos;: &apos;application/json&apos;
            },
            body: JSON.stringify(payload)
        })
            .then(response =&gt; response.json())
            .then(data =&gt; {
                const probabilities = data.output;
                updateProbabilitiesOnPage(probabilities);
            })
            .catch(error =&gt; {
                console.error(&apos;Error:&apos;, error);
            });
    }

    function updateProbabilitiesOnPage(probabilities) {
        for (let i = 0; i &lt;= 9; i++) {
            const probElem = document.getElementById(`prob${i}`);
            probElem.textContent = `${i}: ${(probabilities[i] * 100).toFixed(1)}%`;
        }
    }

    // Implement &quot;Clear&quot; button
    const clearButton = document.getElementById(&quot;clearButton&quot;);
    clearButton.addEventListener(&quot;click&quot;, function() { 
        context.clearRect(0, 0, canvas.width, canvas.height);
        });

    // Implement &quot;Save&quot; button for testing
    const saveButton = document.getElementById(&quot;saveButton&quot;);
    saveButton.addEventListener(&quot;click&quot;, function() {
        var imgDataURL = getTinyImageURL();

        var downloadLink = document.createElement(&apos;a&apos;);
        downloadLink.href = imgDataURL;
        downloadLink.download = &apos;canvasImage.png&apos;;

        downloadLink.click();
    })

    // Implement &quot;Submit&quot; button
    const submitButton = document.getElementById(&quot;submitButton&quot;);
    submitButton.addEventListener(&quot;click&quot;, function() {
        updateProbabilities();
    })


&lt;/script&gt;

</description>
        <pubDate>Tue, 19 Mar 2024 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/projects/Course-Notes----Fastai.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/projects/Course-Notes----Fastai.html</guid>
      </item>
    
      <item>
        <title>Recipes</title>
        <description>&lt;h3 id=&quot;shortbread-cookies&quot;&gt;Shortbread Cookies&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Makes about 3-4 dozen cookies&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;226g unsalted butter&lt;/li&gt;
  &lt;li&gt;90g powdered sugar&lt;/li&gt;
  &lt;li&gt;1 tsp vanilla extract&lt;/li&gt;
  &lt;li&gt;280g AP flour&lt;/li&gt;
  &lt;li&gt;25g cornstarch&lt;/li&gt;
  &lt;li&gt;1/2 tsp salt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For best results, measure ingredients with a scale by weight.&lt;/p&gt;

&lt;p&gt;Mix together and refrigerate dough.&lt;/p&gt;

&lt;p&gt;Bake at 350degF (175degC) in a preheated oven for about 13-15min or until slightly golden brown.&lt;/p&gt;

&lt;h3 id=&quot;sernik-polish-cheesecake&quot;&gt;Sernik (Polish Cheesecake)&lt;!--more--&gt;&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;1.37kg twarog (farmer’s cheese)&lt;/li&gt;
  &lt;li&gt;100g sugar&lt;/li&gt;
  &lt;li&gt;somewhere between 1 tsp and 1 tbsp vanilla extract&lt;/li&gt;
  &lt;li&gt;5 eggs&lt;/li&gt;
  &lt;li&gt;50g corn starch&lt;/li&gt;
  &lt;li&gt;200mL heavy cream&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put the twarog in the mixer, add sugar, and vanilla extract, and mix.
Then add eggs, and mix.
Add corn starch, and mix.
Add heavy cream, mix.&lt;/p&gt;

&lt;p&gt;Take a 12”x8”x2” baking form, coated with butter, and pour the mix in (no higher than 1/2 to 2/3 of the height of the pan).&lt;/p&gt;

&lt;p&gt;Bake at 170degC (340degF) for 90 minutes (or until light brown on top).
After 90 min, turn the oven OFF.
Do not open the oven until it cools down!&lt;/p&gt;

&lt;h3 id=&quot;cornbread&quot;&gt;Cornbread&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Makes one small lodge griddle&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;4 tbsp unsalted butter&lt;/li&gt;
  &lt;li&gt;1/2 cup cornmeal&lt;/li&gt;
  &lt;li&gt;1/2 cup all-purpose flour&lt;/li&gt;
  &lt;li&gt;2 tbsp sugar&lt;/li&gt;
  &lt;li&gt;1/2 tsp kosher salt&lt;/li&gt;
  &lt;li&gt;1 tsp baking powder&lt;/li&gt;
  &lt;li&gt;1/8 tsp baking soda&lt;/li&gt;
  &lt;li&gt;1 egg&lt;/li&gt;
  &lt;li&gt;4 oz greek yogurt&lt;/li&gt;
  &lt;li&gt;6 oz buttermilk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Preheat oven (425F) and brown butter, mix ingredients by hand (no blender), and bake for ~20min. Works great in a cast iron griddle.&lt;/p&gt;

&lt;h3 id=&quot;banana-bread&quot;&gt;Banana Bread&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Work in progress.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;mochi-waffles&quot;&gt;Mochi Waffles&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Makes 4 waffles / one ‘square’ waffle-maker load&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dry Mix:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;1/4 cup oat flour&lt;/li&gt;
  &lt;li&gt;1/4 cup AP flour&lt;/li&gt;
  &lt;li&gt;1-1/4 cup mochiko&lt;/li&gt;
  &lt;li&gt;2 tsp baking powder&lt;/li&gt;
  &lt;li&gt;1 1/2 tsp salt&lt;/li&gt;
  &lt;li&gt;1/2 tsp cornstarch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wet Mix:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;1/2 cup grass-fed whey isolate&lt;/li&gt;
  &lt;li&gt;1-1/4 cup whole milk
(mix the above and let the protein powder hydrate)
then…&lt;/li&gt;
  &lt;li&gt;1/2 banana&lt;/li&gt;
  &lt;li&gt;1 egg&lt;/li&gt;
  &lt;li&gt;a dash of vanilla extract&lt;/li&gt;
  &lt;li&gt;1 tsp lemon juice&lt;/li&gt;
  &lt;li&gt;2 tbsp melted coconut oil (or butter)
(blend all of the above)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fold the resulting wet ingredient blend into the dry ingredients and mix until just combined. Pour into hot waffle maker and enjoy.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notes: Adjusting this again, to try to improve moisture while maintaining chewiness&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 12 Feb 2024 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/lists/Recipes.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/lists/Recipes.html</guid>
      </item>
    
      <item>
        <title>Athletics</title>
        <description>&lt;h3 id=&quot;update---10424&quot;&gt;Update - 1/04/24&lt;/h3&gt;

&lt;p&gt;Well, this is a few years out of date. The whole pandemic lasted a lot longer than I think anyone really expected. Especially with the California lockdowns.&lt;/p&gt;

&lt;p&gt;I wish I could say that left me with smooth and continuous progress, but it wouldn’t be true. We moved, had a kid, and I encountered a small host of minor, but lengthy, injuries. Along the way, I ended up making some changes to my routine.&lt;/p&gt;

&lt;p&gt;For lifting, I switched out of the tactical barbell program (with its focus on 1RM testing), and into a more “bodybuilding” style of lifting. 5 week long phases, with a lot more volume (sets of 10+), and a gradual peaking followed by a recovery week. I started this new routine in mid-December, 2020, and am currently halfway through Phase 19. At 5 nominal weeks / phase, that means I’ve been about 60% efficient with my lifting compared to an ideal schedule.&lt;/p&gt;

&lt;p&gt;I’ve also ended up with a better table tennis setup at home. I’ve now got a table, robot, and most importantly, enough room to use it, so drills with that have become a regular part of my routine. I’ll write about my shot accuracy tracking system in a later update.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Overall, my best guess has me in pretty good overall shape. I definitely don’t have the level of conditioning that I did when I was spending 10+ hours a week at the table tennis clubs pre-pandemic, and I definitely don’t have the level of raw, 1RM strength that I did at the peak of that training, but I’m at an acceptable middle on both of those, with a clear improvement in strength-endurance (from the focus on greater volume of reps) as well as body composition.&lt;/p&gt;

&lt;p&gt;In the meantime, I’ve got clear directions to go for improvement, and the most important step is the next one.&lt;/p&gt;

&lt;h3 id=&quot;update---102720&quot;&gt;Update - 10/27/20&lt;/h3&gt;

&lt;p&gt;Latest graphs at the end of a bulk cycle.&lt;/p&gt;

&lt;p&gt;Bench press 1RM stayed the same, but my shoulder injury is almost totally healed, so… win some, lose some?&lt;/p&gt;

&lt;p&gt;Not pictured here is my progress with kettlebells which I’ve added as a recurring part of my routine (because really, who computes 1RMs for kettlebell swings?). In any case, I’ve worked my way up to 2-hand swings with a 24kg bell, 1-handed swings with a 20kg bell, and Turkish Get-Ups with a 20kg bell. Unfortunately, I’ll pretty soon be maxed out with the kettlebells that I have (only have up to 24kg), so I’ve started to keep an eye on the usual suspects (Rogue and Vulcan, I’m looking at you!) for their next restock.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/1RMs-2020-10-27.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/strength-to-weight-2020-10-27.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;update---9220&quot;&gt;Update - 9/2/20&lt;/h3&gt;

&lt;p&gt;Latest graphs at the end of another 6-week Tactical Barbell cycle.&lt;/p&gt;

&lt;p&gt;My bench press dropped a bit due to sustaining and recovering from a minor shoulder injury.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/1RMs-2020-09-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/strength-to-weight-2020-09-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;update---61420&quot;&gt;Update - 6/14/20&lt;/h3&gt;

&lt;p&gt;Latest graphs at the end of another 6-week Tactical Barbell cycle.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/1RMs-2020-06-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/strength-to-weight-2020-06-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;where-i-began&quot;&gt;Where I began&lt;/h3&gt;

&lt;p&gt;As a child, I never really did any form of organized sports. Sure, I did some karate classes, and even participated in a t-ball league for a few months in… first grade?, but I have almost no memory of those times, and it wasn’t sustained enough to count.&lt;/p&gt;

&lt;p&gt;My first real experience with athletics instead came from joining the cross-country and track teams during freshman and sophomore year of high school.&lt;/p&gt;

&lt;p&gt;To be honest, I think my main reason for joining them was because &lt;em&gt;that’s what the nerds did&lt;/em&gt; at my high school. &lt;em&gt;Everyone knew&lt;/em&gt; that PE sucked, and for some reason or another, there was only one alternative for nerds: cross country in the fall, and track &amp;amp; field in the winter and spring. So that’s what my friends and I did.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;I hated cross country. Running long distances was, and still is to me, an exercise in ever-increasing boredom and pain. I learned that I could do it, as in, I could physically move my body through space for the eight or nine miles of any given run, or the more intense but shorter 3 mile races, but I also learned that I didn’t enjoy it. Not by a long shot.&lt;/p&gt;

&lt;p&gt;Track was better. You could choose your events! They had sprints! I primarily ran hurdles (I was tall) and the 400m. And unlike cross country, since everyone wasn’t competing simultaneously, you could actually go watch and cheer on your friends. Everything about this was fantastic.&lt;/p&gt;

&lt;p&gt;Track also taught me some valuable, though somewhat tangential, skills: how to cheer really, really loudly; how to mentally cope with interval sprints; and that if you intentionally lie to your friends by calling out their split times a few seconds slower than they really are, you can get your friends to try harder and thereby set new PRs, and while they’ll thank you afterwards, they’ll also think you’re a maniac.&lt;/p&gt;

&lt;p&gt;Once sophomore year was over, I had fulfilled my 2-year “PE” requirement, and I dropped the organized athletics entirely to focus on the more important math and science competitions in my life.&lt;/p&gt;

&lt;p&gt;Throughout this period, I had only minimal exposure to strength training. I had seen the inside of a weight room before, and of course I had seen any manner of targeted weight machine, but I did not understand them, nor did I feel even remotely comfortable with them.&lt;/p&gt;

&lt;h3 id=&quot;college-years&quot;&gt;College years&lt;/h3&gt;

&lt;p&gt;Going into Caltech, I wanted to get back into athletics, and I had an growing interest in strength training.&lt;/p&gt;

&lt;p&gt;Over the summer before my freshman year, I had picked up a copy of Arnold Schwarzenegger’s “The New Encyclopedia of Modern Bodybuilding” which was, by weight, 99% an encyclopedia of every exercise you can imagine, and 1% thoughts about how to structure them together as a coherent program. Nevertheless, once rotation was over and all the chaos of move-in and adjusting to the new world had settled down, I began to hit the weight room—and track, for more of those interval sprint workouts!—on an extremely irregular basis with a variety of friends over the years.&lt;/p&gt;

&lt;p&gt;Notable memories include watching a post-doc I knew doing bench press with ~140lbs on the bar—he was using the &lt;em&gt;big&lt;/em&gt; plates!—and visiting the much less-well air conditioned, much grittier, but much more viscerally enjoyable weight room at Los Alamos during the summer research fellowship I did there.&lt;/p&gt;

&lt;p&gt;By far, though, the most major thing to happen to my athletic trajectory during my time at Caltech was about two weeks before I was supposed to move in early for pre-season track &amp;amp; field training (hurdles again!), when I was flipping through the course catalog and saw a listing for “table tennis”. Three thoughts passed through my head in quick succession: college is about trying new things, right?; I enjoy playing ping pong in my back yard…; and “you know… hurdles &lt;em&gt;are&lt;/em&gt; kind of boring…”.&lt;/p&gt;

&lt;p&gt;I switched over.&lt;/p&gt;

&lt;p&gt;In pleasing symmetry, there were three important things that I didn’t realize at that point:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;I had accidentally signed up for the advanced section.&lt;/li&gt;
  &lt;li&gt;The coach, Wei, used to play professionally in China, and played on the US Olympic squad after emigrating.&lt;/li&gt;
  &lt;li&gt;Table tennis was a sport that many learned to play from a very young age, and most of those in the advanced section had been playing for years.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It was immediately obvious that I had no idea what I was doing.&lt;/p&gt;

&lt;p&gt;After the first session, the coach came up to me and asked if I was sure I had signed up for the correct section, and explained that maybe I would be better off switching on one of the beginner/intermediate groups. Not to be deterred, I decided that instead of switching sections, I would simply attend &lt;em&gt;all&lt;/em&gt; of the sections every week. This would prove to be one of the best ideas of my life.&lt;/p&gt;

&lt;p&gt;Over the next four years, I became, though certainly not the best, one of the better players at Caltech, and built wonderful, and enduring, friendships with many people through the table tennis community. My lengthy discussions about technique with Wei easily taught me as much physics as several of the courses I was taking for my degree, and the stability and sleep-requirements of that training became a rock that I could lean on to ground and support myself through the harder trials of those years.&lt;/p&gt;

&lt;p&gt;Notable memories include one exhausting day in San Diego when we decided to field three teams amongst a total of 6 people at a NCTTA tournament; getting to coach our Women’s team at nationals for two years in a row (first in Columbus, OH, and then in Rochester, MN); and traveling up to Stanford in 2007 to watch the World Junior Championships being hosted there.&lt;/p&gt;

&lt;h3 id=&quot;2008-2010&quot;&gt;2008-2010&lt;/h3&gt;

&lt;p&gt;The two years after I graduated were more tumultuous for me. I moved across the country twice before finally settling in Mountain View, I switched jobs several times, and finally ended up diving into the startup world while working on natural language processing applied to email database analysis.&lt;/p&gt;

&lt;p&gt;During this time, I continued to play table tennis at whichever club was most convenient for wherever I was living, but the organized training I enjoyed while at Caltech was largely absent.&lt;/p&gt;

&lt;p&gt;Meanwhile, I had no regular gym/weight room access, so that ended up on the back-burner.&lt;/p&gt;

&lt;h3 id=&quot;2010-2016&quot;&gt;2010-2016&lt;/h3&gt;

&lt;p&gt;Before moving up to Silicon Valley in 2010, I became more seriously interested in strength training, picked up a copy of the &lt;a href=&quot;https://startingstrength.com/&quot;&gt;Starting Strength&lt;/a&gt; book, and a set of Ivanko weights and barbell off of someone on craigslist in Los Angeles. When I finally moved into a place with a garage, I built a squat rack and a bench—both wooden! I know!—and got to training. The bench was a beautiful piece that I still have and use as regular furniture. The squat rack was a wobbly, scary piece of kit with only two hook positions available (one for bench press and one for squats), but hey, at least it had safety rails. And it was cheap.&lt;/p&gt;

&lt;p&gt;It was with that setup that I set a number of PRs. My working weight for three sets of five reps passed 250 lbs on squats, 150 lbs on bench press, 115 lbs for standing press, and 300 lbs on deadlift (ok, just for one set of five reps, not three sets on deadlift). During the later part of this period, I moved again, no longer had a garage, and joined Boss Barbell Club, where in that impressive company, I notably improved my working weight for squats up to my all-time PR of 275 lbs. You learn a new kind of respect for gravity when you pass the point of having more than your entire body weight on a barbell on your back, so I can only imagine the focus and dedication required of those athletes at BBBC whom I saw squatting 500, 600, and even 700+ lbs.&lt;/p&gt;

&lt;p&gt;This time period also led to a renaissance in my table tennis training. If you’re familiar with table tennis in the US, you know that California is one of the hot spots. And if you’re familiar with table tennis in California, you know that the bay area, in particular, is Mecca.&lt;/p&gt;

&lt;p&gt;If you’re not familiar with the scene, understand that in most areas of the US, and even elsewhere in the world, table tennis clubs are often share their facilities part-time with other groups, either as part of independent businesses, or as part of a community recreation center. Thus, while it’s not unheard of, it’s also not the most common thing to find a club with a dedicated space. Even once you find such a club, it’s rarer still that they will be set up and equipped with professional-grade flooring and lighting—things that make a significant difference for the quick, lateral movements of the sport, or when lobbing and smashing high balls.&lt;/p&gt;

&lt;p&gt;The bay area is composed of many small cities, and each city has a dedicated club with professional flooring and lighting. Some cities have several. Opposite the situation elsewhere, it is &lt;em&gt;rare&lt;/em&gt; here to find a club that only has a part-time facility, or one that subjects players to playing on wooden or tile flooring. Professional-grade equipment, dedicated facilities, and top-tier players are de rigueur.&lt;/p&gt;

&lt;p&gt;For further comparison, in last US National Championships in 2019, every one of the four finalists in both the women’s and men’s singles came from a club in the bay area, and in fact, from a group of three clubs, all within a four-mile-radius circle on the map.&lt;/p&gt;

&lt;p&gt;Playing table tennis here has been fantastic. After browsing between several clubs, I picked one and have been a regular at their trainings and league events (though I still drop in at other clubs, time permitting), and my technical understanding and ability with the game have continued to improve.&lt;/p&gt;

&lt;h3 id=&quot;2016-2017&quot;&gt;2016-2017&lt;/h3&gt;

&lt;p&gt;These years were challenging for me due to an incidence of back injury. On several occasions, I ended up tweaking my back to the point where I could not move out of bed the next day without excruciating pain. I reset my working weights for lifting back down to zero several times, and I had to take care to slowly reintroduce even the intensity of my table tennis training.&lt;/p&gt;

&lt;p&gt;I struggled for a solution until I encountered the work of &lt;a href=&quot;https://www.backfitpro.com/&quot;&gt;Stuart McGill&lt;/a&gt;, who I eventually ended up visiting in his home office in Canada. His life’s work is understanding the biomechanics of the back and torso, and working with individuals and athletes of every caliber (including many olympians and world record holders) to rehab and return to form after injuries.&lt;/p&gt;

&lt;p&gt;His methods were magic. Not in the sense that he was able to speak a short incantation, wave his hands, and &lt;strong&gt;bam&lt;/strong&gt; my problems were resolved, but in that unlike any of my prior consultations and appointments, he went into great depth to understand the specific issues I was facing, and his recommendations, like the &lt;a href=&quot;https://www.youtube.com/watch?v=2_e4I-brfqs&quot;&gt;McGill Big 3&lt;/a&gt;, when applied diligently, finally and completely resolved all of my problems.&lt;/p&gt;

&lt;p&gt;After that, I also adjusted my strength training routines to accommodate my McGill-inspired focus on resiliency and stability: I traded barbell squats for Bulgarian split squats, and moved all of my deadlifting to sumo-style.&lt;/p&gt;

&lt;h3 id=&quot;2018-2020&quot;&gt;2018-2020&lt;/h3&gt;

&lt;p&gt;The last few years have seen, by far, the greatest progress in athletics of my life. This comes down to three things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;A change in my responsibilities with my job meant that I no longer had to travel to Florida one week out of every four. Hello improved consistency!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;I changed strength training programs. After much searching, and some trial and error on my own, I settled into a routine following the progressive training templates in &lt;a href=&quot;http://www.tacticalbarbell.com/&quot;&gt;Tactical Barbell&lt;/a&gt;. The problem prior to this is that the energy demands of my lifting and table tennis training in parallel had grown to be too large, and so I would often find myself either tired at table tennis from my lifting the night before, or experiencing slower gains in lifting due to the long sessions of table tennis. The Tactical Barbell program is the best I’ve encountered yet for structuring strength training as a supplementary activity to your main sport, and has supported my progress in both, wonderfully.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;a href=&quot;https://renaissanceperiodization.com/rp-diet-app&quot;&gt;RP App&lt;/a&gt;. A close friend of mine went to work for that company, and recommended I try out their app. Now, I had done various forms of diet tracking before, following templates, and even building an eventually-surprisingly-exhaustive database of nutrition facts for Trader Joe’s products, I had only really had relatively middling success. I often had difficulty maintaining the trajectories of my bulk or cut diets, and attempting cut diets, especially, was always miserable.&lt;/p&gt;

    &lt;p&gt;Enter RP. Like you might expect, to use the RP diet app, you have to tell it what kind of a diet you want to do (muscle-building, maintenance, or fat-loss), and some basic things about yourself and your schedule (height, weight, daily wake-up &amp;amp; sleep times, and workout timing and duration). What you—and I, certainly!—might not expect is that not only will it tell you how much protein, carbs, and fat to eat each day, but it will also tell you &lt;em&gt;when to eat it&lt;/em&gt;. Things like “1:15pm - 30g protein, 15g fat, 20g carbs”. This makes a &lt;strong&gt;huge&lt;/strong&gt; difference. By getting your individual meal timing and sizing right, you can optimize for your individual metabolism, and, when on a fat-loss diet for example, can give your body the regularly-spaced doses of protein it needs to maintain muscle mass, while still being in a caloric deficit to encourage fat loss.&lt;/p&gt;

    &lt;p&gt;Bonus points to the RP app for &lt;em&gt;also&lt;/em&gt; giving you an easy way to select what you’re about to eat from a whole range of different foods, cooking styles, and even by scanning barcodes, and then automatically calculating what total weight of foods you should consume to hit your target macros.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So that brings us to roughly today, and the events of my &lt;a href=&quot;https://www.usuallypragmatic.com/misc/Quarantine-Projects.html&quot;&gt;Quarantine Projects&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;finally-ill-end-with-some-progress-graphs-from-my-use-of-the-tactical-barbell-routine&quot;&gt;Finally, I’ll end with some progress graphs from my use of the Tactical Barbell routine:&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/1RMs.png&quot; alt=&quot;1RMs and bodyweight over time&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/projects/athletics/strength-to-weight.png&quot; alt=&quot;Strength-to-Weight Ratios&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 04 Jan 2024 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/projects/Athletics.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/projects/Athletics.html</guid>
      </item>
    
      <item>
        <title>Thoughts on &quot;The Twelve-Factor App&quot;</title>
        <description>&lt;p&gt;These notes are a stream-of-consciousness response to reading through &lt;a href=&quot;https://12factor.net/&quot;&gt;The Twelve-Factor App&lt;/a&gt; at the suggestion of a good friend of mine.&lt;/p&gt;

&lt;h3 id=&quot;introduction-and-background&quot;&gt;Introduction and Background&lt;/h3&gt;

&lt;p&gt;Nothing particularly special here. At this high of a level of abstraction, everything sounds like a good and reasonable idea!&lt;/p&gt;

&lt;h3 id=&quot;section-1-codebase&quot;&gt;Section 1: Codebase&lt;/h3&gt;

&lt;p&gt;Not too much controversial in here (I hope!). I like the emphasis on strict delineation of codebases between apps, and factoring out shared code into separate libraries under dependency management.&lt;/p&gt;

&lt;h3 id=&quot;section-2-dependencies&quot;&gt;Section 2: Dependencies&lt;!--more--&gt;&lt;/h3&gt;

&lt;p&gt;This one requires some rigor and automated test tools for enforcement!&lt;/p&gt;

&lt;p&gt;Their ending note about extending the philosophy to system tools makes plenty of sense, though it does start to make me wonder how they would handle system tools that might need to be rebuilt for different micro architectures… seems troublesome to end up with nested system compatibility issues…&lt;/p&gt;

&lt;h3 id=&quot;section-3-config&quot;&gt;Section 3: Config&lt;/h3&gt;

&lt;p&gt;This one is an interesting distinction. Of course you don’t want to save credentials and the like into your code repo, but storing all config as environment variables feels a little like you’re just pushing the problem down the road… you still need tools to set up and manage those env vars for any sufficiently complicated setup, and especially if a single user might need to switch between various configs (when, say, deploying to dev vs test vs qa) it feels like it would be very easy to accidentally end up in a world where your config is now stored in a management program or downloaded from a source location.&lt;/p&gt;

&lt;h3 id=&quot;section-4-backing-services&quot;&gt;Section 4: Backing Services&lt;/h3&gt;

&lt;p&gt;This is a reasonable set of definitions and goals, but leaves a little bit of documentation and organization discussion to be desired. For example, if you’re using a SQL database as a resource, you may also need to track specific version requirements for that database implementation–especially if you’re relying on specific and/or unusual functionality–but even in the general case, you may want to specify version requirements to align with your testing environment, even if only to make sure to be able to replicate behavior where bugs may be concerned.&lt;/p&gt;

&lt;p&gt;These sorts of situations would require some extra state to be stored somewhere beyond just the resource handle.&lt;/p&gt;

&lt;h3 id=&quot;section-5-build-release-run&quot;&gt;Section 5: Build, release, run&lt;/h3&gt;

&lt;p&gt;Again reasonable, with some additional potential trickery around dealing with exploding database sizes in cases where the release may include large binaries / etc.&lt;/p&gt;

&lt;h3 id=&quot;section-6-processes&quot;&gt;Section 6: Processes&lt;/h3&gt;

&lt;p&gt;Very reminiscent of my time with Haskell. I dig it, but there are probably consequences of this approach that I’m not immediately appreciating.&lt;/p&gt;

&lt;h3 id=&quot;section-7-port-binding&quot;&gt;Section 7: Port Binding&lt;/h3&gt;

&lt;p&gt;This is one I’ll tag for deeper discussion. There’s definitely some stuff I don’t fully grok about sentences like “does not rely on runtime injection of a webserver into the execution environment to create a web-facing service”.&lt;/p&gt;

&lt;p&gt;For example, what would doing so even mean or entail? Why might you be tempted to do so?&lt;/p&gt;

&lt;h3 id=&quot;section-8-concurrency&quot;&gt;Section 8: Concurrency&lt;/h3&gt;

&lt;p&gt;A few questions in here also. What does “daemonizing” mean? What are PID files? Is there some formalism for “process types” that I should be aware of, or is it just a question of nomenclature, fully under the control of the devs?&lt;/p&gt;

&lt;h3 id=&quot;section-9-disposability&quot;&gt;Section 9: Disposability&lt;/h3&gt;

&lt;p&gt;This again seems like a “mathematically pure” thought, but one that’s devilish to police via testing in practice. In particular, the linked wikipedia page on “reentrant” was surprisingly subtle.&lt;/p&gt;

&lt;h3 id=&quot;section-10-devprod-parity&quot;&gt;Section 10: Dev/prod parity&lt;/h3&gt;

&lt;p&gt;Nice, here’s some discussion of the issues I was thinking about from the “Backing Services” section. Overall this seems like an obviously good idea. I wonder what situations would make it maximally difficult.&lt;/p&gt;

&lt;h3 id=&quot;section-11-logs&quot;&gt;Section 11: Logs&lt;/h3&gt;

&lt;p&gt;Huh. This is definitely an idea in the same vein as the previous ten sections, but it surprised me on first read nonetheless. Just logging everything straight to stdout and leaving log routing and collection to the execution environment definitely makes sense given the rest of this framework. I’ll have to chew on this one a little more to see what I really think of it, but so far no objections, even if it is a change in how I’ve been thinking.&lt;/p&gt;

&lt;h3 id=&quot;section-12-admin-processes&quot;&gt;Section 12: Admin processes&lt;/h3&gt;

&lt;p&gt;This doesn’t actually seem like it’s &lt;em&gt;saying&lt;/em&gt; much of anything at all. Basically the message is “standardize everything you can, and use tools to make sure of it”.&lt;/p&gt;

&lt;p&gt;Is there something more to this that I’m missing?&lt;/p&gt;
</description>
        <pubDate>Tue, 02 Jan 2024 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/blog/2024-01-02-Thoughts-on-The-Twelve-Factor-App.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/blog/2024-01-02-Thoughts-on-The-Twelve-Factor-App.html</guid>
      </item>
    
      <item>
        <title>London Recommendations; pre-pandemic</title>
        <description>&lt;p&gt;I know some people headed to London soon, so for them and anyone else, here are my London recommendations. Do note that these all date from my trips before the onset of covid-19, so you should check the actual availability / openings of things for your specific visit.&lt;/p&gt;

&lt;h2 id=&quot;cocktail-bars&quot;&gt;Cocktail Bars&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.top50cocktailbars.com/bar_profile/dandelyan-at-the-mondrian-hotel/&quot;&gt;Dandelyan&lt;/a&gt; is absolutely one of the best bars in the world, and certainly the most pioneering of the cocktail bars I’ve presonally visited. These are the sort of people who don’t just use a banana syrup in their drinks, they spend weeks making their own banana syrup, from a plethora of different banana species and individual fruit at different levels of ripeness, each ingredient prepared individually to highlight certain flavor elements in the final syrup. The correct way to visit Dandelyan is to show up as close to their opening time as possible—early in the day!—and grab seats at the bar. Then talk the bartender’s ear off. Ask them about the background behind the drinks. Ask them about the ingredients. How they refined the recipes. What surprised them the most. Order whatever you want, but don’t feel pressured to finish everything, or even anything! The best visits here will give you a chance to sample flavors you simply won’t find anywhere else, and it’s perfectly fine to leave half-finished drinks when you’re done. Delight your taste buds. Save your liver.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.mr-foggs.com/&quot;&gt;Mr Fogg’s&lt;/a&gt; are top-notch cocktail bars with a lean towards flair and adventure. If Dandelyan is a science lab, then the Mr Fogg’s bars are Disneyland. Tons of fun, really good drinks, and plenty of atmosphere, theme, and delight. You simply can’t leave without a smile. Mr Fogg’s are best visited a little later in the evening. Your goal shouldn’t be to grab time with the bartender while it’s still uncrowded; instead, get there only a little bit on the early side, so that you can watch it fill up, kick back, and enjoy the celebration that’s sure to surround you.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;restaurants&quot;&gt;Restaurants&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.hopperslondon.com/&quot;&gt;Hoppers&lt;/a&gt; is one of my favorite restaurants in the entire world. It has a focus on Sri Lankan and South Indian food, so expect bold flavors! But everything, &lt;em&gt;everything&lt;/em&gt;, is delicious. Special shout-out to the bone marrow.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.dishoom.com/&quot;&gt;Dishoom&lt;/a&gt; is a series of Indian restaurants in London. They’re much bigger than Hoppers, and tend to have somewhat less bold and specific flavors, but are still delicious, and just extremely solid for a meal.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;other&quot;&gt;Other&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.yelp.com/biz/ty-seven-dials-timberyard-london-2&quot;&gt;Timber Yard Seven Dials&lt;/a&gt; is my favorite coffee shop in all of London. I love the crowds. I love the coffee. I love the location. And I love the snacks. I’ve set up shop there for days at a time, speed-running an online course, just as easily as I’ve used it as an excuse to step in from the cold and enjoy a quick, warm drink.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://boroughmarket.org.uk/&quot;&gt;Borough Market&lt;/a&gt; is the best damn food market I’ve ever encountered, only Torvehallerne in Copenhagen comes close. Come for the duck wraps. Come back for the charcuterie. Come back again for the cheeses. Come back yet again for the baked goods. Come back one more time for whatever else you feel like. It’s all great. Then hit up the hot chocolate from across the street. It’s all fantastic.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.timeout.com/london/restaurants/afternoon-tea-in-london&quot;&gt;High tea&lt;/a&gt; is worth doing at least once. On every week. Of every trip. Honestly, it’s a little kitsch, but it’s delicious, it’s fun, you’ve got a billion excellenet choices to pick from, and it’s &lt;em&gt;so&lt;/em&gt; London. Note that some of the more expensive options have a refill policy that can actually be quite a good value for your money if you’re hungry enough. For example, I have &lt;em&gt;definitely not ever&lt;/em&gt; taken advantage of the Langham’s infinite refills on sandwiches to consume in excess of 23 delicious little tea sandwiches in a single sitting.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;non-food-thoughts&quot;&gt;Non-Food Thoughts&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Have at least one set of nice clothes. There are plenty of places in London which, unlike California, actually have dress codes. This means at least pants, a button-down shirt, and a blazer for men. Flip flops and sneakers need not apply.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It’ll probably rain. You can deal with it. You won’t melt. And honestly, while you should pack a reasonable coat, you probably don’t need to bring an umbrella. If it’s raining &lt;em&gt;that&lt;/em&gt; hard, you can always buy a cheap one when you’re there, or borrow one from your hotel.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Shows are a lot of fun! You should try one!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Festivals / exhibitions / etc are worth watching out for. Something or other is always passing through London, and you can easily lose a day—or more!—in any of the excellent museums.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;London has a bunch of great bookshops! Even though I do almost all of my reading on something with a screen these days, I love browsing around and picking up something with pages every once in a while.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Yelp has been really quite reasonable for me in London. Also Uber.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;There’s really not much need to plan day trips in advance if you don’t mind taking the train (and you shouldn’t! it’s great!). Just show up at the station, buy a ticket, and grab the next one.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If you’re visiting London for a while, dealing with laundry can be surprisingly tricky. Hotels often charge &lt;em&gt;very&lt;/em&gt; high rates, so you may be best served with a local wash-and-fold service.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The parks and walking paths are great. There are few things I enjoy more than meeting up with friends in London and catching up over a walk. In any direction. From anywhere. To anywhere. It’s great! Bonus points if you end up passing through one of the many parks, which are always lovely.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Shopping is… a thing? I guess? Fortnum &amp;amp; Mason has great tea, and we always bring back a bunch with us whenever we go. Beyond that, London is certainly a major metropolis, with more than enough wealth and fashions to support just about any sort of shopping experience you’re looking for.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;There are tourist attractions. They usually have lines. At least, I’ve usually seen lines whenever I’ve walked by them. I dunno, it’s not really my thing. I’d much rather wander through Soho with a cup of coffee, or crash a table tennis club somewhere.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Speaking of which, activity clubs are myriad in London, and well worth looking up for your trip. Whatever your hobby, you’re very likely to be able to find some club or gathering for it in the city during your visit, and that’s a great way to make friends, have a great time, and get the inside scoop on whatever you want from some locals.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 11 Dec 2021 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/blog/2021-12-11-London-Recommendations-pre-pandemic.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/blog/2021-12-11-London-Recommendations-pre-pandemic.html</guid>
      </item>
    
      <item>
        <title>Course Notes -- Coursera - Andrew Ng&apos;s Machine Learning Introduction and Deep Learning Specialization</title>
        <description>&lt;h3 id=&quot;im-back-with-another-round-of-course-notes-this-time-from-courseras-machine-learning-by-andrew-ng-as-well-as-the-entire-deep-learning-specialization-sequence&quot;&gt;I’m back with another round of course notes, this time from Coursera’s &lt;a href=&quot;https://www.coursera.org/learn/machine-learning&quot;&gt;Machine Learning, by Andrew Ng&lt;/a&gt;, as well as the entire &lt;a href=&quot;https://www.coursera.org/specializations/deep-learning&quot;&gt;Deep Learning Specialization&lt;/a&gt; sequence.&lt;/h3&gt;

&lt;p&gt;My history with these courses and material was curious. Much of the background mathematics, including calculus, I became extremely familiar with through the course of my physics degree years ago. Then, back around 2011, I went through the first run of Caltech’s &lt;a href=&quot;https://home.work.caltech.edu/telecourse.html&quot;&gt;Learning From Data&lt;/a&gt; online class which was, as is usual for Caltech, a tour de force of &lt;em&gt;even more math&lt;/em&gt;, to really drill to the core of some of the most fundamental concepts in the field of machine learning. But at the time, it was obviously missing some of the more recent focus on neural networks, so I put in a mental bookmark to return to the subject and catch up on more recent developments once I had the opportunity.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;That opportunity came recently, as a friend and I worked through the OG Machine Learning Introduction class on Coursera by Andrew Ng. This was a really great survey, but still felt a little dated, and certainly lacked many of the more recent developments in Deep Learning, so I still wanted more.&lt;/p&gt;

&lt;p&gt;Done with the intro class, I started looking at Coursera’s Deep Learning Specialization sequence: a series of 5 courses, focused directly at deep learning techniques up to about 2017-2018.&lt;/p&gt;

&lt;p&gt;The fateful moment came when I noticed that Coursera wanted a $49/month subscription¹ to access the course materials, but gave a 7-day “free trial” period.&lt;/p&gt;

&lt;p&gt;Now, if you know me at all, you know that I don’t go for half measures of “slow and steady” progress. I’ve even written an essay on the subject called &lt;a href=&quot;https://www.usuallypragmatic.com/essays/Slow-and-Steady-is-Bullshit.html&quot;&gt;Slow and Steady is Bullshit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So I saw the words “7-day free trial”, and read them as a challenge. All I’d have to do would be to exceed my usual pace of 1-week of a course per day, and accelerate it to 1-entire-course per day. Keep up that pace for five days, and I’d be done with time to spare.&lt;/p&gt;

&lt;p&gt;If this sounds insane, that’s because it probably was (at least a little bit?). It was also only conceivable through the confluence of several factors: my previously-established deep familiarity with mathematics, my fluency with the python programming language (which was also the language of choice for the courses), the fact that the courses in the specialization sequence were shorter than is usual for semester-length classes (~2-4 weeks of material each, rather than ~12), and the browser console one-liner &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$(&apos;video&apos;).playbackRate = 3.5&lt;/code&gt; to override the default maximum playback speeds of the lecture videos.&lt;/p&gt;

&lt;h3 id=&quot;so-i-targeted-a-weekend-took-a-couple-days-off-on-either-side-canceled-or-turned-down-all-of-my-other-plans-and-got-to-work&quot;&gt;So I targeted a weekend, took a couple days off on either side, canceled or turned down all of my other plans, and got to work.&lt;/h3&gt;

&lt;object data=&quot;https://www.usuallypragmatic.com/attachments/projects/course-notes-andrew-ng/Coursera-Andrew_Ng_Machine_Learning.pdf&quot; type=&quot;application/pdf&quot; style=&quot;min-height:100vh;width:100%&quot;&gt;Fallback: this browser does not support PDFs. Please &lt;a href=&quot;https://www.usuallypragmatic.com/attachments/projects/course-notes-andrew-ng/Coursera-Andrew_Ng_Machine_Learning.pdf&quot;&gt;download the PDF&lt;/a&gt; to view it.
&lt;/object&gt;

&lt;p&gt;&lt;a href=&quot;https://www.usuallypragmatic.com/attachments/projects/course-notes-andrew-ng/Coursera-Andrew_Ng_Machine_Learning.pdf&quot;&gt;Download my course notes as a PDF.&lt;/a&gt;&lt;/p&gt;

&lt;object data=&quot;https://www.usuallypragmatic.com/attachments/projects/course-notes-andrew-ng/Coursera-Deep_Learning_Specialization.pdf&quot; type=&quot;application/pdf&quot; style=&quot;min-height:100vh;width:100%&quot;&gt;Fallback: this browser does not support PDFs. Please &lt;a href=&quot;https://www.usuallypragmatic.com/attachments/projects/course-notes-andrew-ng/Coursera-Deep_Learning_Specialization.pdf&quot;&gt;download the PDF&lt;/a&gt; to view it.
&lt;/object&gt;

&lt;p&gt;&lt;a href=&quot;https://www.usuallypragmatic.com/attachments/projects/course-notes-andrew-ng/Coursera-Deep_Learning_Specialization.pdf&quot;&gt;Download my course notes as a PDF.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Long story short, I succeeded right on plan at a pace of 1 course per day, finishing the entire Deep Learning Specialization in 5 consecutive days. This was intense, and by the end I was literally dreaming about multiheaded attention and LSTMs. But, on the other hand, I’m now psyched and ready to dive into even newer developments in the field of deep learning since the 2017-2018 cutoff dates of the specialization.&lt;/p&gt;

&lt;p&gt;I don’t know that I would recommend this extreme speedrun approach to others. In my case it was literally only possible because I already had a very solid background on all of the tools necessary for the course, and heck, it even helped that I had already spent a while getting used to the sound of Andrew Ng’s voice on significant speedup during the Machine Learning Intro class!&lt;/p&gt;

&lt;p&gt;That said, if you want to learn through these courses yourself, figure out what sacrifices you can make, and then do it as fast as you can. Slow and steady is still bullshit.&lt;/p&gt;

&lt;hr /&gt;

&lt;ol&gt;
  &lt;li&gt;$49 / month is really a very reasonable amount of money to charge for access to the quality of material in the Deep Learning Specialization. No qualms there, and hats off to Coursera for providing such excellent lectures, notes, exercises, programming assignments, and exams.&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Mon, 16 Aug 2021 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/projects/Course-Notes----Coursera---Andrew-Ng-Machine-Learning-and-Deep-Learning-Specialization.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/projects/Course-Notes----Coursera---Andrew-Ng-Machine-Learning-and-Deep-Learning-Specialization.html</guid>
      </item>
    
      <item>
        <title>Unit Vector Orthogonality and What It Means For You</title>
        <description>&lt;p&gt;I talk a lot about comparative advantage, and finding ways to trade on it. But one of the things I’ve never directly defended is the idea that strong comparative advantages can exist, and that you can improve your chances of developing such comparative advantages by studying more or less anything at all.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;So, here’s a quantitative estimate.&lt;/p&gt;

&lt;p&gt;Imagine forming a multi-dimensional vector representing your level of productivity on various tasks. Now, asking whether you are likely to have serious comparative advantages compared to someone else is akin to asking whether your productivity-vector points in a different direction to theirs. What are the odds of that happening, even in the worst case scenario, where your study is left to chance?&lt;/p&gt;

&lt;p&gt;To get an idea of the numbers, we’ll pick some different dimensionalities, generate a bunch of random unit vectors of each dimensionality, and just look at the angle between the vectors of the same dimensionality. To make things even more concrete, we’ll pick a cutoff (in this case, ±2°) and ask “What is the chance of two randomly generated unit vectors of a given dimensionality being within ±2° of 90°?” This will tell us not only the chance of having a significant angle between the two vectors, but the chance of the two vectors being nearly maximally un-aligned. Or, in other words, the chance of really significant comparative advantages existing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/blog/unit_vector_orthogonality.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So there it is. Study things—almost anything at all, and the more the better—and you’ll be practically guaranteed to develop significant comparative advantages that you can use for mutually beneficial trade.&lt;/p&gt;
</description>
        <pubDate>Sun, 04 Jul 2021 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/blog/2021-07-04-Unit-Vector-Orthogonality-and-What-It-Means-For-You.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/blog/2021-07-04-Unit-Vector-Orthogonality-and-What-It-Means-For-You.html</guid>
      </item>
    
      <item>
        <title>Communication, Management, and Leadership in Startups</title>
        <description>&lt;blockquote&gt;
  &lt;p style=&quot;text-align: center;&quot;&gt;&lt;em&gt;– tl;dr –&lt;/em&gt;&lt;/p&gt;

  &lt;p&gt;To &lt;strong&gt;communicate&lt;/strong&gt; well, apply techniques of error-correcting conversations, especially whenever someone says something that sounds dumb, or otherwise doesn’t make sense:&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;
      &lt;p&gt;Make sure you’ve heard their words correctly. “Did you just say &lt;em&gt;&amp;lt;the words you heard&amp;gt;&lt;/em&gt;?”&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;p&gt;Use your understanding to create a prediction for an implication outside the immediate bounds of what they’ve said, and see if &lt;em&gt;their&lt;/em&gt; understanding agrees with &lt;em&gt;your&lt;/em&gt; prediction. “Does that mean that we would also expect X/Y/Z?”&lt;/p&gt;
    &lt;/li&gt;
    &lt;li&gt;
      &lt;p&gt;Rinse and Repeat.&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;

  &lt;p&gt;&lt;strong&gt;Management&lt;/strong&gt; is about developing comparative advantages, both within yourself, and among your teams. The goal for yourself is to minimize context switching costs on a daily basis. The goal for your teams is to ensure that no matter what surprise tomorrow brings, your team has a spread of comparative advantages that will let it tackle the work with efficiency and effectiveness.&lt;/p&gt;

  &lt;p&gt;As an addendum, when hiring, forget the adage about “T-shaped people”. Instead, seek out and hire Koosh ball people: people with multiple, separate areas of deep skill. This maximizes the chance of your team members having really distinct and applicable comparative advantages, no matter the challenges ahead.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;Leaders&lt;/strong&gt; have two jobs: to cultivate pervasive trust, and to delegate well.&lt;/p&gt;

  &lt;p&gt;There’s a lot said about culture, and most of it is BS. The only thing that matters in a startup’s culture is whether or not all members of the company share a deep trust with each other. The operative question is “Would they take a bullet for me?”. When asked from anyone’s perspective, and directed at anyone else, the answer had better be “yes”. As a leader, judge every action, policy, incentive, and plan with regards to whether it deepens or depletes trust.&lt;/p&gt;

  &lt;p&gt;Delegation is a two-way contract. It must have a clear vision and strategy defined from above, and tactical authority and true acceptance from below. The delegator specifies the goal and the delegatee specifies what they need to accomplish it. Vitally, the delegatee must truly be able to say no if they deem the task impossible given the resource constraints.&lt;!--more--&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;em&gt;Startups are hard. These are my guidelines for making them a little bit easier.&lt;/em&gt;&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;em&gt;These thoughts are, of course, applicable to many other situations in life as well, but by using the word “startup”, I hope to attract the attention of people in startups, for whom this advice may make a tangible difference between success and failure.&lt;/em&gt;&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;em&gt;This is the most directly actionable advice I have, distilled from more than a decade in the field, and I wish someone had presented it to me, in just this way, when I was new.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;communication&quot;&gt;Communication&lt;/h2&gt;

&lt;p&gt;The typical communication involves three distinct translation steps.&lt;/p&gt;

&lt;p&gt;First, an &lt;em&gt;idea&lt;/em&gt; in one person’s mind must be translated into &lt;em&gt;words that are spoken&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Second, the &lt;em&gt;spoken words&lt;/em&gt; are translated into &lt;em&gt;heard words&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And third, the &lt;em&gt;heard words&lt;/em&gt; are translated into an &lt;em&gt;idea&lt;/em&gt; in the second person’s mind. Each of these translation steps is an opportunity for errors to creep in, and miscommunication to result.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://www.usuallypragmatic.com/images/essays/cml_in_startups/error_correcting_conversations.png&quot; alt=&quot;a typical miscommunication&quot; /&gt;
&lt;em&gt;this happens to everyone&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the origin of a peculiar paradox: everyone has heard plenty of other people say dumb things, yet when asked, everyone will tell you that they try very hard not to say dumb things themselves!&lt;/p&gt;

&lt;p&gt;The solution is that most of the time when something sounds dumb, it’s because the idea that you’ve ended up with in your mind (after three steps of potential translation error) doesn’t match the idea that was in the speaker’s mind. Thus, they may have been trying to express an idea that made perfect sense to them, but by the time it’s reached you it just seems sort of stupid… &lt;em&gt;because it’s not the same idea&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Most of the time you can resolve these sorts of issues by borrowing a page from the scientific method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Clean your data. Make sure you’ve heard them correctly by just repeating their words back to them and asking if that’s what they’ve said.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Come up with a prediction about an implication of the idea that’s outside the direct bounds of what they’ve just said, and see if they agree with your prediction.&lt;/p&gt;

&lt;p&gt;Step 2 is usually the tricky one. The idea here is that since there’s no way to directly compare the neural pulses in your brain with those in theirs, the best you can do is try to make sure that all of the predictions that arise from the idea in your mind match all of the predictions of the idea in their mind. If this is broadly true, then for all practical intents and purposes, the two ideas are the same.&lt;/p&gt;

&lt;h3 id=&quot;here-are-some-examples-of-what-this-might-look-like&quot;&gt;Here are some examples of what this might look like:&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Person A:&lt;/em&gt; “Unemployment is bad.”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person B:&lt;/em&gt; “Do you mean that no one should be allowed to quit their job and take time off?”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person A:&lt;/em&gt; “No! Just that if too many people want jobs and can’t find them, it’s not good.”&lt;/p&gt;

&lt;p&gt;– or –&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person A:&lt;/em&gt; “Facts aren’t always true.”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person B:&lt;/em&gt; “What? Like linear differential equations don’t have unique solutions?”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person A:&lt;/em&gt; “Naw, just that when someone shows up with some data, you have to question it! How was it collected? Is there a bias towards one viewpoint above others? Which industry group paid for it?”&lt;/p&gt;

&lt;p&gt;– or even –&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person A:&lt;/em&gt; “This surface needs to be smooth.”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person B:&lt;/em&gt; “So you mean you want it to be polished so it doesn’t feel rough?”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Person A:&lt;/em&gt; “More than that! We have to make sure that reflections on any part don’t have sudden changes!”&lt;/p&gt;

&lt;h2 id=&quot;management&quot;&gt;Management&lt;/h2&gt;

&lt;p&gt;Management is about developing and ensuring comparative advantages, so that tasks can get done as efficiently and effectively as possible.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;em&gt;If you’d like a refresher on comparative advantages and why they’re important, check out the beginning of my essay on &lt;a href=&quot;https://www.usuallypragmatic.com/essays/Comparative-Advantage-and-the-Theory-of-Intertemporal-Self-Trade.html&quot;&gt;Comparative Advantage and the Theory of Intertemporal Self-Trade&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For managing yourself&lt;/strong&gt;, you can create comparative advantages between different days by trying to arrange your schedule to minimize context-switching costs. This is related to Paul Graham’s idea of the &lt;a href=&quot;http://paulgraham.com/makersschedule.html&quot;&gt;Maker Schedule vs Manager Schedule&lt;/a&gt;, but slightly more expansive.&lt;/p&gt;

&lt;p&gt;Of course, a la PG, it’s better to schedule meetings together in a concentrated batch, and ideally to keep them fully separate from blocks of time dedicated to deep work. But we can go further than this and say that even among blocks of deep work, it’s usually more efficient to focus on just one thing at a time, for as long as possible; so if you’ve got a to-do list that consists of a database migration, refining a new SVM model, and setting up A/B tests for marketing copy, for the love of god, do them one at a time if at all possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managing teams&lt;/strong&gt; is a little different. The focus becomes learning the distinct comparative advantages of your team and ensuring that your team members are free to dedicate themselves to work that aligns closely with their comparative advantages. Most teams get this right to first order—have the database experts work on the database, and the UI designers focus on the frontend—but in the case of startups, first order correctness doesn’t help much when you’re working with fewer engineers than you’d like, most of them generalists, and you certainly don’t have entire &lt;em&gt;departments&lt;/em&gt; dedicated to specific functions.&lt;/p&gt;

&lt;p&gt;In those cases you’ve got two options, and you should pursue them both simultaneously.&lt;/p&gt;

&lt;p&gt;On one hand, get to know your team members. Watch their performance on various tasks closely and build up a good mental model—as accurate as you can!—of their comparative advantages. Figure out who’s the fastest for exploratory work, and who’s the most thorough for vital functions. Determine who can hold their own in open presentations, and who prefers communication through written documentation. And do your damndest to make sure that every one of your team members gets to focus on their comparative advantages.&lt;/p&gt;

&lt;p&gt;On the other hand, be open with your team members and talk to them, often, about where they see their current comparative advantages, and what new ones they’d like to develop—they might surprise you! And of course, it’s vital to not only encourage your team members to develop new or deeper comparative advantages, you must make doing so part of their job. This means that continuing education can not be optional; time must be formally and officially set aside for it.&lt;/p&gt;

&lt;p&gt;Continuing education can be tricky to mandate. Too often, it turns into useless corporate classes and gets viewed as a chore. Instead, it’s best to leave the direction and method of the learning completely up to the individual doing the learning. If they want to audit a class online, then they get to audit a class! If they want to study a book, then they get to study a book! And if their chosen topics don’t align directly with the work they’re currently doing, so much the better: it just means that when new, unexpected challenges come down the line tomorrow, you’re more likely to have someone able to tackle them.&lt;/p&gt;

&lt;p&gt;To judge their efforts, simply suggest some sort of presentation on the learnings at the end. This can be as elaborate as showing off a small project to other teammates, or as simple as a verbal discussion with you (their manager) or another colleague. The important part is to ensure interaction with an outside voice that can ask questions, for that is when some of the most valuable learning takes place. Study groups, in particular, are excellent at this.&lt;/p&gt;

&lt;h3 id=&quot;a-note-on-hiring&quot;&gt;A note on hiring…&lt;/h3&gt;

&lt;p&gt;The goal in hiring is to bring in new team members who have sets of comparative advantages that serve as good complements to those possessed by your current team members. The problem is that while you may know what tasks need doing today—and so you can interview for them—you will not generally know what tasks need doing tomorrow.&lt;/p&gt;

&lt;p&gt;The solution is to try to pick candidates who have significant additional comparative advantages outside of the set that you directly need for your current tasks. &lt;a href=&quot;https://en.wikipedia.org/wiki/Koosh_ball&quot;&gt;Koosh ball&lt;/a&gt; people instead of &lt;a href=&quot;https://en.wikipedia.org/wiki/T-shaped_skills&quot;&gt;T-shaped people&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The way I do this is to ask candidates in interviews to “teach me something technical”. I tell them to pick a topic they’re very comfortable with, and then as they teach me about it, I will ask questions about related ideas or corner cases that hopefully they haven’t encountered directly before. I even tell them exactly what I’m looking for: not particularly &lt;em&gt;correct&lt;/em&gt; answers (because I’m not likely to be a good judge of correctness on a topic I’m probably unfamiliar with), but instead that I’m looking to understand their thought process and approach when I throw them a curveball.&lt;/p&gt;

&lt;p&gt;Once they pick a topic and dive in, I let them talk for maybe fifteen minutes or so, asking only clarifying questions at first, so that I understand what they’re telling me. Then I take a moment and come up with my curveball. This is almost always just asking them to reconsider the topic with some change to one of their fundamental assumptions: either a difference in constraint, a difference in the scale of some number, or similar.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For example, here are some descriptions of actual interviews:&lt;/p&gt;

  &lt;p&gt;Candidate A told me about their time working on nuclear power plants, and described in detail the challenges associated with the cooling systems. I asked them “Imagine that word of your expertise gets around, and tomorrow NASA shows up at your door, wanting a nuclear reactor for a new space station. How does your cooling system change without gravity?”.&lt;/p&gt;

  &lt;p&gt;Candidate B told me about a mesh sensor network that they put together for their garden. I asked them “How would you tackle this if your garden was huge and you still wanted to instrument every plant? What if it wasn’t just a garden, but a full scale farm?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The point is not what solution they give to the curveball question, but how carefully they think through it. A bad answer will be simple: “Oh, I would just change X and that would be it”. A great answer will show them progressing down, discovering and resolving issues as they consider the ripple effects of your modified assumption: “Well, the biggest effect from that change would be X, which we could try solving by adjusting Y, but then that brings up the question of Z…”.&lt;/p&gt;

&lt;p&gt;There is no topic that can survive a change in scale of multiple orders of magnitude, or the switching of a basic assumption, without triggering a fractal cascade of effects. The only metric is how far down that chain they can go.&lt;/p&gt;

&lt;p&gt;The reason I do this is to learn how deeply the candidate digs into topics that they’re faced with. If the answer is “very deeply indeed”, then you can be pretty confident that they probably bring this behavior to lots of topics, and so they’re almost certain to have plenty of deep comparative advantages to bring to the table outside their direct job description.&lt;/p&gt;

&lt;p&gt;In a startup, you need these people. They’re the only way to get ahead of the curve and give your team the best chance possible of having suitable comparative advantages already in place when unexpected challenges show up¹.&lt;/p&gt;

&lt;h2 id=&quot;leadership&quot;&gt;Leadership&lt;/h2&gt;

&lt;p&gt;The only thing that matters in a company’s culture is &lt;strong&gt;deep, mutual trust&lt;/strong&gt; between all of the team members at the company, and as a leader, you are responsible for cultivating that trust.&lt;/p&gt;

&lt;p&gt;This is important, so I’ll say it again.&lt;/p&gt;

&lt;p&gt;No one actually cares if you have ping pong tables, dogs in the office, weekly happy hours and board game nights, or even an on-site masseuse. Those are all bullshit and meaningless towards the success of your startup if you don’t have deep, mutual trust. Similarly, if you &lt;em&gt;do&lt;/em&gt; have deep, mutual trust, you can be working out of an unfurnished basement for all anyone cares, and still have full engagement from your team and produce amazing results.&lt;/p&gt;

&lt;p&gt;The metric for this trust is the question “Would they take a bullet for me?”. This doesn’t need to be literal, but the gist is that anyone in your company, thinking of anyone else in the company that they interact with, should feel assured that the other person would be willing to take risk, flak, or trouble onto themselves for the sake of the questioner.&lt;/p&gt;

&lt;p&gt;This means managers taking the heat when one of their team screws up. It means colleagues giving credit to otherwise invisible advice from others when it helps their project succeed. And it means the CEO rolling up their sleeves and turning a god damned wrench if it’s truly “all hands on deck”.&lt;/p&gt;

&lt;p&gt;As a leader, you need to evaluate everything around you for whether it encourages or diminishes this kind of trust. Get it right and prosper with engaged colleagues, good retention, and full buy-in to the mission. Get it wrong and suffer.&lt;/p&gt;

&lt;p&gt;For example, if you want to make sure that your remote employees feel like a full part of the team, don’t bring them into HQ for a bonding offsite, but send your HQ team on an offsite to the remote location.&lt;/p&gt;

&lt;p&gt;Another: don’t expect your team leads to take flak for their reports if the VPs don’t take flak for their team leads in turn. And make this metric a part of their performance reviews!&lt;/p&gt;

&lt;p&gt;Jeszcze raz². If the CEO is leaving the office while other team members are still crunching, then the CEO had better offer to get them coffee on the way out.&lt;/p&gt;

&lt;h3 id=&quot;delegating-well&quot;&gt;Delegating well&lt;/h3&gt;

&lt;p&gt;Too many people think that delegation is simply the act of telling someone else what to do. This is a recipe for disaster, missed deadlines, and a breakdown of trust.&lt;/p&gt;

&lt;p&gt;Instead, delegation must be a two-way contract.&lt;/p&gt;

&lt;p&gt;The delegator is charged with maintaining a comparative advantage in understanding the bigger picture, and specifying the desired goal.&lt;/p&gt;

&lt;p&gt;The delegatee should have a comparative advantage (and freedom of choice!) in the tactical implementation required to achieve the specified goal, and crucially, must be responsible for specifying the needed resources (people/time/material)³.&lt;/p&gt;

&lt;p&gt;Finally, the delegator and delegatee must reach an agreement as to the final nature of the goal, and resources available to reach it. This must be a real agreement. That means that the delegatee &lt;em&gt;must be able to say no&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Without the ability to say “no”, it is far too easy to default into an endless stream of under-resourced death marches, chasing impossible goals and achieving little besides record burnout and employee churn.&lt;/p&gt;

&lt;p&gt;Do note that the ability to say “no” doesn’t mean that you have to arrive at “yes” on the first pass. It’s completely reasonable to take a couple rounds of back-and-forth between the delegator and delegatee, carefully refining the precise definition of the goal, and likewise the precise resources needed to achieve it. This is an incredibly valuable process⁴.&lt;/p&gt;

&lt;p&gt;Delegation and trust are tied together. Proper delegation enhances trust. Poor delegation destroys it.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;&lt;em&gt;One final note: much of this last section on leadership is distilled from the insight of two sources: &lt;a href=&quot;https://smile.amazon.com/Boyd-Fighter-Pilot-Who-Changed-ebook/dp/B000FA5UEG/&quot;&gt;Robert Coram’s biography of John Boyd&lt;/a&gt; and &lt;a href=&quot;https://www.amazon.com/Certain-Win-Strategy-Applied-Business-ebook/dp/B0793SDYSM/&quot;&gt;Chet Richards’s book on applying the strategy of John Boyd to business&lt;/a&gt;. Both are excellent reads.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Or, as we call it in startups, “on Tuesday”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;“Jeszcze raz” – roughly “once again” in Polish.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;This is the only time I will come close to referring to “people” as “resources”. I hate it when this is done, and only do it here because I’m using “resources” to mean a broader set, including also time, equipment, tooling, money, etc. If you use the word “resources” when all you really mean is “people”, then then only thing you’re doing is obfuscating and anonymizing the fact that you’re referring to &lt;em&gt;human beings&lt;/em&gt;, and there is surely a special place in hell for you… right next to people who talk at the theater.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Also known as “planning”.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Thu, 01 Jul 2021 00:00:00 +0000</pubDate>
        <link>https://www.usuallypragmatic.com/essays/Communication-Management-and-Leadership-in-Startups.html</link>
        <guid isPermaLink="true">https://www.usuallypragmatic.com/essays/Communication-Management-and-Leadership-in-Startups.html</guid>
      </item>
    
  </channel>
</rss>

