Jekyll2021-03-05T21:29:20+00:00https://switzerb.github.io/imposter/feed.xmlImposter SyndromeMy "travel" journal of coding practice and exploration. This blog is about my experiences with software engineering, both the painful and the enjoyable. The intention here is less "tutorial" than "conversing about a topic I love". There are already many tutorials out there and frankly it makes me uncomfortable to position myself as an authority - I am constantly aware of how much there is to learn for any given topic.
Writing software is delightful madness, personal obsession and an endless source of both frustration and joy. It is my hope that my writing here will both create a vehicle for deeper understanding for myself as well as spark conversation and connection with anyone who lands here and reads. Feel free to drop me a line at hello@brennaswitzer.com.Kotlin Comparable2021-03-02T00:00:00+00:002021-03-02T00:00:00+00:00https://switzerb.github.io/imposter/kotlin,/toolkit/2021/03/02/comparble-and-sort<p>By default, the order of elements will be in <code class="language-plaintext highlighter-rouge">natural order</code> - 5 is greater than 2, -4 is greater than -10, b is greater than a, etc.</p>
<h2 id="comparable">Comparable</h2>
<p>To define natural order for a user-defined type, you can implement the interface <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-comparable/">Comparable</a>. Kotlin also provides an additional advantage that the instance implementing Comparable interface can be compared using relational operators:</p>
<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">data class</span> <span class="nc">Fruit</span><span class="p">(</span>
<span class="kd">val</span> <span class="py">taste_ranking</span><span class="p">:</span> <span class="nc">Int</span><span class="p">,</span>
<span class="kd">val</span> <span class="py">name</span><span class="p">:</span> <span class="nc">String</span><span class="p">,</span>
<span class="kd">val</span> <span class="py">color</span><span class="p">:</span> <span class="nc">String</span>
<span class="p">)</span> <span class="p">:</span> <span class="nc">Comparable</span><span class="p"><</span><span class="nc">Fruit</span><span class="p">></span> <span class="p">{</span>
<span class="c1">// defines natural order for the type Fruit</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">compareTo</span><span class="p">(</span><span class="n">other</span><span class="p">:</span> <span class="nc">Fruit</span><span class="p">):</span> <span class="nc">Int</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">taste_ranking</span> <span class="p">!=</span> <span class="n">other</span><span class="p">.</span><span class="n">taste_ranking</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="n">taste_ranking</span> <span class="p">-</span> <span class="n">other</span><span class="p">.</span><span class="n">taste_ranking</span>
<span class="p">}</span> <span class="k">else</span> <span class="mi">0</span>
<span class="p">}</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">toString</span><span class="p">():</span> <span class="nc">String</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">name</span>
<span class="p">}</span>
<span class="kd">val</span> <span class="py">grape</span> <span class="p">=</span> <span class="nc">Fruit</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s">"Grape"</span><span class="p">,</span> <span class="s">"purple"</span><span class="p">)</span>
<span class="kd">val</span> <span class="py">mango</span> <span class="p">=</span> <span class="nc">Fruit</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s">"Mango"</span><span class="p">,</span> <span class="s">"orange"</span><span class="p">)</span>
<span class="kd">val</span> <span class="py">strawberry</span> <span class="p">=</span> <span class="nc">Fruit</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="s">"Strawberry"</span><span class="p">,</span> <span class="s">"red"</span><span class="p">)</span>
<span class="kd">val</span> <span class="py">breadfruit</span> <span class="p">=</span> <span class="nc">Fruit</span><span class="p">(-</span><span class="mi">10</span><span class="p">,</span> <span class="s">"Breadfruit"</span><span class="p">,</span> <span class="s">"beige"</span><span class="p">)</span>
<span class="nf">println</span><span class="p">(</span><span class="n">grape</span> <span class="p">></span> <span class="n">mango</span><span class="p">)</span> <span class="c1">//false</span>
<span class="nf">println</span><span class="p">(</span><span class="n">strawberry</span> <span class="p">></span> <span class="n">breadfruit</span><span class="p">)</span> <span class="c1">//true</span>
</code></pre></div></div>
<h2 id="comparators">Comparators</h2>
<p>To create more nuanced sorting or custom ordering, create a <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-comparator/">Comparator</a> for the user-defined type. Note the use of this below returns a copy of the list and does not sort in-place.</p>
<p>Using the above <code class="language-plaintext highlighter-rouge">Fruit</code> type:</p>
<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// A comparator to compare Fruit by color </span>
<span class="kd">class</span> <span class="nc">FruitByColor</span> <span class="p">:</span> <span class="nc">Comparator</span><span class="p"><</span><span class="nc">Fruit</span><span class="p">></span> <span class="p">{</span>
<span class="k">override</span> <span class="k">fun</span> <span class="nf">compare</span><span class="p">(</span><span class="n">o1</span><span class="p">:</span> <span class="nc">Fruit</span><span class="p">?,</span> <span class="n">o2</span><span class="p">:</span> <span class="nc">Fruit</span><span class="p">?):</span> <span class="nc">Int</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">o1</span> <span class="p">==</span> <span class="k">null</span> <span class="p">||</span> <span class="n">o2</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">o1</span><span class="p">.</span><span class="n">color</span><span class="p">.</span><span class="nf">compareTo</span><span class="p">(</span><span class="n">o2</span><span class="p">.</span><span class="n">color</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">val</span> <span class="py">fruits</span> <span class="p">=</span> <span class="nf">listOf</span><span class="p">(</span><span class="n">grape</span><span class="p">,</span> <span class="n">mango</span><span class="p">,</span> <span class="n">strawberry</span><span class="p">,</span> <span class="n">breadfruit</span><span class="p">)</span>
<span class="nf">rintln</span><span class="p">(</span><span class="n">fruits</span><span class="p">.</span><span class="nf">sortedWith</span><span class="p">(</span><span class="nc">FruitByColor</span><span class="p">()))</span> <span class="c1">//[Breadfruit, Mango, Grape, Strawberry]</span>
</code></pre></div></div>
<h2 id="mutable-and-immutable-sorting">Mutable and Immutable Sorting</h2>
<p>For sorting, you can choose whether you would like to sort in-place or return a sorted copy of the object.
<code class="language-plaintext highlighter-rouge">sort()</code> sorts a mutable collection in-place and <code class="language-plaintext highlighter-rouge">sorted()</code> creates a new collection. Note that you can’t sort an immutable type in-place.</p>
<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kd">val</span> <span class="py">sortedFruit</span> <span class="p">=</span> <span class="n">fruits</span><span class="p">.</span><span class="nf">sorted</span><span class="p">()</span>
<span class="nf">println</span><span class="p">(</span><span class="n">fruits</span><span class="p">)</span> <span class="c1">// [Grape, Mango, Strawberry, Breadfruit]</span>
<span class="nf">println</span><span class="p">(</span><span class="n">sortedFruit</span><span class="p">)</span> <span class="c1">// [Breadfruit, Grape, Mango, Strawberry]</span>
<span class="n">fruits</span><span class="p">.</span><span class="nf">sort</span><span class="p">()</span> <span class="c1">// throws an error</span>
<span class="n">fruits</span><span class="p">.</span><span class="nf">toMutableList</span><span class="p">().</span><span class="nf">sort</span><span class="p">()</span>
<span class="nf">println</span><span class="p">(</span><span class="n">fruits</span><span class="p">)</span> <span class="c1">//[Grape, Mango, Strawberry, Breadfruit]</span>
</code></pre></div></div>By default, the order of elements will be in natural order - 5 is greater than 2, -4 is greater than -10, b is greater than a, etc.React Router Auth and Typescript and Hooks2021-02-28T00:00:00+00:002021-02-28T00:00:00+00:00https://switzerb.github.io/imposter/typescript/2021/02/28/typescript-react-router<p>I recently transitioned a small app I built for my son to Typescript, to get some more practical “sandbox-y” experience with the language structures. The app is a tiny budgeting tool for kids (that <em>mostly</em> helps him see how much money he’s spent on Fortnite) and it only has a handful of views. It’s a React front end and a Firebase backend.</p>
<p>The app, like many React projects, uses the <a href="https://reactrouter.com/">React Router</a> library for routing and navigation. When attempting to get a simple authentication flow in place, I ran into a couple of interesting challenges that I thought I’d note down here, for future me.</p>
<p>You can see the full auth flow demonstrated all in one place here in <a href="https://codesandbox.io/s/typscript-router-sandbox-otfln?file=/src/App.tsx">codesandbox</a>. And you can see the code broken down into separate components and integrated with Firebase Auth <a href="https://github.com/switzerb/money-blender/tree/master/src">in the Github repo here</a>.</p>
<p>In the React Router docs, they give a simple example of an auth redirect flow: <a href="https://reactrouter.com/web/example/auth-workflow">React Router Auth Workflow</a>. It’s using Context and Hooks to create an <code class="language-plaintext highlighter-rouge">Auth Provider</code> component to easily be able to access authentication information and to direct navigational business logic. The most interesting part for me was this wrapper component, that wraps the <code class="language-plaintext highlighter-rouge">Route</code> library component with an auth check, that will automatically redirect to login if the user is not authenticated. See how the render prop is conditional based on the presence of the user?</p>
<figure class="highlight"><pre><code class="language-javascript" data-lang="javascript"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre><span class="kd">function</span> <span class="nx">PrivateRoute</span><span class="p">({</span> <span class="nx">children</span><span class="p">,</span> <span class="p">...</span><span class="nx">rest</span> <span class="p">})</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">auth</span> <span class="o">=</span> <span class="nx">useAuth</span><span class="p">();</span>
<span class="k">return</span> <span class="p">(</span>
<span class="o"><</span><span class="nx">Route</span>
<span class="p">{...</span><span class="nx">rest</span><span class="p">}</span>
<span class="nx">render</span><span class="o">=</span><span class="p">{({</span> <span class="nx">location</span> <span class="p">})</span> <span class="o">=></span>
<span class="nx">auth</span><span class="p">.</span><span class="nx">user</span> <span class="p">?</span> <span class="p">(</span>
<span class="nx">children</span>
<span class="p">)</span> <span class="p">:</span> <span class="p">(</span>
<span class="o"><</span><span class="nx">Redirect</span>
<span class="nx">to</span><span class="o">=</span><span class="p">{{</span>
<span class="na">pathname</span><span class="p">:</span> <span class="dl">"</span><span class="s2">/login</span><span class="dl">"</span><span class="p">,</span>
<span class="na">state</span><span class="p">:</span> <span class="p">{</span> <span class="na">from</span><span class="p">:</span> <span class="nx">location</span> <span class="p">}</span>
<span class="p">}}</span>
<span class="sr">/</span><span class="err">>
</span> <span class="p">)</span>
<span class="p">}</span>
<span class="sr">/</span><span class="err">>
</span> <span class="p">);</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>
<p>Below, you can see the wrapped component in Typescript, with just a few changes. I’ve defined a type for the props, to make it clearer what is happening here and used a syntax to render the component child that I feel is more intuitive for me. I am not completely happy with the spread here, since I think it introduces a lot of wiggle into the component, but since it was a personal project I just let it sit as-is.</p>
<figure class="highlight"><pre><code class="language-typescript" data-lang="typescript"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre><span class="kd">type</span> <span class="nx">PrivateRouteProps</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">path</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span>
<span class="nl">exact</span><span class="p">?:</span> <span class="nx">boolean</span><span class="p">;</span>
<span class="nl">component</span><span class="p">:</span> <span class="nx">React</span><span class="p">.</span><span class="nx">FC</span><span class="o"><</span><span class="nx">RouteComponentProps</span><span class="o">></span><span class="p">;</span>
<span class="p">};</span>
<span class="kd">function</span> <span class="nx">PrivateRoute</span><span class="p">({</span> <span class="na">component</span><span class="p">:</span> <span class="nx">Component</span><span class="p">,</span> <span class="p">...</span><span class="nx">rest</span> <span class="p">}:</span> <span class="nx">PrivateRouteProps</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">auth</span> <span class="o">=</span> <span class="nx">useAuth</span><span class="p">();</span>
<span class="k">return</span> <span class="p">(</span>
<span class="o"><</span><span class="nx">Route</span>
<span class="p">{...</span><span class="nx">rest</span><span class="p">}</span>
<span class="nx">render</span><span class="o">=</span><span class="p">{(</span><span class="na">props</span><span class="p">:</span> <span class="nx">RouteComponentProps</span><span class="p">)</span> <span class="o">=></span>
<span class="nx">auth</span> <span class="o">&&</span> <span class="nx">auth</span><span class="p">.</span><span class="nx">user</span> <span class="p">?</span> <span class="p">(</span>
<span class="o"><</span><span class="nx">Component</span> <span class="p">{...</span><span class="nx">props</span><span class="p">}</span> <span class="sr">/</span><span class="err">>
</span> <span class="p">)</span> <span class="p">:</span> <span class="p">(</span>
<span class="o"><</span><span class="nx">Redirect</span>
<span class="nx">to</span><span class="o">=</span><span class="p">{{</span>
<span class="na">pathname</span><span class="p">:</span> <span class="dl">"</span><span class="s2">/login</span><span class="dl">"</span><span class="p">,</span>
<span class="na">state</span><span class="p">:</span> <span class="p">{</span> <span class="na">prevPath</span><span class="p">:</span> <span class="nx">rest</span><span class="p">.</span><span class="nx">path</span> <span class="p">}</span>
<span class="p">}}</span> <span class="sr">/</span><span class="err">>
</span> <span class="p">)</span>
<span class="p">}</span>
<span class="sr">/</span><span class="err">>
</span> <span class="p">);</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></figure>I recently transitioned a small app I built for my son to Typescript, to get some more practical “sandbox-y” experience with the language structures. The app is a tiny budgeting tool for kids (that mostly helps him see how much money he’s spent on Fortnite) and it only has a handful of views. It’s a React front end and a Firebase backend.Dijkstra’s Two-Stack Algorithm2021-01-12T00:00:00+00:002021-01-12T00:00:00+00:00https://switzerb.github.io/imposter/algorithms/2021/01/12/dijkstra-two-stack<p>Dijkstra was pretty good at his job, as evidenced by the fact that his name is on a bunch of useful algorithms. This is one that was put in front of me as I was trying to solve <a href="https://adventofcode.com/2020/day/18">Advent of Code, Day 18 2020</a>. I’d never heard of it so thought I’d look in more detail.</p>
<p>The gist of the puzzle (you can read the full text above) is evaluating arithmetic expressions in a way that is non-standard, like so:</p>
<p><code class="language-plaintext highlighter-rouge">The homework (your puzzle input) consists of a series of expressions that consist of addition (+), multiplication (*), and parentheses ((...)). Just like normal math, parentheses indicate that the expression inside must be evaluated before it can be used by the surrounding expression. Addition still finds the sum of the numbers on both sides of the operator, and multiplication still finds the product.</code></p>
<p><code class="language-plaintext highlighter-rouge">However, the rules of operator precedence have changed. Rather than evaluating multiplication before addition, the operators have the same precedence, and are evaluated left-to-right regardless of the order in which they appear.</code></p>
<p>So the gist is that you start with an expression like <code class="language-plaintext highlighter-rouge">((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2</code> and get an answer of <code class="language-plaintext highlighter-rouge">23340</code> instead of <code class="language-plaintext highlighter-rouge">3208</code> like you’d get with a calculator.</p>
<p>–</p>
<p>Although I was able to solve the puzzle without Dijkstra’s Two-Stack Algorithm, once it was pointed out to me I saw immediately how much better a solution it is. I also discovered via Google it is a <a href="http://faculty.cs.niu.edu/~hutchins/csci241/eval.htm">totally standard CS 201 thing to do</a>. Yet another opportunity for me to beat myself up for not studying computer science in school when I had the chance.</p>
<p>I found a succinct explanation of the algorithm from <a href="https://www.cis.upenn.edu/~matuszek/">David Matuszek on his magnificent web page</a> which I have shamelessly used to further my own understanding of the fundamentals of computer science.</p>
<p>I also learned about <code class="language-plaintext highlighter-rouge">infix</code> and <code class="language-plaintext highlighter-rouge">prefix</code> and <code class="language-plaintext highlighter-rouge">postfix</code> arithmetic expressions, which I was unaware of. It’s a way of changing the syntax of a mathematical expression without changing the semantic. It was interesting to learn this since I’ve been watching my son work his way through math word problems in the fifth grade and it’s…there is a lot of overlap. It’s incredible to see how much the <strong>way you talk</strong> about a problem affects the <strong>way you solve</strong> it.</p>
<h3 id="format-of-arithmetic-expressions">Format of Arithmetic Expressions</h3>
<p><strong>Infix</strong> is operators between operands: <code class="language-plaintext highlighter-rouge">3 + 4</code></p>
<p><strong>Prefix</strong> is operators before operands: <code class="language-plaintext highlighter-rouge">+ 3 4</code></p>
<p><strong>Postfix</strong> is operators after operands: <code class="language-plaintext highlighter-rouge">3 4 +</code></p>
<p>Humans are more effective understanders of infix and computers prefer postfix…so something to remember as a handy rule of thumb for translation. The algorithm below is for infix expressions.</p>
<h3 id="dijkstras-two-stack-algorithm-in-plain-english-language-words">Dijkstra’s Two-Stack Algorithm, In Plain English Language Words:</h3>
<p>You need two stacks, a value stack (operands), and an operator stack. Numbers will be double values, operators will be char values. The whole of the expression is made up of <code class="language-plaintext highlighter-rouge">items</code> - the “stuff”, ignoring whitespace.</p>
<ol>
<li>While there are still items to read
<ol>
<li>Get the next item</li>
<li>If the item is:
<ol>
<li><strong>A number</strong>: push it onto the value stack.</li>
<li><strong>A left parenthesis</strong>: push it onto the operator stack.</li>
<li><strong>A right parenthesis</strong>:
<ol>
<li>While the top of the operator stack is not a left parenthesis
<ol>
<li>Pop the operator from the operator stack.</li>
<li>Pop the value stack twice, getting two operands.</li>
<li>Apply the operator to the operands, in the correct order.</li>
<li>Push the result onto the value stack.</li>
</ol>
</li>
<li>Pop the left parenthesis from the operator stack</li>
</ol>
</li>
<li><strong>An operator</strong> <code class="language-plaintext highlighter-rouge">op</code>:
<ol>
<li>While the operator stack is not empty, and the top of the
operator stack has the same or greater precedence as <code class="language-plaintext highlighter-rouge">op</code>,
<ol>
<li>Pop the operator from the operator stack.</li>
<li>Pop the value stack twice, getting two operands.</li>
<li>Apply the operator to the operands, in the correct order.</li>
<li>Push the result onto the value stack.</li>
</ol>
</li>
<li>Push <code class="language-plaintext highlighter-rouge">op</code> onto the operator stack.</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
<li>While the operator stack is not empty,
<ol>
<li>Pop the operator from the operator stack.</li>
<li>Pop the value stack twice, getting two operands.</li>
<li>Apply the operator to the operands, in the correct order.</li>
<li>Push the result onto the value stack.</li>
</ol>
</li>
<li>At this point the operator stack should be empty, and the value
stack should have only one value in it, which is the final result.</li>
</ol>
<p>You can see a lot of opportunity here for helper methods and for more efficiency, but the logic is clean and intuitive. In any case, once I got over myself and learned a bit, I re-implemented the puzzle solution. Here is a part of what I ended up with, that represents the algorithm above:</p>
<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">private</span> <span class="k">fun</span> <span class="nf">result</span><span class="p">(</span><span class="n">op</span><span class="p">:</span> <span class="nc">Char</span><span class="p">,</span> <span class="n">a</span><span class="p">:</span> <span class="nc">Long</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nc">Long</span><span class="p">):</span> <span class="nc">Long</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">when</span><span class="p">(</span><span class="n">op</span><span class="p">)</span> <span class="p">{</span>
<span class="sc">'+'</span> <span class="p">-></span> <span class="n">a</span> <span class="p">+</span> <span class="n">b</span>
<span class="sc">'-'</span> <span class="p">-></span> <span class="n">a</span> <span class="p">-</span> <span class="n">b</span>
<span class="sc">'*'</span> <span class="p">-></span> <span class="n">a</span> <span class="p">*</span> <span class="n">b</span>
<span class="sc">'/'</span> <span class="p">-></span> <span class="n">a</span> <span class="p">/</span> <span class="n">b</span>
<span class="k">else</span> <span class="p">-></span> <span class="k">throw</span> <span class="nc">IllegalArgumentException</span><span class="p">(</span><span class="s">"$op is not a recognized operator."</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">fun</span> <span class="nf">evaluate</span><span class="p">(</span><span class="n">expr</span><span class="p">:</span> <span class="nc">CharIterator</span><span class="p">)</span> <span class="p">:</span> <span class="nc">Long</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">ops</span> <span class="p">=</span> <span class="nc">MutableStack</span><span class="p"><</span><span class="nc">Char</span><span class="p">>();</span>
<span class="kd">val</span> <span class="py">values</span> <span class="p">=</span> <span class="nc">MutableStack</span><span class="p"><</span><span class="nc">Long</span><span class="p">>();</span>
<span class="k">while</span> <span class="p">(</span><span class="n">expr</span><span class="p">.</span><span class="nf">hasNext</span><span class="p">())</span> <span class="p">{</span>
<span class="kd">val</span> <span class="py">c</span> <span class="p">=</span> <span class="n">expr</span><span class="p">.</span><span class="nf">nextChar</span><span class="p">()</span>
<span class="k">when</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> <span class="p">{</span>
<span class="sc">'('</span> <span class="p">-></span> <span class="n">ops</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="sc">')'</span> <span class="p">-></span> <span class="p">{</span>
<span class="k">while</span><span class="p">(!</span><span class="n">ops</span><span class="p">.</span><span class="nf">isEmpty</span><span class="p">()</span> <span class="p">&&</span> <span class="n">ops</span><span class="p">.</span><span class="nf">peek</span><span class="p">()</span> <span class="p">!=</span> <span class="sc">'('</span> <span class="p">)</span> <span class="p">{</span>
<span class="n">values</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="nf">result</span><span class="p">(</span><span class="n">ops</span><span class="p">.</span><span class="nf">pop</span><span class="p">(),</span> <span class="n">values</span><span class="p">.</span><span class="nf">pop</span><span class="p">(),</span> <span class="n">values</span><span class="p">.</span><span class="nf">pop</span><span class="p">()))</span>
<span class="n">ops</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="sc">'+'</span><span class="p">,</span> <span class="sc">'-'</span><span class="p">,</span> <span class="sc">'*'</span><span class="p">,</span> <span class="sc">'/'</span> <span class="p">-></span> <span class="p">{</span>
<span class="k">while</span><span class="p">(!</span><span class="n">ops</span><span class="p">.</span><span class="nf">isEmpty</span><span class="p">()</span> <span class="p">&&</span> <span class="p">(</span><span class="nf">precedence</span><span class="p">(</span><span class="n">ops</span><span class="p">.</span><span class="nf">peek</span><span class="p">()</span><span class="o">!!</span><span class="p">)</span> <span class="p">>=</span> <span class="nf">precedence</span><span class="p">(</span><span class="n">c</span><span class="p">)))</span> <span class="p">{</span>
<span class="n">values</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="nf">result</span><span class="p">(</span><span class="n">ops</span><span class="p">.</span><span class="nf">pop</span><span class="p">(),</span> <span class="n">values</span><span class="p">.</span><span class="nf">pop</span><span class="p">(),</span> <span class="n">values</span><span class="p">.</span><span class="nf">pop</span><span class="p">()))</span>
<span class="p">}</span>
<span class="n">ops</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">c</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">-></span> <span class="n">values</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">c</span><span class="p">.</span><span class="nf">toString</span><span class="p">().</span><span class="nf">toLong</span><span class="p">())</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">values</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>
<p>It’s not fancy but it really helped me understand stacks and arithmetic expressions. It was also pointed out to me that this algorithm could be expressed recursively, by using the stack frames as a way to express “stack”…so perhaps a project for the future. My original puzzle solution was recursive, but not nearly so elegant.</p>Dijkstra was pretty good at his job, as evidenced by the fact that his name is on a bunch of useful algorithms. This is one that was put in front of me as I was trying to solve Advent of Code, Day 18 2020. I’d never heard of it so thought I’d look in more detail.Group By2019-12-12T00:00:00+00:002019-12-12T00:00:00+00:00https://switzerb.github.io/imposter/toolkit/2019/12/12/groupby<p>I recently came across a situation in javascript where I needed to do a “pivot” on some data, which amounted to needing the <code class="language-plaintext highlighter-rouge">GROUP BY</code> functionality in SQL, or <code class="language-plaintext highlighter-rouge">groupBy</code> which is provided as standard in multiple languages like Kotlin. Javascript doesn’t have that function out of the box and writing it ended up being an interesting little project to understand the nuances of that transformation. I’m going to step through it as simply as possible here to outline what I mean.</p>
<p>In the simplest terms, the shape of the problem is to “pivot” a data structure around a key. It’s a really common pattern with data…so common, in fact, that at first I was a little taken aback when I was building it that it wasn’t simpler. The basic problem I had was: take a list of categories that each have an array of month, value pairs and show me how much value was in each month regardless of category.</p>
<p>This was the simple test I started with, so you can see the starting and expected objects:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">group by month is correct</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">categories</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Category One</span><span class="dl">"</span><span class="p">,</span>
<span class="na">values</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Jan</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">5</span><span class="dl">"</span><span class="p">},</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Feb</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span><span class="p">},]</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Category Two</span><span class="dl">"</span><span class="p">,</span>
<span class="na">values</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Jan</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span><span class="p">},</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Feb</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">12</span><span class="dl">"</span><span class="p">},]</span>
<span class="p">},</span>
<span class="p">];</span>
<span class="kd">const</span> <span class="nx">actual</span> <span class="o">=</span> <span class="nx">categoryTotals</span><span class="p">(</span><span class="nx">categories</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">expected</span> <span class="o">=</span> <span class="p">[{</span><span class="na">month</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Jan</span><span class="dl">'</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">15</span><span class="p">},</span> <span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Feb</span><span class="dl">'</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">22</span><span class="p">}];</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">actual</span><span class="p">).</span><span class="nx">toStrictEqual</span><span class="p">(</span><span class="nx">expected</span><span class="p">);</span>
<span class="p">})</span>
</code></pre></div></div>
<p>In even simpler languages, I started with a list of categories with month/value data and I <em>needed</em> to see a list of months with the sum of all it’s relevant values. Pretty normal use case, right?</p>
<p>Below is the code that I ended up with, which is really three separate steps.</p>
<ol>
<li>
<p>First, aggregate all the values into one structure, in this case from the test <code class="language-plaintext highlighter-rouge">[{"Jan",5},{"Feb",10},{"Jan",10},{"Feb",12}]</code>. The idea here is to make it all one thing, flattened with just the data we want so it’s easy to work with.</p>
</li>
<li>
<p>Second, a <code class="language-plaintext highlighter-rouge">groupBy</code> generic function that takes all the categories and groups them by month as one structure.</p>
</li>
<li>
<p>Third, a <code class="language-plaintext highlighter-rouge">reduce</code> over the entries in the map returned from <code class="language-plaintext highlighter-rouge">groupBy</code> to sum the values in each month into one sum.</p>
</li>
</ol>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">groupBy</span> <span class="o">=</span> <span class="p">(</span><span class="nx">items</span><span class="p">,</span> <span class="nx">extractKey</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">items</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span> <span class="nx">v</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">k</span> <span class="o">=</span> <span class="nx">extractKey</span><span class="p">(</span><span class="nx">v</span><span class="p">);</span>
<span class="k">return</span> <span class="p">{...</span><span class="nx">a</span><span class="p">,</span> <span class="p">[</span><span class="nx">k</span><span class="p">]:</span> <span class="p">(</span><span class="nx">a</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span> <span class="o">||</span> <span class="p">[]).</span><span class="nx">concat</span><span class="p">(</span><span class="nx">v</span><span class="p">)};</span>
<span class="p">},</span> <span class="p">{});</span>
<span class="p">}</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">categoryTotals</span> <span class="o">=</span> <span class="p">(</span><span class="nx">cat</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">aggregate_values</span> <span class="o">=</span> <span class="nx">cat</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span><span class="nx">sc</span><span class="p">)</span><span class="o">=></span> <span class="nx">a</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span><span class="nx">sc</span><span class="p">.</span><span class="nx">values</span><span class="p">),</span> <span class="p">[]);</span>
<span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">entries</span><span class="p">(</span><span class="nx">groupBy</span><span class="p">(</span><span class="nx">aggregate_values</span><span class="p">,</span> <span class="p">(</span><span class="nx">v</span><span class="p">)</span> <span class="o">=></span> <span class="nx">v</span><span class="p">.</span><span class="nx">month</span><span class="p">))</span>
<span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">result</span><span class="p">,</span> <span class="p">[</span><span class="nx">k</span><span class="p">,</span> <span class="nx">v</span><span class="p">])</span> <span class="o">=></span> <span class="nx">result</span><span class="p">.</span><span class="nx">concat</span><span class="p">({</span>
<span class="na">month</span><span class="p">:</span> <span class="nx">k</span><span class="p">,</span>
<span class="na">value</span><span class="p">:</span> <span class="nx">v</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span> <span class="nx">n</span><span class="p">)</span> <span class="o">=></span> <span class="nx">a</span> <span class="o">+</span> <span class="nb">Number</span><span class="p">(</span><span class="nx">n</span><span class="p">.</span><span class="nx">value</span><span class="p">),</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">}),</span> <span class="p">[]);</span>
<span class="p">}</span>
</code></pre></div></div>
<p>One thing you might notice is that <code class="language-plaintext highlighter-rouge">groupBy</code> here as a function takes two parameters, the array of items to work with and a <code class="language-plaintext highlighter-rouge">extractKey</code> function. This format was suggested to me by a more experienced engineer and I immediately saw how it was superior to the way I was trying to initially write this function. By passing in <code class="language-plaintext highlighter-rouge">extractKey</code> to the <code class="language-plaintext highlighter-rouge">groupBy</code> function, then <code class="language-plaintext highlighter-rouge">groupBy</code> doesn’t need to know <em>anything</em> about the internal structure of the array it’s iterating over. We simply give it the methodology for getting the key we want to use.</p>
<p>So in this case, you can see I use an anonymous function <code class="language-plaintext highlighter-rouge">(v) => v.month</code> to extract the “month” value. If my data structure were more complex, I could have a more complex <code class="language-plaintext highlighter-rouge">extractKey</code> without having to refactor anything.</p>
<p>For someone like me who started on this engineering path writing a whole bunch of raw sql into my code (<a href="https://www.w3schools.com/php/php_mysql_insert.asp">remember writing code like this??</a>) it was sort of shocking how much complexity was wrapped up in the SQL version of this same transformation idea. In SQL this same idea might look like, if you had a (fictional) table called <code class="language-plaintext highlighter-rouge">Subcategories</code> with month and value columns.</p>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">SELECT</span> <span class="k">SUM</span><span class="p">(</span><span class="n">value</span><span class="p">),</span> <span class="k">Month</span>
<span class="k">FROM</span> <span class="n">Subcategories</span>
<span class="k">GROUP</span> <span class="k">BY</span> <span class="k">Month</span><span class="p">;</span>
</code></pre></div></div>
<p>Pretty elegant language, right? Since the last half-decade of working with mostly <code class="language-plaintext highlighter-rouge">JSON</code> formatted data coming through a REST API (or, lately, graphQL), getting a straightforward rowset back from a database feels magically intuitive.</p>
<p>If javascript <em>did</em> have a native groupBy, it might look something like the one in Kotlin. Although here the data structures look a bit different, it’s the same concept applied. Here there are a list of four <code class="language-plaintext highlighter-rouge">Pair</code> instances that are a tuple of month, value pairs. The <code class="language-plaintext highlighter-rouge">Pair</code> has no semantic in this case and is just a way to group related data, so in the “real” world this is much more likely to be a <code class="language-plaintext highlighter-rouge">data class Category</code> with a name and an array of months…but for the sake of example this is clearer.</p>
<p>Notice how you would still need the <code class="language-plaintext highlighter-rouge">sum</code> step after grouping. Here we end up with a <code class="language-plaintext highlighter-rouge">List</code> of <code class="language-plaintext highlighter-rouge">List</code>s of <code class="language-plaintext highlighter-rouge">Pairs</code> after we group, so it would still be necessary to iterate over the entries in <code class="language-plaintext highlighter-rouge">byMonth</code> and reduce (and then again) to get each month to have a sum in it.</p>
<div class="language-kotlin highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">val</span> <span class="py">categories</span> <span class="p">=</span> <span class="nf">listOf</span><span class="p">(</span>
<span class="nc">Pair</span><span class="p">(</span><span class="s">"Jan"</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
<span class="nc">Pair</span><span class="p">(</span><span class="s">"Jan"</span><span class="p">,</span><span class="mi">10</span><span class="p">),</span>
<span class="nc">Pair</span><span class="p">(</span><span class="s">"Feb"</span><span class="p">,</span> <span class="mi">10</span><span class="p">),</span>
<span class="nc">Pair</span><span class="p">(</span><span class="s">"Feb"</span><span class="p">,</span><span class="mi">12</span><span class="p">)</span>
<span class="p">)</span>
<span class="kd">val</span> <span class="py">byMonth</span> <span class="p">=</span> <span class="n">categories</span>
<span class="p">.</span><span class="nf">groupBy</span> <span class="p">{</span> <span class="n">it</span><span class="p">.</span><span class="n">first</span> <span class="p">}</span> <span class="c1">// groups by pair first value, e.g. month</span>
<span class="nf">println</span><span class="p">(</span><span class="n">byMonth</span><span class="p">.</span><span class="n">keys</span><span class="p">)</span> <span class="c1">// ["Jan", "Feb"]</span>
<span class="nf">println</span><span class="p">(</span><span class="n">byMonth</span><span class="p">.</span><span class="n">values</span><span class="p">)</span> <span class="c1">// [[(Jan, 5), (Jan, 10)], [(Feb, 10), (Feb, 12)]]</span>
</code></pre></div></div>
<p>One other thing to note about all of this in my javascript implementation (which could use some better error handling <em>cough</em>) is that I have chosen here to use immutable structures and functional programming. In simpler terms, I <code class="language-plaintext highlighter-rouge">concat</code> onto the array instead of <code class="language-plaintext highlighter-rouge">push</code>ing. For me, the safety of not mutating the structures feels like the right choice and I didn’t need to worry about performance in the context I was in. It was more important to not leak out a returned value that wasn’t guaranteed to be immutable or accidentally mutate the passed-in array.</p>
<p>However, making all these copies is definitely more memory-intensive and slower. If I were building a <code class="language-plaintext highlighter-rouge">groupBy</code> that was going to be used in unknown contexts as a library method, I would reimplement to optimize for performance and keep the making-copies to a minimum. It would be a rather large bummer to pass in a massive array to <code class="language-plaintext highlighter-rouge">groupBy</code> and have the whole system slow to a crawl or crash as the system ran out of memory.</p>I recently came across a situation in javascript where I needed to do a “pivot” on some data, which amounted to needing the GROUP BY functionality in SQL, or groupBy which is provided as standard in multiple languages like Kotlin. Javascript doesn’t have that function out of the box and writing it ended up being an interesting little project to understand the nuances of that transformation. I’m going to step through it as simply as possible here to outline what I mean.Unit Testing2019-12-09T00:00:00+00:002019-12-09T00:00:00+00:00https://switzerb.github.io/imposter/process/2019/12/09/UnitTesting<p>If you are anything like me, you heard the phrase “unit testing” thrown around a lot before it meant anything real. And terms such as “unit testing”, “integration testing” and “functional testing” had little distinction. They all fell into the category of “should be doing but not on THIS project”. Most of my software experience at that point comprised of tight deadlines, unfamiliar technologies, poorly defined specifications or tight budgets that didn’t account for anything as fancy as “testing”.</p>
<p>During one particularly frustrating bug-chasing afternoon, I had arrived at that familiar near-tears, nothing-works, I-am-stupid-and-I-should-just-quit-forever moment and was ready to submit my resignation and go start a new career as a grocery store clerk. Already at the bottom, I figured I’d give testing a try since it could hardly be worse.</p>
<p>To my delight, the tests created magnificent clarity about the actual problems. It forced me to think in very small units – hey! an actual unit test! - and tiny, logical steps. Does this one method return the right number? Does it handle the null case? What about the next one?</p>
<p>Since then, I’ve been a convert. Testing isn’t just about code reliability (although, of course, that’s awesome, too) it’s a tool to help build successful thinking and execution.</p>
<h4 id="unit-testing-is-exactly-what-it-sounds-like">Unit testing is exactly what it sounds like</h4>
<p>Ideally, a “unit” of code has one job and is encapsulated - meaning you can reliably give input and get expected output, without side effects. If you are connecting to a database or a network resource or some other external dependency or interaction, you aren’t unit testing.</p>
<p>While I always understood unit tests as a way to make sure the software works correctly, it’s really a <em>design</em> tool to help you write better code. I’ve discovered that my tests are dead simple when my code is really good…and nearly impossible when my code is spaghetti-fied crap.</p>
<p>Most languages have built-in tests and test runners, so if you want to give it a try, just start super slow. Test just one method that has a crystal clear answer.</p>
<p>For example, I recently wrote a method that ended up being a more complex aggregation than I expected, to calculate some monthly totals:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">calcSubcategoryTotals</span> <span class="o">=</span> <span class="p">(</span><span class="nx">subcategories</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">result</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">const</span> <span class="nx">aggregated</span> <span class="o">=</span> <span class="nx">subcategories</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span><span class="nx">sc</span><span class="p">)</span><span class="o">=></span> <span class="p">{</span>
<span class="nx">sc</span><span class="p">.</span><span class="nx">values</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">v</span> <span class="o">=></span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">a</span><span class="p">[</span><span class="nx">v</span><span class="p">.</span><span class="nx">month</span><span class="p">])</span> <span class="p">{</span>
<span class="nx">a</span><span class="p">[</span><span class="nx">v</span><span class="p">.</span><span class="nx">month</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="nb">Number</span><span class="p">(</span><span class="nx">v</span><span class="p">.</span><span class="nx">value</span><span class="p">)];</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="nx">a</span><span class="p">[</span><span class="nx">v</span><span class="p">.</span><span class="nx">month</span><span class="p">].</span><span class="nx">push</span><span class="p">(</span><span class="nb">Number</span><span class="p">(</span><span class="nx">v</span><span class="p">.</span><span class="nx">value</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">a</span><span class="p">;</span>
<span class="p">},{});</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">entries</span><span class="p">(</span><span class="nx">aggregated</span><span class="p">).</span><span class="nx">map</span><span class="p">(([</span><span class="nx">k</span><span class="p">,</span><span class="nx">v</span><span class="p">])</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">result</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span> <span class="na">month</span><span class="p">:</span> <span class="nx">k</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="nx">v</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">a</span><span class="p">,</span><span class="nx">n</span><span class="p">)</span> <span class="o">=></span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">n</span><span class="p">,</span> <span class="mi">0</span><span class="p">)});</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>In the middle of <code class="language-plaintext highlighter-rouge">mapping</code> inside my <code class="language-plaintext highlighter-rouge">reduce</code> I was like, “Well, I have no idea if this is the right approach.”. So I wrote a super minimal unit test, which both helped me understand what I was doing and also let me know if I was done.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="p">{</span><span class="nx">calcSubcategoryTotals</span><span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">./utils</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">calculates the aggregation correctly</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">subcats</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">{</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Subcat Name</span><span class="dl">"</span><span class="p">,</span>
<span class="na">values</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Jan</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span><span class="p">},</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Feb</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span><span class="p">},]</span>
<span class="p">},</span>
<span class="p">{</span>
<span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Subcat Name Two</span><span class="dl">"</span><span class="p">,</span>
<span class="na">values</span><span class="p">:</span> <span class="p">[</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Jan</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span><span class="p">},</span>
<span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Feb</span><span class="dl">"</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="dl">"</span><span class="s2">10</span><span class="dl">"</span><span class="p">},]</span>
<span class="p">},</span>
<span class="p">];</span>
<span class="kd">const</span> <span class="nx">actual</span> <span class="o">=</span> <span class="nx">calcSubcategoryTotals</span><span class="p">(</span><span class="nx">subcats</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">expected</span> <span class="o">=</span> <span class="p">[{</span><span class="na">month</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Jan</span><span class="dl">'</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">20</span><span class="p">},</span> <span class="p">{</span><span class="na">month</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Feb</span><span class="dl">'</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">20</span><span class="p">}];</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">actual</span><span class="p">).</span><span class="nx">toStrictEqual</span><span class="p">(</span><span class="nx">expected</span><span class="p">);</span>
<span class="p">})</span>
</code></pre></div></div>
<p>This is one nano test that took me about five minutes to write, but it helped me clarify my thinking enormously. And, even better, anyone that comes along after me will have this super simple example of what I was trying to do. And when they discover that my code bombs on the null case, it’s easy to write a test to prove it and know exactly what to fix.</p>
<h4 id="red-green-refactor">Red, Green, Refactor</h4>
<p>The other handy benefit is that once my test passed, I can go in there and make the original method less…um, obtuse. And as long as the test(s) are clear, I know I haven’t broken anything essential.</p>
<p>This is the conceptual basis of test-driven development –</p>
<ol>
<li>Red: write the failing test (e.g. call the skeleton method)</li>
<li>Green: write the method so the test passes</li>
<li>Refactor: make it good while <em>knowing</em> you aren’t breaking anything</li>
</ol>
<p>I was shocked at the amount of mental order this brought to my problem solving. My code improved markedly overnight not because I had any additional specialized knowledge, but because I was able to break the code into sufficiently small parts. So small and simple, in fact, that months later I could go back and read what I had written without effort.</p>
<h4 id="but-what-about-testing-that-the-software-actually-works-for-reals">But what about testing that the software actually works for reals?</h4>
<p>This is the domain of integration and functional testing, and it is also incredibly valuable. However, without a solid foundation of unit tests it can be just as messy, fragile and hard to understand as the code you are struggling to prove works. I have read a hundred Medium articles where devs have all this complex mocking behavior and click event rendering whatever and that’s great – super useful. But even the simplest, least fancy test can make a big impact.</p>
<h4 id="so-yeah-im-a-fan-but-the-real-world-is-pretty-messy">So, yeah, I’m a fan but the real world is pretty messy</h4>
<p>Most of the time as a dev, you inherit code from someone else that only barely makes sense to you. Writing tests for code that’s already complicated is not only difficult, it’s damn near herculean. So my approach is the same one I take about flossing or getting regular exercise: some is better than none, consistency is more important than perfection and when you just can’t get to it because “reasons” then just move on and fight the next fire.</p>If you are anything like me, you heard the phrase “unit testing” thrown around a lot before it meant anything real. And terms such as “unit testing”, “integration testing” and “functional testing” had little distinction. They all fell into the category of “should be doing but not on THIS project”. Most of my software experience at that point comprised of tight deadlines, unfamiliar technologies, poorly defined specifications or tight budgets that didn’t account for anything as fancy as “testing”.Mise En Place2019-11-12T00:00:00+00:002019-11-12T00:00:00+00:00https://switzerb.github.io/imposter/process/2019/11/12/MiseEnPlace<p>The benefits of mental clarity and organization on the quality of code can hardly be overstated. From the tools used to code to the mental processes employed to break a problem down, physical space and time, a clear idea of purpose and destination, it all factors into both the quality of the experience and the resulting code. Because coding itself can be so intellectually challenging, the lack of focus can be so disastrous as to make solving a problem impossible.</p>
<p>And like most things that are incredibly, powerfully useful and straightforward, it’s super difficult to actually do consistently. This blog post was supposed to be about mutual recursion…a tricky topic about two interacting recursive loops that turned out to be incredible useful in a code puzzle I was solving.</p>
<p>But instead, my life got busy with deadlines, parenting and a new employment opportunity and so the blog post got postponed. And then postponed again. And I totally lost all of my clarity. Of course I did.</p>
<h2 id="please-distract-me">Please, distract me?</h2>
<p>Which got me thinking about mental discipline, fear, and the craft of coding. Trying to produce code while being scattered, overwhelmed, afraid, tired, distracted or otherwise mentally off your game is just excruciating. For me, this often manifests as a sort of whirlwind of useless activity – I start something and then leave it undone while I skip to the next thing and then interupt myself with yet another urgent thing I don’t finish. Lack of focus doesn’t even begin to describe that state.</p>
<h2 id="getting-pleasure-from-being-organized">Getting pleasure from being organized</h2>
<p>Which brings me to <em>mise en place</em>, a term found in the kitchen rather than Silicon Valley, but something I use quite often to help me get over the “scattered and anxious” wall. Merriam-Webster defines <em>mise en place</em> as “A culinary process in which ingredients are prepared and organized (as in a restaurant kitchen) before cooking”. In french it means “setting in place”.</p>
<p>More concretely, it’s all those prep bowls you see when you watch cooking shows, filled with pre-measured and pre-chopped ingredients on immaculate counter tops. It’s the recipe available on the counter and the notebook with lists of stuff that need to go into the oven and when.</p>
<p>Just like those prep bowls in the kitchen, I don’t start coding until my notebook is full of notes, I have a mental map of the problem statement and all my tools are ready to go. If you can’t get those materials together or don’t know what materials you need, then that’s a clear diagnostic tool to tell you that you aren’t really to start solving the problem yet. Maybe the problem isn’t well-defined or you don’t have a deep enough grasp of the underlying technology. Knowing that you aren’t prepared is incredible useful information.</p>
<p>The magic in this occurs when you can focus on the problem instead of the platform. With cooking, you can focus on the color and the fragrance as you are sweating the onions rather than racing to get the garlic chopped. With coding, you can float all those delicate abstractions and relationships in your brain without worrying about how to make your text editor soft wrap or color code the syntax properly. It’s not an insignificant detail that when your tools and materials are in place, it is more satisfying and less stressful to work.</p>
<h2 id="and-then-there-is-actual-life">And then there is actual life</h2>
<p>The whole point of this essay is, of course, real life rarely works that way. For me, the barrier is usually that I am in a big rush or over-committed so I start before I am ready. Or I’ve had a terrible night of sleep and can’t muster enough brain power or, more commonly, I’ve spent a day bouncing between emails and meetings and the administrative overload eviscerates my ability to go deep into a problem.</p>
<p>While it’s easy to dispense the advice “be organized”, it’s rather harder to actually implement. Additionally, it’s a more subtle problem than it appears on the surface. A decade ago I had a conversation with a friend where we commiserated over the word “discipline” and how unfair it was when it was applied to activities we loved. Pushing yourself super hard can absolutely kill the joy, but not pushing yourself leads to atrophy and stagnation. How do you know when to push? When is discipline appropriate and when do you rest and give yourself a break?</p>
<p>A decade later, I had my answer: judgment about when to push and when not to is entirely learned through experience and really making forward progress in any field requires both, applied intelligently. A prescription to “be organized” and “be mentally disciplined” is absolutely useless advice even if it’s correct.</p>
<p>Which brings me back to <em>mise en place</em>. Rather than prescription, it’s a concrete and systematic way to acknowledge that life is messy and building high-quality software a significant challenge. It’s precisely when I am the most tired and distracted that it is the most valuable, even if it’s not ideal circumstances. For me, the assembly of materials takes on an almost ritualistic quality: the notebook and black uniball pen, the laptop, the IDE, the “hello world” proof of architecture. It keeps me from being overwhelmed and provides a sense of organization and satisfaction I use to get me over whatever internal resistance I have to the work.</p>
<p>More importantly, it reminds me that software is a process not a destination. You do the work, you do your best and you recognize that your code is not you. Bringing order and discipline isn’t about proving something, it’s about making safe space for deep focus, play and learning.</p>
<h2 id="the-meta-message">The meta message</h2>
<p>All of which is to say that I decided to make the post about the meta process of getting organized instead of the actual coding problem I was unraveling because it’s just as critical to the process and it goes largely unrecognized as a skill. Like any skill, the more I practice the more intuitive and beneficial the practice becomes.</p>
<p>The last benefit is more elusive but probably the most important: it allows me to be a beginner over and over again, consistently. My fragile ego shouting at me, telling me “I should already know how to do this” or “I am not making enough progress” or “I am clearly dumb as a box of broken hammers” gets dimmer and dimmer if I just focus on the basics. I know I’m going to need carrots, so cut the carrots, put them in a bowl and we’ll deal with the onions in a minute. One thing at a time, one prep at a time, one task over and over again IS the work.</p>
<p>Which means, ultimately, that the real practice is to stay curious, focused and relaxed which not only makes the process more pleasurable but produces wildly more successful problem solving ability.</p>The benefits of mental clarity and organization on the quality of code can hardly be overstated. From the tools used to code to the mental processes employed to break a problem down, physical space and time, a clear idea of purpose and destination, it all factors into both the quality of the experience and the resulting code. Because coding itself can be so intellectually challenging, the lack of focus can be so disastrous as to make solving a problem impossible.Hello, World2019-11-04T00:00:00+00:002019-11-04T00:00:00+00:00https://switzerb.github.io/imposter/process/2019/11/04/HelloWorld<p>The beginning of a project for me, particularly a greenfield project where no legacy code exists, is both exciting and terrifying. The sense of potential and possibility is almost intoxicating. And, for those of us with control issues and aspirations of perfection, a blank page also represents code with no errors in it yet.</p>
<p>Crossing the threshold into complexity doesn’t take long and, inevitably the pride in accomplishment gets married to a strong impulse to refactor everything, RIGHT NOW.</p>
<p>Which is why sometimes it’s hard to get started. Avoidance of the actual messiness of real life and fear of failure can generate a remarkable heap of procrastination.</p>
<p>So small, simple formal beginnings can be quite useful in solving that problem. In particular, when I am overwhelmed by impending complexity, this provides a clear open door to walk through.</p>
<p>As a concrete example, this year I’ve set out to learn some Java as a way to focus on coding fundamentals, which intimidated me.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public static void main(String[] args) throws IOException {
System.out.println("Hello, World");
}
</code></pre></div></div>
<p>This was the first Java I ever wrote and is likely the place most beginners start.</p>
<p>The uses of a simple “Hello, World” start are many:</p>
<ul>
<li>It’s a simple entry point and the complexity is manageable even to a beginner</li>
<li>It’s concrete, visible and short time-to-execute</li>
<li>It demonstrates the development environment/deploy/stack is set up correctly</li>
<li>It exposes environmental and system problems, like a cumbersome deploy process</li>
</ul>
<p>When I start personal or professional projects, I include a “Hello, World” unit test as well to confirm my test environment will run and tests things. It usually looks something like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> @Test
public void testHello() {
assertEquals(true, true);
}
</code></pre></div></div>The beginning of a project for me, particularly a greenfield project where no legacy code exists, is both exciting and terrifying. The sense of potential and possibility is almost intoxicating. And, for those of us with control issues and aspirations of perfection, a blank page also represents code with no errors in it yet.