<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>chrisphan.com</title><link>https:://chrisphan.com/</link><description>Recent content on chrisphan.com</description><language>en-us</language><copyright>Copyright © 2012–2026 Christopher L. Phan, Ph.D.</copyright><lastBuildDate>Thu, 9 Apr 2026 05:18:17 +0000</lastBuildDate><item><title>Happy (belated) π Day!</title><link>https:://chrisphan.com/posts/2026-03-14_happy_belated_pi_day.html</link><description><![CDATA[ Happy belated π Day! π Day is the 14th of March, i.e. 03-14 both the U.S. or ISO 8601 date formats. Two times in the]]></description><guid>https:://chrisphan.com/posts/2026-03-14_happy_belated_pi_day.html</guid><pubDate>Wed, 18 Mar 2026 16:15:00 -0500</pubDate><content:encoded><![CDATA[
<p>Happy belated π Day! <a href="https://en.wikipedia.org/wiki/Pi_Day">π
Day</a> is the 14th of March, i.e. 03-14
both the U.S. or ISO 8601 date formats. Two times in the past, I have posted
some kind of method (not necessarily efficient) to approximate π as a π Day
celebration:</p>
<ul>
<li><a href="/pi_day_2021/">2021</a>: Used a Monte Carlo method: randomly selecting points
\((x, y) \in [0, 1] \times [0, 1]\), and seeing what proportion have
\(x^2 + y^2 &lt; 1\). Implemented in JavaScript.</li>
<li><a href="/pi_day_2024/">2024</a>: Used a
power series approximation and an argument from <q>Papa Rudin</q><sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>.
Implemented in <a href="https://julialang.org">Julia</a></li>
</ul>
<p>This year's entry, admittedly a little late, involves WebAssembly and
differential equations.</p>
<h2>A system of differential equations</h2>
<p>This year, I decided to estimate π by approximating \(\sin t\) for values
of \(t &gt; 0\), using differential equations and Euler's method. Specifically,
note that \(x = \sin t, y = \cos t\) is the only solution to the system of
differential equations
\[\begin{aligned} \frac{dx}{dt} &amp;= y, \\ \frac{dy}{dt} &amp;= -x
\end{aligned}\]
that satisfies the initial conditions \(x(0) = 0,\; y(0) = 1\).</p>
<h2>Euler's method</h2>
<p>Suppose we have a system of differential equations of the form
\[\begin{aligned}
\frac{dx}{dt} &amp;= a x + b y,\\
\frac{dy}{dt} &amp;= c x + d y.
\end{aligned}\]
We can use Euler's method to find numerical solutions (that is to say,
approximations of the solutions) to this system. For any real number \(t_0\),
and small real number \(\Delta t\), we can estimate the quantities
\[\begin{aligned}
\Delta x &amp;= x(t_0 + \Delta t) - x(t_0),\\
\Delta y &amp;= y(t_0 + \Delta t) - y(t_0),
\end{aligned}\]
with the approximations
\[\begin{aligned}
\Delta x &amp;\approx \left(a x(t_0) + b y(t_0)\right) \Delta t,\\
\Delta y &amp;\approx \left(c x(t_0) + d y(t_0)\right) \Delta t.
\end{aligned}\]</p>
<p>Given initial values \(x(0) = x_0\) and \(y(0) = y_0\), we can come up with
approximations \(x_k\) and \(y_k\) for \(x(k \Delta t)\) and
\(y(k \Delta t)\), respectively, by recursively defining
\[\begin{aligned}
x_{k + 1} &amp;= x_k + \left(a x_k + b y_k\right) \Delta t,\\
y_{k + 1} &amp;= y_k + \left(c x_k + d y_k\right) \Delta t.
\end{aligned}\]</p>
<h2>Enter WASM</h2>
<p>Lately, I have been learning <a href="https://webassembly.org">WebAssembly</a> (WASM), and
thought it would be fun to implement this year's π Day demo in WASM.
While traditional <a href="https://en.wikipedia.org/wiki/Assembly_language">assembly
language</a> is used to specify
processor instructions in order to program a computer directly, WebAssembly
instructions are run on a stack-based virtual machine inside the web
browser.<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup> WASM in created by writing the instructions in a human-readable
text format, <a href="https://developer.mozilla.org/en-US/docs/WebAssembly/Guides/Understanding_the_text_format">WebAssembly
text</a>
or WAT.</p>
<p>For example, here is some WAT code for my WASM implementation of Euler's method:</p><div class="code_block"><div class="code-header"><span class="filename">pi_day_2026.wat</span> <span class="code-lang">WAT</span></div><pre class=""  id="block-6c0169ee-b8e8-4d11-9835-1327ee58506b"><code class="language-wat"><code class="code-elipsis" id="block-6c0169ee-b8e8-4d11-9835-1327ee58506b-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">;; set delta_x = (a*x + b*y) * delta_t</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.get</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$a</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.get</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$x</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">f64.mul</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.get</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$b</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.get</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$y</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">f64.mul</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">f64.add</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.tee</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$dxdt</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.get</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$delta_t</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">f64.mul</span><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="background-color:#6e2e32;color:#839496;">local.set</span><span style="color:#839496;"> </span><span style="background-color:#6e2e32;color:#839496;">$delta_x</span><span style="color:#839496;"></span></code>
<code class="code-elipsis" id="block-6c0169ee-b8e8-4d11-9835-1327ee58506b-elipsis-end"></code>
</code></pre></div>
<p>Lines starting with <code>;;</code> are comments. The virtual machine that executes WASM is
a <a href="https://en.wikipedia.org/wiki/Stack_machine">stack machine</a>. In the above
snippet<sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup>:</p>
<table>
<thead>
<tr>
<th align="left">Line</th>
<th align="left">Stack before</th>
<th align="left">WAT Instruction</th>
<th align="left">Description</th>
<th align="left">Stack after</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">44</td>
<td align="left">(empty)</td>
<td align="left"><code>local.get $a</code></td>
<td align="left">Copy the value stored in the variable <code>$a</code> and push it on top of the stack</td>
<td align="left"><code>$a</code></td>
</tr>
<tr>
<td align="left">45</td>
<td align="left"><code>$a</code></td>
<td align="left"><code>local.get $x</code></td>
<td align="left">Copy the value stored in the variable <code>$x</code> and push it on top of the stack</td>
<td align="left"><code>$a</code>, <code>$x</code></td>
</tr>
<tr>
<td align="left">46</td>
<td align="left"><code>$a</code>, <code>$x</code></td>
<td align="left"><code>f64.mul</code></td>
<td align="left">Pop the top two values off the stack, multiply them, and push the result on the stack</td>
<td align="left"><code>$a</code> × <code>$x</code></td>
</tr>
<tr>
<td align="left">47</td>
<td align="left"><code>$a</code> × <code>$x</code></td>
<td align="left"><code>local.get $b</code></td>
<td align="left">Copy the value stored in the variable <code>$b</code> and push it on top of the stack</td>
<td align="left"><code>$a</code> × <code>$x</code>, <code>$b</code></td>
</tr>
<tr>
<td align="left">48</td>
<td align="left"><code>$a</code> × <code>$x</code>, <code>$b</code></td>
<td align="left"><code>local.get $y</code></td>
<td align="left">Copy the value stored in the variable <code>$y</code> and push it on top of the stack</td>
<td align="left"><code>$a</code> × <code>$x</code>, <code>$b</code>, <code>$y</code></td>
</tr>
<tr>
<td align="left">49</td>
<td align="left"><code>$a</code> × <code>$x</code>, <code>$b</code>, <code>$y</code></td>
<td align="left"><code>f64.mul</code></td>
<td align="left">Pop the top two values off the stack, multiply them, and push the result on the stack</td>
<td align="left"><code>$a</code> × <code>$x</code>, <code>$b</code> × <code>$y</code></td>
</tr>
<tr>
<td align="left">50</td>
<td align="left"><code>$a</code> × <code>$x</code>, <code>$b</code> × <code>$y</code></td>
<td align="left"><code>f64.add</code></td>
<td align="left">Pop the top two values off the stack, add them, and push the result on the stack</td>
<td align="left"><code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code></td>
</tr>
<tr>
<td align="left">51</td>
<td align="left"><code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code></td>
<td align="left"><code>local.tee $dxdt</code></td>
<td align="left">Copy the top value from the stack (without removing it) and store in the variable <code>$dxdt</code></td>
<td align="left"><code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code></td>
</tr>
<tr>
<td align="left">52</td>
<td align="left"><code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code></td>
<td align="left"><code>local.get $delta_t</code></td>
<td align="left">Copy the value stored in the variable <code>$delta_t</code> and push it on top of the stack</td>
<td align="left"><code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code>, <code>$delta_t</code></td>
</tr>
<tr>
<td align="left">53</td>
<td align="left"><code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code>, <code>$delta_t</code></td>
<td align="left"><code>f64.mul</code></td>
<td align="left">Pop the top two values off the stack, multiply them, and push the result on the stack</td>
<td align="left">(<code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code>) × <code>$delta_t</code></td>
</tr>
<tr>
<td align="left">54</td>
<td align="left">(<code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code>) × <code>$delta_t</code></td>
<td align="left"><code>local.set $delta_x</code></td>
<td align="left">Pop the top value off the stack and store in the variable <code>$delta_x</code></td>
<td align="left">(empty)</td>
</tr>
</tbody>
</table>
<p>The overall effect of lines 44-54 is to:</p>
<ul>
<li>Compute <code>$a</code> × <code>$x</code> + <code>$b</code> × <code>$y</code> and store in <code>$dxdt</code></li>
<li>Compute <code>$dxdt</code> × <code>$delta_t</code> and store it in <code>$delta_x</code>.</li>
</ul>
<p>This illustrates the downside to WASM: it takes 11 lines of code to accomplish
what most programming languages can do in two.</p>
<h2>Euler step demo</h2>
<p>The total function to do one step of Euler's method takes about 40 lines of WAT
code. This JavaScript on this page is able to access the Euler step function. To
the browser, this function is called <code>eulerStep</code>. It takes 7 numbers as
arguments (\(a, b, c, d, x(t), y(t),\) and \(\Delta T\))
and returns four numbers (estimates for \(x(t), y(t), x'(t),\) and
\(y'(t)\). You can play with this function by opening your browser's
JavaScript console and evaluating the function
there<span id="console_instr">, once the WASM is done loading</span>:</p><div class="code_block"><div class="code-header"><span class="code-lang">JavaScript (console)</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-javascript"><code class="javascript_console_repl_prompt_0"><span style="color:#b58900;">eulerStep</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">2</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">3</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">4</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.0625</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
[1.1875, 1.4375, 3, 7]
</pre>
</div></div></div>
<p>On the other hand, if mucking around in your browser's JavaScript console isn't
your thing, you can also access <code>eulerStep</code> via the following demo:</p>
<p id="demo_status">Demo is not ready yet. Loading WASM...</p>
<div id="euler_step_demo">
  <div id="euler_step_inputs">
    <div id="a_value">a = <input type="number" id="a_input" value="1" /></div>
    <div id="b_value">b = <input type="number" id="b_input" value="2" /></div>
    <div id="c_value">c = <input type="number" id="c_input" value="3" /></div>
    <div id="d_value">d = <input type="number" id="d_input" value="4" /></div>
    <div id="system_header">System:</div>
    <div>dx/dt = <span id="a_disp">a</span> x
      <span id="b_sign">+</span> <span id="b_disp">b</span> y</div>
    <div>dy/dt = <span id="c_disp">c</span> x
      <span id="d_sign">+</span> <span id="d_disp">d</span> y</div>
    <div id="x_value">x(<span id="t_disp_1">0</span>) =
      <input type="number" id="x_input" value="1"/></div>
    <div id="y_value">y(<span id="t_disp_2">0</span>) =
      <input type="number" id="y_input" value="1"/></div>
    <div id="delta_t_value">&Delta; t =
      <input type="number" id="delta_t_input" value="0.0625"/></div>
    <button id="euler_step_calculate" disabled>Step</button>
    <button id="euler_step_reset" disabled>Reset</button>
  </div>
  <div id="euler_step_output">
    <table id="euler_step_table">
      <thead>
        <tr>
          <th>t</th>
          <th>x</th>
          <th>y</th>
          <th>dx/dt</th>
          <th>dy/dt</th>
        </tr>
      </thead>
      <tbody id="euler_step_table_body">
      </tbody>
    </table>
  </div>
</div>
<h2>Approximating π</h2>
<p>One definition of π is that \(t = \pi\) smallest positive real solution to
the equation \(\sin t = 0\). Earlier I mentioned that
\(x(t) = \sin t, y(t) = \cos t\) is the unique solution to the system of
differential equations
\[\begin{aligned}
\frac{dx}{dt} &amp; = y, \\
\frac{dy}{dt} &amp;= -x
\end{aligned}\]
that satisfies the initial conditions \(x(0) = 0, y(0) = 1\).
My plan is to use Euler's method to approximate a solution to this system (with
initial conditions), which means approximating \(\sin t\) and
\(\cos t\), and looking for the first positive value of \(t\) for
which \(\cos t \leq 0\), which will be our approximation of π. The
smaller \(\Delta t\) used, the better approximation of π we get.</p>
<p>Once the WASM has loaded successfully, click on the <q>Run</q> button to come
up with different estimates for π using smaller and smaller values of
\(\Delta t\).</p>
<p>Our estimates are produced as
<a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">IEEE 754 double-precision floating-point numbers</a>.
This 64-bit format represents numbers<sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup> in the form
\[(-1)^s \times \left(1 + f/2^{52}\right)\times 2^{e - 1023},\]
using one bit for \(s\), 11 bits for \(e\), and 52 bits for \(f\).
For example, the number 3.25 is represented as</p>
<p>\[\begin{aligned}
(-1)^0 \times \left(1 + \frac{2814749767106560}{2^{52}}\right) \times 2^{1024 - 1023}
&amp;= \left(1 + \frac{10 \times 2^{48}}{2^{52}} \right) \times 2 \\
&amp;= \left(1 + 10/16\right) \times 2  \\
&amp;= 3.25.
\end{aligned}\]</p>
<p>For each approximation produced, click on the <q>Show me the IEEE!</q> to see
the approximation as it's represented internally.</p>
<p><span id="status">Loading the WASM...</span></p>
<p><button id="main_button" disabled>Run</button></p>
<table id="main_table">
  <thead>
    <tr>
      <th><i>k</i></th><th>&Delta;<i>t</i> = 2<sup>-<i>k</i></sup></th>
      <th>Approx. for &pi;</th>
      <th>Error from
        <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI">
          <code>Math.PI</code>
        </a>
      </th>
      <th>Time (ms)</th>
      <th>Num. values</th>
      <th>Plot</th>
    </tr>
  </thead>
  <tbody id="main_table_body">
  </tbody>
</table>
<ul>
<li>
<p><a href="/pi_day_2026/index.html">Standalone page with the interactive portions of this
post</a></p>
</li>
<li>
<p><a href="https://codeberg.org/christopherphan/Pi_Day_2026">Source code</a></p>
</li>
</ul>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p><cite>Real and Complex Analysis, 3rd Edition</cite> by Walter Rudin
(McGraw Hill 1987) <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>Or other runtimes, but the browser is my focus here. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p>In this table, the stacks are written from bottom to top. For example,
the stack after line 45 is executed, written as <q><code>$a</code>, <code>$x</code></q>, has
<code>$a</code> on the bottom and <code>$x</code> on the top. <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p>I'm ignoring values such as NaN (not a number) and \(\pm\infty\),
which can also be represented as IEEE double-precision floating-point
numbers. <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>6 7</title><link>https:://chrisphan.com/posts/2025-12-31_6_7.html</link><description><![CDATA[ Yeah, if you have or frequently interact with children, you are probably familiar with the nonsense saying six seven . Is this a ridiculously silly]]></description><guid>https:://chrisphan.com/posts/2025-12-31_6_7.html</guid><pubDate>Wed, 31 Dec 2025 12:30:00 -0600</pubDate><content:encoded><![CDATA[
<p>Yeah, if you have or frequently interact with children, you are probably
familiar with <a href="https://www.merriam-webster.com/slang/six-seven">the nonsense saying <q>six
seven</q></a>. Is this a
ridiculously silly meme? <em>Of course it is</em>, but so is (for example) <a href="https://en.wikipedia.org/wiki/Rickrolling">trying to
trick people into watching a particular music
video</a>. Watching my first-grader
experience her first meme is wonderful and I choose to celebrate it!</p>
<p>Therefore, without further ado, I present:</p>
<!-- This is all on one line to prevent my static site generator from trying to
parse it as markdown. The HTML source code below has a version whose source is
more readable. -->
<p><svg width="800" height="500" xmlns="http://www.w3.org/2000/svg" id="67_animation" aria-label="The number 67 and the words 'six seven' in various fonts and colors move horizontally from right to left at differing speeds."> <defs><path d="M 0,0 v -40 a 50 50 180 0 0 -100 0 v 120 a 50 50 180 0 0 100 0 v -19 h -20 v 14 a 30 30 180 0 1 -60 0 v -20 a 30 30 180 0 1 60 0 h 20 v -5 a 40 40 90 0 0 -40 -40 q -40 0 -40 10 v -60 a 30 30 180 0 1 60 0 v 30 z" id="six" /> <path d="M 0,0 h 150 v 25 c -30,0  -70,30 -70,70 v 30 h 50 v 20 h -50 v 75 h -25 v -75 h -50 v -20 h 50 v -35 c 0,-30 30,-50 40,-60 h -110 v -25 z  " id="seven" /> <g id="six-seven"> <use href="#six" x="100" y="90" style="transform: scale(0.2)" /> <use href="#seven" x="135" y="2" style="transform: scale(0.2)" /> </g> <path id="disp_seg_vert" d="M 0,0 l 20,20 v 50 l -20,20 l -20,-20 v -50 l 20,-20 " /> <g id="disp_seg_horiz"> <use href="#disp_seg_vert" style="transform: rotateZ(-90deg)" /> </g> <g id="6_lcd"> <use href="#disp_seg_horiz" x="5" y="-5" /> <use href="#disp_seg_vert" /> <use href="#disp_seg_vert" y="100" /> <use href="#disp_seg_vert" x="100" y="100" /> <use href="#disp_seg_horiz" x="5" y="95" /> <use href="#disp_seg_horiz" x="5" y="195" /> </g> <g id="7_lcd"> <use href="#disp_seg_horiz" /> <use href="#disp_seg_vert" x="95" y="5" /> <use href="#disp_seg_vert" x="95" y="100" /> </g> <g id="67_lcd"> <use href="#6_lcd" /> <use href="#7_lcd" x="150" /> </g> <pattern id="background_6_7" width="80" height="80" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse"> <rect fill="black" x="0" y="0" width="80" height="80" /> <use href="#six-seven" fill="#333" style="transform: scale(0.5)" /> <use href="#67_lcd" fill="#333" x="400" y="25" style="transform: scale(0.1)" /> <use href="#67_lcd" fill="#333" y="400" x="25" style="transform: scale(0.1)" /> <use href="#six-seven" fill="#333" x="80" y="80" style="transform: scale(0.5)" /> </pattern> <text class="label1" id="67_1">67</text> <text class="label2" id="67_2">67</text> <text class="label3" id="67_3">67</text> <text class="label1" id="67_4">six seven</text> <text class="label2" id="67_5">six seven</text> <text class="label3" id="67_6">six seven</text> <text class="label4" id="67_7">67</text> <text class="label5" id="67_8">67</text> <text class="label4" id="67_9">six seven</text> <text class="label5" id="67_10">six seven</text> <text class="label6" id="67_11">67</text> <text class="label6" id="67_12">six seven</text> <rect class="background" id="bg" x="-80" y="-80" width="960" height="660" fill="url(#background_6_7)" /> </defs> <style> .label1 { font: 60px sans-serif; } .label2 { font: 120px serif; } .label3 { font: 90px monospace; } .label4 { font: 100px cursive; } .label5 { font: 75px fantasy; } .label6 { font: 130px system-ui; } </style> </svg></p>
<p><a href="/67_animation/">A version on its own page</a></p>
<h2>Source code</h2>
<p>In case you are interested, below is the source code for this animation.</p>
<h3>Standalone HTML</h3>
<p>This is the page linked above.</p><div class="code_block"><div class="code-header"><span class="filename">index.html</span> <span class="code-lang">HTML</span></div><pre class=""  id="block-c5cdd230-9611-4131-b82e-1e2ec26b4601"><code class="language-html"><code class="checker lineno dig-2"><span style="color:#586e75;">&lt;!</span><span style="color:#268bd2;">doctype</span><span style="color:#839496;"> html</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">html </span><span style="color:#b58900;">lang</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">en</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;!--</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;">  Silly* six-seven animation</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"></span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;">  Christopher Phan &lt;https://chrisphan.com/&gt;</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;">  2026-W01</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"></span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;">  For Emmy</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">  SPDX-License-Identifier: MIT</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">  *This whole six-seven thing is silly, but so is finding 1000 creative ways to</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">   trick someone into watching the same Rick Astley video :-) --&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">head</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">title</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">Six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">title</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">meta </span><span style="color:#b58900;">charset</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">utf-8</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">link </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">reset.css</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">rel</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">stylesheet</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">link </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">animate.css</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">rel</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">stylesheet</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">head</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">body</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">svg</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">      </span><span style="color:#b58900;">width</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">800</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">      </span><span style="color:#b58900;">height</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">500</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">      </span><span style="color:#b58900;">xmlns</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">http://www.w3.org/2000/svg</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">      </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_animation</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">      </span><span style="color:#b58900;">aria-label</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">The number 67 and the words &#39;six seven&#39; in various fonts and colors move horizontally from right to left at differing speeds.</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">    </span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">      &gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">      </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">defs</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">path</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">d</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">M 0,0 v -40 a 50 50 180 0 0 -100 0 v 120</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                a 50 50 180 0 0 100 0 v -19 h -20 v 14</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                a 30 30 180 0 1 -60 0 v -20</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                a 30 30 180 0 1 60 0 h 20 v -5 a 40 40 90 0 0 -40 -40</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                q -40 0 -40 10 v -60 a 30 30 180 0 1 60 0 v 30 z</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">six</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">       </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">path</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">d</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">M 0,0 h 150 v 25 c -30,0  -70,30 -70,70 v 30 h 50 v 20 h -50</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                v 75 h -25 v -75 h -50 v -20 h 50 v -35 c 0,-30 30,-50 40,-60</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                h -110 v -25 z  </span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">seven</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">       </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">g </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">six-seven</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#six</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">100</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">90</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">scale</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0.2</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#seven</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">135</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">2</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">scale</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0.2</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">g</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">path</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">disp_seg_vert</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">d</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">M 0,0 l 20,20 v 50 l -20,20 l -20,-20</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">                    v -50 l 20,-20 </span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">       </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">g </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">disp_seg_horiz</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_vert</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">rotateZ</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">-90</span><span style="color:#859900;">deg</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">g</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">g </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">6_lcd</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_horiz</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">5</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">-5</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_vert</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_vert</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">100</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_vert</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">100</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">100</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_horiz</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">5</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">95</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_horiz</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">5</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">195</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">g</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">g </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">7_lcd</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_horiz</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_vert</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">95</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">5</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#disp_seg_vert</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">95</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">100</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">g</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">g </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_lcd</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#6_lcd</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#7_lcd</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">150</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">g</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">pattern</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">background_6_7</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">width</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">80</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">height</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">80</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">patternUnits</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">userSpaceOnUse</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">          </span><span style="color:#b58900;">patternContentUnits</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">userSpaceOnUse</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">        </span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">rect </span><span style="color:#b58900;">fill</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">black</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">width</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">80</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">height</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">80</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#six-seven</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#333</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">scale</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0.5</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#67_lcd</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">fill</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#333</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">400</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">25</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">scale</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0.1</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">         </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#67_lcd</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">fill</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#333</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">            </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">400</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">25</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">scale</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0.1</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">         </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">use</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">href</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#six-seven</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">fill</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">#333</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">80</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">80</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">            </span><span style="color:#b58900;">style</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">transform</span><span style="color:#657b83;">: </span><span style="color:#859900;">scale</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0.5</span><span style="color:#657b83;">)</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">         </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">pattern</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label1</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_1</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">67</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label2</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_2</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">67</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label3</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_3</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">67</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label1</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_4</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label2</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_5</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label3</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_6</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label4</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_7</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">67</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label5</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_8</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">67</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label4</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_9</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label5</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_10</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label6</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_11</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">67</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">text </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">label6</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_12</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span><span style="color:#839496;">six seven</span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">text</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">rect</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">class</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">background</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">bg</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">x</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">-80</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">y</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">-80</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">width</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">960</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">height</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">660</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">          </span><span style="color:#b58900;">fill</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">url(#background_6_7)</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">       </span><span style="color:#586e75;"> /&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">defs</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">style</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">        </span><span style="color:#b58900;">.label1 </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#859900;">font</span><span style="color:#839496;">: </span><span style="color:#6c71c4;">60</span><span style="color:#859900;">px sans-serif</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">        </span><span style="color:#b58900;">.label2 </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#859900;">font</span><span style="color:#839496;">: </span><span style="color:#6c71c4;">120</span><span style="color:#859900;">px serif</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">        </span><span style="color:#b58900;">.label3 </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#859900;">font</span><span style="color:#839496;">: </span><span style="color:#6c71c4;">90</span><span style="color:#859900;">px monospace</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">        </span><span style="color:#b58900;">.label4 </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#859900;">font</span><span style="color:#839496;">: </span><span style="color:#6c71c4;">100</span><span style="color:#859900;">px cursive</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">        </span><span style="color:#b58900;">.label5 </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#859900;">font</span><span style="color:#839496;">: </span><span style="color:#6c71c4;">75</span><span style="color:#859900;">px fantasy</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">        </span><span style="color:#b58900;">.label6 </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          </span><span style="color:#859900;">font</span><span style="color:#839496;">: </span><span style="color:#6c71c4;">130</span><span style="color:#859900;">px system-ui</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">style</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">svg</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">script </span><span style="color:#b58900;">src</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">animation_67.js</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;&lt;/</span><span style="color:#268bd2;">script</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">body</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">html</span><span style="color:#586e75;">&gt;</span></code>
</code></pre></div>
<h3>Typescript</h3>
<p>I wrote the main script in TypeScript. It needs to be transpiled down to
JavaScript before being used.</p><div class="code_block"><div class="code-header"><span class="filename">animation_67.ts</span> <span class="code-lang">TypeScript</span></div><pre class=""  id="block-0771e808-1ebc-4a71-988a-e8fbef1f1e9c"><code class="language-javascript"><code class="checker lineno dig-2"><span style="color:#586e75;">/* @filename: animation_67.ts</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> * Silly* six-seven animation</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> * Christopher Phan &lt;https://chrisphan.com/&gt;</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> * 2026-W01</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> * For Emmy</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"> * SPDX-License-Identifier: MIT</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"> * *This whole six-seven thing is silly, but so is finding 1000 creative ways to</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"> *  trick someone into watching the same Rick Astley video :-)</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"> */</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#268bd2;">class </span><span style="color:#b58900;">AnimatedElt </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">// Represents a `use` element in an SVG that we will be moving around</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    elt: SVGUseElement</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    rootSvg: SVGElement</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">constructor</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">elt</span><span style="color:#839496;">: </span><span style="color:#268bd2;">SVGUseElement</span><span style="color:#839496;">, </span><span style="color:#268bd2;">rootSvg</span><span style="color:#839496;">: </span><span style="color:#268bd2;">SVGElement</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.elt </span><span style="color:#657b83;">= </span><span style="color:#839496;">elt</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.rootSvg </span><span style="color:#657b83;">= </span><span style="color:#839496;">rootSvg</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">create</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">targetSVG</span><span style="color:#839496;">: </span><span style="color:#268bd2;">SVGElement</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">x</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">y</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">href</span><span style="color:#839496;">: </span><span style="color:#268bd2;">string</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">id</span><span style="color:#839496;">: </span><span style="color:#268bd2;">string</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">fill</span><span style="color:#839496;">: </span><span style="color:#268bd2;">string</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">)</span><span style="color:#839496;">: AnimatedElt {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        const elt = document.</span><span style="color:#b58900;">createElementNS</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#268bd2;">http</span><span style="color:#839496;">:</span><span style="color:#586e75;">//www.w3.org/2000/svg&#39;, &#39;use&#39;)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">elt</span><span style="color:#839496;">.</span><span style="color:#268bd2;">setAttribute</span><span style="color:#839496;">(&#39;</span><span style="color:#268bd2;">x</span><span style="color:#839496;">&#39;, `</span><span style="color:#268bd2;">$</span><span style="color:#657b83;">{</span><span style="color:#268bd2;">x</span><span style="color:#657b83;">}</span><span style="color:#839496;">`</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        elt.</span><span style="color:#b58900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#268bd2;">y</span><span style="color:#839496;">&#39;, `</span><span style="color:#268bd2;">$</span><span style="color:#657b83;">{</span><span style="color:#268bd2;">y</span><span style="color:#657b83;">}</span><span style="color:#839496;">`</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        elt.</span><span style="color:#b58900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#268bd2;">id</span><span style="color:#839496;">&#39;, </span><span style="color:#268bd2;">id</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        elt.</span><span style="color:#b58900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#268bd2;">fill</span><span style="color:#839496;">&#39;, </span><span style="color:#268bd2;">fill</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        elt.</span><span style="color:#b58900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#268bd2;">href</span><span style="color:#839496;">&#39;, `#</span><span style="color:#268bd2;">$</span><span style="color:#657b83;">{</span><span style="color:#268bd2;">href</span><span style="color:#657b83;">}</span><span style="color:#839496;">`</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        targetSVG.</span><span style="color:#b58900;">appendChild</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">elt</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        return new </span><span style="color:#b58900;">AnimatedElt</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">elt</span><span style="color:#839496;">, </span><span style="color:#268bd2;">targetSVG</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">move</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">dx</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">, </span><span style="color:#268bd2;">dy</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">dx </span><span style="color:#657b83;">!== </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#268bd2;">const </span><span style="color:#839496;">currentX </span><span style="color:#657b83;">= </span><span style="color:#d33682;">this</span><span style="color:#839496;">.elt.</span><span style="color:#859900;">getAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">x</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">let </span><span style="color:#839496;">newX </span><span style="color:#657b83;">= </span><span style="color:#839496;">dx</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">currentX </span><span style="color:#657b83;">!== </span><span style="color:#b58900;">null</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">                newX </span><span style="color:#657b83;">+= </span><span style="color:#859900;">parseFloat</span><span style="color:#657b83;">(</span><span style="color:#839496;">currentX</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#d33682;">this</span><span style="color:#839496;">.elt.</span><span style="color:#859900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">x</span><span style="color:#839496;">&#39;, `${newX}`</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">const </span><span style="color:#839496;">currentY </span><span style="color:#657b83;">= </span><span style="color:#d33682;">this</span><span style="color:#839496;">.elt.</span><span style="color:#859900;">getAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">y</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">dy </span><span style="color:#657b83;">!== </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#268bd2;">let </span><span style="color:#839496;">newY </span><span style="color:#657b83;">= </span><span style="color:#839496;">dy</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">currentY </span><span style="color:#657b83;">!== </span><span style="color:#b58900;">null</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">                newY </span><span style="color:#657b83;">+= </span><span style="color:#859900;">parseFloat</span><span style="color:#657b83;">(</span><span style="color:#839496;">currentY</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#d33682;">this</span><span style="color:#839496;">.elt.</span><span style="color:#859900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">y</span><span style="color:#839496;">&#39;, `${newY}`</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#268bd2;">class </span><span style="color:#b58900;">Mover </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    velocityX: number</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    velocityY: number</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    item: AnimatedElt</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    lastUpdate: Date</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">constructor</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">velocityX</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">, </span><span style="color:#268bd2;">velocityY</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">, </span><span style="color:#268bd2;">item</span><span style="color:#839496;">: </span><span style="color:#268bd2;">AnimatedElt</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.velocityX </span><span style="color:#657b83;">= </span><span style="color:#839496;">velocityX</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.velocityY </span><span style="color:#657b83;">= </span><span style="color:#839496;">velocityY</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.item </span><span style="color:#657b83;">= </span><span style="color:#839496;">item</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.lastUpdate </span><span style="color:#657b83;">= </span><span style="color:#859900;">new Date</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">create</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">targetSVG</span><span style="color:#839496;">: </span><span style="color:#268bd2;">SVGElement</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">x</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">y</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">href</span><span style="color:#839496;">: </span><span style="color:#268bd2;">string</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">id</span><span style="color:#839496;">: </span><span style="color:#268bd2;">string</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">fill</span><span style="color:#839496;">: </span><span style="color:#268bd2;">string</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">velocityX</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">velocityY</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">)</span><span style="color:#839496;">: Mover {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            const item = AnimatedElt.prototype.</span><span style="color:#b58900;">create</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">                </span><span style="color:#268bd2;">targetSVG</span><span style="color:#839496;">, </span><span style="color:#268bd2;">x</span><span style="color:#839496;">, </span><span style="color:#268bd2;">y</span><span style="color:#839496;">, </span><span style="color:#268bd2;">href</span><span style="color:#839496;">, </span><span style="color:#268bd2;">id</span><span style="color:#839496;">, </span><span style="color:#268bd2;">fill</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            return new </span><span style="color:#b58900;">Mover</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">velocityX</span><span style="color:#839496;">, </span><span style="color:#268bd2;">velocityY</span><span style="color:#839496;">, </span><span style="color:#268bd2;">item</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">update</span><span style="color:#657b83;">() {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">const </span><span style="color:#839496;">now </span><span style="color:#657b83;">= </span><span style="color:#859900;">new Date</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#268bd2;">const </span><span style="color:#839496;">elapsedTime </span><span style="color:#657b83;">= (</span><span style="color:#839496;">now.</span><span style="color:#b58900;">valueOf</span><span style="color:#657b83;">() - </span><span style="color:#d33682;">this</span><span style="color:#839496;">.lastUpdate.</span><span style="color:#b58900;">valueOf</span><span style="color:#657b83;">()) / </span><span style="color:#6c71c4;">1000</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.lastUpdate </span><span style="color:#657b83;">= </span><span style="color:#839496;">now</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#d33682;">this</span><span style="color:#839496;">.item.</span><span style="color:#b58900;">move</span><span style="color:#657b83;">(</span><span style="color:#d33682;">this</span><span style="color:#839496;">.velocityX </span><span style="color:#657b83;">* </span><span style="color:#839496;">elapsedTime, </span><span style="color:#d33682;">this</span><span style="color:#839496;">.velocityY </span><span style="color:#657b83;">* </span><span style="color:#839496;">elapsedTime</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">function </span><span style="color:#b58900;">randomColor</span><span style="color:#657b83;">()</span><span style="color:#839496;">: string </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">hue </span><span style="color:#657b83;">= </span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">floor</span><span style="color:#657b83;">(</span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">random</span><span style="color:#657b83;">() * </span><span style="color:#6c71c4;">360</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">sat </span><span style="color:#657b83;">= </span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">random</span><span style="color:#657b83;">() * </span><span style="color:#6c71c4;">100</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">light </span><span style="color:#657b83;">= </span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">random</span><span style="color:#657b83;">() * </span><span style="color:#6c71c4;">75 </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">25</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">return </span><span style="color:#839496;">`</span><span style="color:#2aa198;">hsl(</span><span style="color:#839496;">${hue}</span><span style="color:#2aa198;">, </span><span style="color:#839496;">${sat}</span><span style="color:#2aa198;">%, </span><span style="color:#839496;">${light}</span><span style="color:#2aa198;">%)</span><span style="color:#839496;">`</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">/* The SVG should have the following elements defined:</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"> * - 67_lcd</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"> * - background_6_7 (pattern)</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"> * - 67_n for n = 1 to 12</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"> *</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"> * For example: https://chrisphan.com/67_animation/</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"> */</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">function </span><span style="color:#b58900;">createNew</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">n</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">, </span><span style="color:#268bd2;">targetSVG</span><span style="color:#839496;">: </span><span style="color:#268bd2;">SVGElement</span><span style="color:#657b83;">)</span><span style="color:#839496;">: Mover </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">y </span><span style="color:#657b83;">= </span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">random</span><span style="color:#657b83;">() * </span><span style="color:#6c71c4;">500</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">let </span><span style="color:#839496;">c </span><span style="color:#657b83;">= </span><span style="color:#839496;">n</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">n </span><span style="color:#859900;">&gt; </span><span style="color:#6c71c4;">13</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        c </span><span style="color:#657b83;">= </span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">floor</span><span style="color:#657b83;">(</span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">random</span><span style="color:#657b83;">() * </span><span style="color:#6c71c4;">14</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">let </span><span style="color:#839496;">href: string </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">c </span><span style="color:#657b83;">=== </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        href </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">six-seven</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">} </span><span style="color:#859900;">else if </span><span style="color:#657b83;">(</span><span style="color:#839496;">c </span><span style="color:#657b83;">=== </span><span style="color:#6c71c4;">13</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        href </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">67_lcd</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">} </span><span style="color:#859900;">else  </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        href </span><span style="color:#657b83;">= </span><span style="color:#839496;">`</span><span style="color:#2aa198;">67_</span><span style="color:#839496;">${c}`</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">id </span><span style="color:#657b83;">= </span><span style="color:#839496;">`</span><span style="color:#2aa198;">mover_</span><span style="color:#839496;">${n}`</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">fill </span><span style="color:#657b83;">= </span><span style="color:#b58900;">randomColor</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">velocityX </span><span style="color:#657b83;">= - (</span><span style="color:#859900;">Math</span><span style="color:#839496;">.</span><span style="color:#b58900;">random</span><span style="color:#657b83;">() * </span><span style="color:#6c71c4;">50 </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">50</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">return Mover</span><span style="color:#839496;">.</span><span style="color:#859900;">prototype</span><span style="color:#839496;">.</span><span style="color:#b58900;">create</span><span style="color:#657b83;">(</span><span style="color:#839496;">targetSVG, </span><span style="color:#6c71c4;">850</span><span style="color:#839496;">, y, href, id, fill, velocityX, </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">function </span><span style="color:#b58900;">update</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">targetSVG</span><span style="color:#839496;">: </span><span style="color:#268bd2;">SVGElement</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">objects</span><span style="color:#839496;">: </span><span style="color:#268bd2;">Array</span><span style="color:#839496;">&lt;</span><span style="color:#268bd2;">Mover</span><span style="color:#839496;">&gt;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">active</span><span style="color:#839496;">: </span><span style="color:#268bd2;">Array</span><span style="color:#839496;">&lt;</span><span style="color:#268bd2;">number</span><span style="color:#839496;">&gt;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">startTime</span><span style="color:#839496;">: </span><span style="color:#268bd2;">Date</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">count</span><span style="color:#839496;">: </span><span style="color:#268bd2;">number</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">lastAdded</span><span style="color:#839496;">: </span><span style="color:#268bd2;">Date</span><span style="color:#839496;"> | </span><span style="color:#268bd2;">null</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">inactive</span><span style="color:#839496;">: </span><span style="color:#268bd2;">Array</span><span style="color:#839496;">&lt;</span><span style="color:#268bd2;">number</span><span style="color:#839496;">&gt;</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">now </span><span style="color:#657b83;">= </span><span style="color:#859900;">new Date</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">const </span><span style="color:#839496;">elapsedTime </span><span style="color:#657b83;">= (</span><span style="color:#839496;">now.</span><span style="color:#b58900;">valueOf</span><span style="color:#657b83;">() - </span><span style="color:#839496;">startTime.</span><span style="color:#b58900;">valueOf</span><span style="color:#657b83;">()) / </span><span style="color:#6c71c4;">1000</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">let </span><span style="color:#839496;">sinceLastAdded </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">1000000</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">lastAdded </span><span style="color:#657b83;">!== </span><span style="color:#b58900;">null</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        sinceLastAdded </span><span style="color:#657b83;">= (</span><span style="color:#839496;">now.</span><span style="color:#b58900;">valueOf</span><span style="color:#657b83;">() - </span><span style="color:#839496;">lastAdded.</span><span style="color:#b58900;">valueOf</span><span style="color:#657b83;">()) / </span><span style="color:#6c71c4;">1000</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">let </span><span style="color:#839496;">newCount </span><span style="color:#657b83;">= </span><span style="color:#839496;">count</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">let </span><span style="color:#839496;">addedOne </span><span style="color:#657b83;">= </span><span style="color:#b58900;">false</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">elapsedTime </span><span style="color:#859900;">&gt; </span><span style="color:#839496;">newCount </span><span style="color:#859900;">&amp;&amp; </span><span style="color:#839496;">sinceLastAdded </span><span style="color:#859900;">&gt; </span><span style="color:#6c71c4;">0.5</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">objects.length </span><span style="color:#859900;">&lt; </span><span style="color:#6c71c4;">60</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#268bd2;">const </span><span style="color:#839496;">newThing </span><span style="color:#657b83;">= </span><span style="color:#b58900;">createNew</span><span style="color:#657b83;">(</span><span style="color:#839496;">count, targetSVG</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            objects.</span><span style="color:#859900;">push</span><span style="color:#657b83;">(</span><span style="color:#839496;">newThing</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            active.</span><span style="color:#859900;">push</span><span style="color:#657b83;">(</span><span style="color:#839496;">objects.length </span><span style="color:#657b83;">- </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            addedOne </span><span style="color:#657b83;">= </span><span style="color:#b58900;">true</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">} </span><span style="color:#859900;">else if </span><span style="color:#657b83;">(</span><span style="color:#839496;">inactive.length </span><span style="color:#859900;">&gt; </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#268bd2;">const </span><span style="color:#839496;">recycledIndex </span><span style="color:#657b83;">= </span><span style="color:#839496;">inactive.</span><span style="color:#859900;">shift</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#268bd2;">const </span><span style="color:#839496;">recycled </span><span style="color:#657b83;">= </span><span style="color:#839496;">objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">recycledIndex</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            recycled.item.elt.</span><span style="color:#859900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">x</span><span style="color:#839496;">&#39;, `${</span><span style="color:#6c71c4;">850</span><span style="color:#839496;">}`</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            recycled.lastUpdate </span><span style="color:#657b83;">= </span><span style="color:#859900;">new Date</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            active.</span><span style="color:#859900;">push</span><span style="color:#657b83;">(</span><span style="color:#839496;">recycledIndex</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            addedOne </span><span style="color:#657b83;">= </span><span style="color:#b58900;">true</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">addedOne</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            newCount</span><span style="color:#657b83;">++</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            lastAdded </span><span style="color:#657b83;">= </span><span style="color:#859900;">new Date</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">let </span><span style="color:#839496;">newActive: </span><span style="color:#859900;">Array&lt;</span><span style="color:#839496;">number</span><span style="color:#859900;">&gt; </span><span style="color:#657b83;">= </span><span style="color:#268bd2;">[]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    active.</span><span style="color:#b58900;">forEach</span><span style="color:#657b83;">((</span><span style="color:#268bd2;">idx</span><span style="color:#657b83;">) </span><span style="color:#268bd2;">=&gt; </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">update</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.item.elt.</span><span style="color:#859900;">getAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">id</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">) === </span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">back</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#859900;">parseFloat</span><span style="color:#657b83;">(</span><span style="color:#839496;">objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.item.elt.</span><span style="color:#859900;">getAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">x</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)) </span><span style="color:#859900;">&gt; </span><span style="color:#6c71c4;">80</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.item.elt.</span><span style="color:#859900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">x</span><span style="color:#839496;">&#39;, &#39;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#859900;">parseFloat</span><span style="color:#657b83;">(</span><span style="color:#839496;">objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.item.elt.</span><span style="color:#859900;">getAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">y</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)) </span><span style="color:#859900;">&gt; </span><span style="color:#6c71c4;">80</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.item.elt.</span><span style="color:#859900;">setAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">y</span><span style="color:#839496;">&#39;, &#39;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            newActive.</span><span style="color:#859900;">push</span><span style="color:#657b83;">(</span><span style="color:#839496;">idx</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">else if </span><span style="color:#657b83;">(</span><span style="color:#859900;">parseFloat</span><span style="color:#657b83;">(</span><span style="color:#839496;">objects</span><span style="color:#268bd2;">[</span><span style="color:#839496;">idx</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.item.elt.</span><span style="color:#859900;">getAttribute</span><span style="color:#657b83;">(</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">x</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)) </span><span style="color:#859900;">&gt; </span><span style="color:#657b83;">-</span><span style="color:#6c71c4;">1000</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            newActive.</span><span style="color:#859900;">push</span><span style="color:#657b83;">(</span><span style="color:#839496;">idx</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">} </span><span style="color:#859900;">else </span><span style="color:#657b83;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            inactive.</span><span style="color:#859900;">push</span><span style="color:#657b83;">(</span><span style="color:#839496;">idx</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">})</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">window</span><span style="color:#839496;">.</span><span style="color:#b58900;">requestAnimationFrame</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">() </span><span style="color:#268bd2;">=&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#b58900;">update</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            targetSVG,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            objects,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            newActive,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            startTime,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            newCount,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            lastAdded,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            inactive</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">const </span><span style="color:#839496;">mainSvg </span><span style="color:#657b83;">= </span><span style="color:#859900;">document</span><span style="color:#839496;">.</span><span style="color:#b58900;">querySelector</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">svg[id=&#39;67_animation&#39;]</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">as </span><span style="color:#839496;">SVGElement</span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">let </span><span style="color:#839496;">background </span><span style="color:#657b83;">= </span><span style="color:#859900;">Mover</span><span style="color:#839496;">.</span><span style="color:#859900;">prototype</span><span style="color:#839496;">.</span><span style="color:#b58900;">create</span><span style="color:#657b83;">(</span><span style="color:#839496;">mainSvg, </span><span style="color:#657b83;">-</span><span style="color:#6c71c4;">80</span><span style="color:#839496;">, </span><span style="color:#657b83;">-</span><span style="color:#6c71c4;">80</span><span style="color:#839496;">, &quot;</span><span style="color:#2aa198;">bg</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">back</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">#333</span><span style="color:#839496;">&quot;, </span><span style="color:#6c71c4;">5</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">let </span><span style="color:#839496;">objects: </span><span style="color:#859900;">Array&lt;</span><span style="color:#839496;">Mover</span><span style="color:#859900;">&gt; </span><span style="color:#657b83;">= </span><span style="color:#268bd2;">[</span><span style="color:#839496;">background</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">let </span><span style="color:#839496;">active: </span><span style="color:#859900;">Array&lt;</span><span style="color:#839496;">number</span><span style="color:#859900;">&gt; </span><span style="color:#657b83;">= </span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#268bd2;">const </span><span style="color:#839496;">startTime </span><span style="color:#657b83;">= </span><span style="color:#859900;">new Date</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#b58900;">update</span><span style="color:#657b83;">(</span><span style="color:#839496;">mainSvg, objects, </span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span><span style="color:#839496;">, startTime, </span><span style="color:#6c71c4;">0</span><span style="color:#839496;">, </span><span style="color:#b58900;">null</span><span style="color:#839496;">, </span><span style="color:#268bd2;">[]</span><span style="color:#657b83;">)</span></code>
</code></pre></div>]]></content:encoded></item><item><title>Happy ISO Week Date New Year!</title><link>https:://chrisphan.com/posts/2025-12-29_happy_new_year.html</link><description><![CDATA[ Happy New Year—under the ISO week date calendar , that is! As I explained exactly 52 weeks ago , a year in the ISO week]]></description><guid>https:://chrisphan.com/posts/2025-12-29_happy_new_year.html</guid><pubDate>Mon, 29 Dec 2025 09:00:00 -0600</pubDate><content:encoded><![CDATA[
<p>Happy New Year—under the <a href="https://en.wikipedia.org/wiki/ISO_week_date">ISO week date
calendar</a>, that is!</p>
<p><a href="/posts/2024-12-30_happy_new_year.html">As I explained exactly 52 weeks ago</a>,
a year in the ISO week date calendar is made up of exactly 52 or 53 weeks, so
that every week (Monday through Sunday) is in the same year. So even though
today is 2025-12-29 in the Gregorian calendar (in ISO 8601), under the ISO week
date calendar, today is 2026-W01-1 , i.e., the first day (Monday) of the first
week of 2025.</p>
<p>Also, 2026 has 53 weeks in the ISO week date calendar. Most years only get 52,
but any Gregorian year that beings on a Thursday, and any Gregorian leap year
that begins on a Wednesday, will have 53 weeks in the ISO week date calendar.</p>
<p>In general, the year that a week falls in is determined by the Gregorian year
of its Thursday. This week is assigned to 2026 because Thursday is in 2026;
indeed, Thursday is the Gregorian New Year's Day.</p>
<p>Here is a simple Python script I wrote to make a table showing the start of each
week in the ISO week date calendar:</p><div class="code_block"><div class="code-header"><span class="filename">iso_week_date_table.py</span> <span class="code-lang">Python</span></div><pre class=""  id="block-5652579e-93dd-423f-8803-8b2dda846d32"><code class="language-python"><code class="checker lineno dig-1"><span style="color:#586e75;">#!/usr/bin/env python3</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">&quot;&quot;&quot;Produce a Markdown table for the ISO week-date calendar.&quot;&quot;&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># Christopher Phan</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># 2025-W52</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># SPDX-License-Identifier: MIT</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">datetime</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">string</span></code>
<code class="checker lineno dig-0"><span style="color:#cb4b16;">import </span><span style="color:#839496;">sys</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">def </span><span style="color:#b58900;">iso_table</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">year</span><span style="color:#839496;">: </span><span style="color:#859900;">int</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; </span><span style="color:#859900;">str</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">&quot;&quot;&quot;Produce a Markdown table for the ISO week-date calendar.&quot;&quot;&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    outstr </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">| ISO week date | ISO Gregorian |</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    outstr </span><span style="color:#657b83;">+= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">|:--------------|:--------------|</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    jan_1 </span><span style="color:#657b83;">= </span><span style="color:#839496;">datetime.</span><span style="color:#b58900;">date</span><span style="color:#657b83;">(</span><span style="color:#839496;">year, </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;"># If Jan 1 is a Thursday, or is Wednesday of a leap year, there is 53 weeks.</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;"># Otherwise 52 weeks:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#839496;">jan_1.</span><span style="color:#b58900;">isoweekday</span><span style="color:#657b83;">() == </span><span style="color:#6c71c4;">4 </span><span style="color:#859900;">or </span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        jan_1.</span><span style="color:#b58900;">isoweekday</span><span style="color:#657b83;">() == </span><span style="color:#6c71c4;">3 </span><span style="color:#859900;">and </span><span style="color:#657b83;">(</span><span style="color:#839496;">year </span><span style="color:#657b83;">% </span><span style="color:#6c71c4;">400 </span><span style="color:#657b83;">== </span><span style="color:#6c71c4;">0 </span><span style="color:#859900;">or </span><span style="color:#839496;">year </span><span style="color:#657b83;">% </span><span style="color:#6c71c4;">4 </span><span style="color:#657b83;">== </span><span style="color:#6c71c4;">0 </span><span style="color:#859900;">and </span><span style="color:#839496;">year </span><span style="color:#657b83;">% </span><span style="color:#6c71c4;">100</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        num_weeks </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">53</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        num_weeks </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">52</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">for </span><span style="color:#839496;">week </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#839496;">num_weeks</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        d </span><span style="color:#657b83;">= </span><span style="color:#839496;">datetime.date.</span><span style="color:#b58900;">fromisocalendar</span><span style="color:#657b83;">(</span><span style="color:#839496;">year, week </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        outstr </span><span style="color:#657b83;">+= </span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">| </span><span style="color:#657b83;">{</span><span style="color:#839496;">year</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">-W</span><span style="color:#657b83;">{</span><span style="color:#839496;">week</span><span style="color:#657b83;">+</span><span style="color:#6c71c4;">1</span><span style="color:#cb4b16;">:02d</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">-1    | </span><span style="color:#657b83;">{</span><span style="color:#839496;">d</span><span style="color:#cb4b16;">:%Y-%m-%d</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">    |</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">return </span><span style="color:#839496;">outstr</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">if __name__ </span><span style="color:#657b83;">== </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">__main__</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if len</span><span style="color:#657b83;">(</span><span style="color:#839496;">sys.argv</span><span style="color:#657b83;">) &gt; </span><span style="color:#6c71c4;">1 </span><span style="color:#859900;">and </span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;"># strip out any non-digit characters from the first argument</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        year_str := &quot;&quot;.</span><span style="color:#b58900;">join</span><span style="color:#657b83;">(</span><span style="color:#839496;">k </span><span style="color:#859900;">if </span><span style="color:#839496;">k </span><span style="color:#859900;">in </span><span style="color:#839496;">string.digits </span><span style="color:#859900;">else </span><span style="color:#839496;">&quot;&quot; </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in </span><span style="color:#839496;">sys.argv</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">1</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        year </span><span style="color:#657b83;">= </span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">year_str</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        year </span><span style="color:#657b83;">= </span><span style="color:#839496;">datetime.date.</span><span style="color:#b58900;">today</span><span style="color:#657b83;">()</span><span style="color:#839496;">.year</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#b58900;">iso_table</span><span style="color:#657b83;">(</span><span style="color:#839496;">year</span><span style="color:#657b83;">))</span></code>
</code></pre></div>
<p>And here is the resulting table (after the Markdown is rendered as HTML):</p>
<table>
<thead>
<tr>
<th align="left">ISO week date</th>
<th align="left">ISO Gregorian</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">2026-W01-1</td>
<td align="left">2025-12-29</td>
</tr>
<tr>
<td align="left">2026-W02-1</td>
<td align="left">2026-01-05</td>
</tr>
<tr>
<td align="left">2026-W03-1</td>
<td align="left">2026-01-12</td>
</tr>
<tr>
<td align="left">2026-W04-1</td>
<td align="left">2026-01-19</td>
</tr>
<tr>
<td align="left">2026-W05-1</td>
<td align="left">2026-01-26</td>
</tr>
<tr>
<td align="left">2026-W06-1</td>
<td align="left">2026-02-02</td>
</tr>
<tr>
<td align="left">2026-W07-1</td>
<td align="left">2026-02-09</td>
</tr>
<tr>
<td align="left">2026-W08-1</td>
<td align="left">2026-02-16</td>
</tr>
<tr>
<td align="left">2026-W09-1</td>
<td align="left">2026-02-23</td>
</tr>
<tr>
<td align="left">2026-W10-1</td>
<td align="left">2026-03-02</td>
</tr>
<tr>
<td align="left">2026-W11-1</td>
<td align="left">2026-03-09</td>
</tr>
<tr>
<td align="left">2026-W12-1</td>
<td align="left">2026-03-16</td>
</tr>
<tr>
<td align="left">2026-W13-1</td>
<td align="left">2026-03-23</td>
</tr>
<tr>
<td align="left">2026-W14-1</td>
<td align="left">2026-03-30</td>
</tr>
<tr>
<td align="left">2026-W15-1</td>
<td align="left">2026-04-06</td>
</tr>
<tr>
<td align="left">2026-W16-1</td>
<td align="left">2026-04-13</td>
</tr>
<tr>
<td align="left">2026-W17-1</td>
<td align="left">2026-04-20</td>
</tr>
<tr>
<td align="left">2026-W18-1</td>
<td align="left">2026-04-27</td>
</tr>
<tr>
<td align="left">2026-W19-1</td>
<td align="left">2026-05-04</td>
</tr>
<tr>
<td align="left">2026-W20-1</td>
<td align="left">2026-05-11</td>
</tr>
<tr>
<td align="left">2026-W21-1</td>
<td align="left">2026-05-18</td>
</tr>
<tr>
<td align="left">2026-W22-1</td>
<td align="left">2026-05-25</td>
</tr>
<tr>
<td align="left">2026-W23-1</td>
<td align="left">2026-06-01</td>
</tr>
<tr>
<td align="left">2026-W24-1</td>
<td align="left">2026-06-08</td>
</tr>
<tr>
<td align="left">2026-W25-1</td>
<td align="left">2026-06-15</td>
</tr>
<tr>
<td align="left">2026-W26-1</td>
<td align="left">2026-06-22</td>
</tr>
<tr>
<td align="left">2026-W27-1</td>
<td align="left">2026-06-29</td>
</tr>
<tr>
<td align="left">2026-W28-1</td>
<td align="left">2026-07-06</td>
</tr>
<tr>
<td align="left">2026-W29-1</td>
<td align="left">2026-07-13</td>
</tr>
<tr>
<td align="left">2026-W30-1</td>
<td align="left">2026-07-20</td>
</tr>
<tr>
<td align="left">2026-W31-1</td>
<td align="left">2026-07-27</td>
</tr>
<tr>
<td align="left">2026-W32-1</td>
<td align="left">2026-08-03</td>
</tr>
<tr>
<td align="left">2026-W33-1</td>
<td align="left">2026-08-10</td>
</tr>
<tr>
<td align="left">2026-W34-1</td>
<td align="left">2026-08-17</td>
</tr>
<tr>
<td align="left">2026-W35-1</td>
<td align="left">2026-08-24</td>
</tr>
<tr>
<td align="left">2026-W36-1</td>
<td align="left">2026-08-31</td>
</tr>
<tr>
<td align="left">2026-W37-1</td>
<td align="left">2026-09-07</td>
</tr>
<tr>
<td align="left">2026-W38-1</td>
<td align="left">2026-09-14</td>
</tr>
<tr>
<td align="left">2026-W39-1</td>
<td align="left">2026-09-21</td>
</tr>
<tr>
<td align="left">2026-W40-1</td>
<td align="left">2026-09-28</td>
</tr>
<tr>
<td align="left">2026-W41-1</td>
<td align="left">2026-10-05</td>
</tr>
<tr>
<td align="left">2026-W42-1</td>
<td align="left">2026-10-12</td>
</tr>
<tr>
<td align="left">2026-W43-1</td>
<td align="left">2026-10-19</td>
</tr>
<tr>
<td align="left">2026-W44-1</td>
<td align="left">2026-10-26</td>
</tr>
<tr>
<td align="left">2026-W45-1</td>
<td align="left">2026-11-02</td>
</tr>
<tr>
<td align="left">2026-W46-1</td>
<td align="left">2026-11-09</td>
</tr>
<tr>
<td align="left">2026-W47-1</td>
<td align="left">2026-11-16</td>
</tr>
<tr>
<td align="left">2026-W48-1</td>
<td align="left">2026-11-23</td>
</tr>
<tr>
<td align="left">2026-W49-1</td>
<td align="left">2026-11-30</td>
</tr>
<tr>
<td align="left">2026-W50-1</td>
<td align="left">2026-12-07</td>
</tr>
<tr>
<td align="left">2026-W51-1</td>
<td align="left">2026-12-14</td>
</tr>
<tr>
<td align="left">2026-W52-1</td>
<td align="left">2026-12-21</td>
</tr>
<tr>
<td align="left">2026-W53-1</td>
<td align="left">2026-12-28</td>
</tr>
</tbody>
</table>
<p>I wish you health, happiness, and prosperity in the next 53 weeks, and beyond.</p>]]></content:encoded></item><item><title>Improved color contrast tool</title><link>https:://chrisphan.com/posts/2025-12-27_color_contrast_improved.html</link><description><![CDATA[ I'm now indisputably middle-aged, and my eyesight isn't what it used to be. Specifically, I get very frustrated when text on screens contrasts poorly with]]></description><guid>https:://chrisphan.com/posts/2025-12-27_color_contrast_improved.html</guid><pubDate>Sat, 27 Dec 2025 12:15:00 -0600</pubDate><content:encoded><![CDATA[
<p>I'm now indisputably middle-aged, and my eyesight isn't what it used to be.
Specifically, I get very frustrated when text on screens contrasts poorly with
background colors.</p>
<figure>
<img src="/2025-W52/bad_contrast.svg" width="300" height="100"
alt="A hypothetical screenshot of a small portion of a checkout page. The label coupon code is in white text and the background color is a mustardish-yellow. It's hard to read."
/>
<figcaption>
It's hard to read this, especially after 40.
</figcaption>
</figure>
<p>A few years ago, I made an JavaScript <a href="/posts/2023-07-15_color_contrast_checker/">color contract
checker</a>. You specify two colors and
the widget will tell you how well the colors contrast, and whether the contrast
meets accessibility guidelines.</p>
<figure>
<img src="/color_contrast_screenshots/screenshot_2025-1.png" width="989" height="582"
alt="Screenshot: A widget in which the user can enter as hex triplets (or using the system color-picker) two colors. The widget then shows the relative luminance of each color as well as the contrast ratio and the WCAG 2.0 accessibility ratings for that contrast ratio"
/>
<figcaption>
The default mode of the tool is the original mode, which evaluates the contrast
between two colors.
</figcaption>
</figure>
I just released an improved version of my tool. The upgrades include:
<ul>
<li>Permanent links to your comparison (in case you find <a href="/color_contrast/?mode=2col&amp;c1=dadb0d&amp;c2=0d00d5">a particular color
combo</a> amusing.)</li>
<li><a href="/color_contrast/?mode=hue&amp;color=8b2a4c&amp;role=fg&amp;hue=81">A new mode</a>
allowing you to evaluate the contrast between one color and shades
of another.</li>
<li>Some help pages: <a href="/color_contrast/help/">instructions for using the tool</a> and
<a href="/color_contrast/help/colors.html">a gentle explanation of colors in CSS</a>.</li>
</ul>
<figure>
<img src="/color_contrast_screenshots/screenshot_2025-2.png" width="989" height="531"
alt="Screenshot: A widget in which the user can enter a color as a hex triplet, and specify the hue for a second color. The widget then shows how well the first color contrasts with various HSL combinations involving the given hue."
/>
<figcaption>
A new mode compares a fixed color against a variety of shades of a different color.
</figcaption>
</figure>
<p>On the technical side, I rewrote the code in TypeScript, a language that I have
been meaning to learn.</p>
<ul>
<li><a href="/color_contrast/">Color contrast tool</a></li>
<li><a href="https://codeberg.org/christopherphan/color_contrast">Source code (Codeberg)</a>
(<a href="https://codeberg.org/christopherphan/color_contrast/src/branch/main/LICENSE.md">MIT
License</a>)</li>
</ul>]]></content:encoded></item><item><title>Oops</title><link>https:://chrisphan.com/posts/2026-12-27_color_contrast_improved.html</link><description><![CDATA[ This was supposed to go to this URL:]]></description><guid>https:://chrisphan.com/posts/2026-12-27_color_contrast_improved.html</guid><pubDate>Sat, 27 Dec 2025 12:15:00 -0600</pubDate><content:encoded><![CDATA[
<p>This was supposed to go to this URL:
<a href="/posts/2025-12-27_color_contrast_improved.html"><code>/posts/2025-12-27_color_contrast_improved.html</code></a></p>]]></content:encoded></item><item><title>Mastodon posts for 2025-W49</title><link>https:://chrisphan.com/posts/2025-12-08_mastodon_posts_2025-W49.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/posts/2025-12-08_mastodon_posts_2025-W49.html</guid><pubDate>Mon, 8 Dec 2025 13:30:00 -0600</pubDate><content:encoded><![CDATA[
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115657237667000983"><details>
<summary>Quotes a profane word for fecal matter</summary><p>I can enthusiastically recommend &quot;Oh Shit, Git!&quot; by <span class="h-card" translate="no"><a href="https://front-end.social/@ksylor" class="u-url mention">@<span>ksylor</span></a></span> and <span class="h-card" translate="no"><a href="https://social.jvns.ca/@b0rk" class="u-url mention">@<span>b0rk</span></a></span> . Twice in the last two days I have consulted this zine to fix silly <a href="https://hachyderm.io/tags/git" class="mention hashtag" rel="tag">#<span>git</span></a> mistakes I have made.</p><p><a href="https://wizardzines.com/zines/oh-shit-git/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">wizardzines.com/zines/oh-shit-</span><span class="invisible">git/</span></a></p><p><a href="https://ohshitgit.com" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">ohshitgit.com</span><span class="invisible"></span></a></p><p>They have a no-swears version, too:</p><p><a href="https://wizardzines.com/zines/dangit-git/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">wizardzines.com/zines/dangit-g</span><span class="invisible">it/</span></a></p><p><a href="https://dangitgit.com/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">dangitgit.com/</span><span class="invisible"></span></a></p></details><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115657237667000983"><span class="date"><time datetime="2025-12-03T13:16:33-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='84.53995' y2='55.65613' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='65.48591' y2='30.37383' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 1:16"class="small_clock" />&nbsp;2025-12-03 / 2025-W49-3T13:16:33-06:00 / 0x69308c91</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115657269856288219"><p>Really, all of <span class="h-card" translate="no"><a href="https://social.jvns.ca/@b0rk" class="u-url mention">@<span>b0rk</span></a></span> &#39;s zines are really good. <a href="https://wizardzines.com" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">wizardzines.com</span><span class="invisible"></span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115657269856288219"><span class="date"><time datetime="2025-12-03T13:24:44-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='68.33951' y2='79.81044' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='66.84682' y2='31.52881' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 1:24"class="small_clock" />&nbsp;2025-12-03 / 2025-W49-3T13:24:44-06:00 / 0x69308e7c</time></span></a></p></blockquote>
</div>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115657624101810881"><p>This year, I will be posting my solutions to the <a href="https://hachyderm.io/tags/AdventOfCode" class="mention hashtag" rel="tag">#<span>AdventOfCode</span></a> on @codeberg! <a href="https://hachyderm.io/tags/Codeberg" class="mention hashtag" rel="tag">#<span>Codeberg</span></a> </p><p><a href="https://codeberg.org/christopherphan/cphan_advent_2025" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">codeberg.org/christopherphan/c</span><span class="invisible">phan_advent_2025</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115657624101810881"><span class="date"><time datetime="2025-12-03T14:54:49-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='31.92133' y2='20.03065' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='74.97443' y2='48.86956' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 2:54"class="small_clock" />&nbsp;2025-12-03 / 2025-W49-3T14:54:49-06:00 / 0x6930a399</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115675095908861933"><details>
<summary>Advent of code (general)</summary><p>One thing I love about the <a href="https://hachyderm.io/tags/AdventOfCode" class="mention hashtag" rel="tag">#<span>AdventOfCode</span></a> is when I solve Part 1 pretty quickly, without thinking too hard about efficiency, and then adapting that approach to Part 2 is a combinatorial nightmare! (Or especially when the Part 1 approach is OK for Part 2 on the sample input, but not the actual puzzle input, which tend to be larger.)</p><p>I love being pushed to come up with a better approach. It usually makes my Part 1 better when I go back and do things better.</p><p>This has happened to me several days so far.</p><p>I&#39;m also using <a href="https://hachyderm.io/tags/Clippy" class="mention hashtag" rel="tag">#<span>Clippy</span></a> (the <a href="https://hachyderm.io/tags/Rust" class="mention hashtag" rel="tag">#<span>Rust</span></a> tool, not the turn-of-the-century animated annoyance in Microsoft Office) to lint my solutions, and Clippy is great at teaching you how to write Rust better. </p><p>BTW, I have been posting my solutions on <a href="https://hachyderm.io/tags/Codeberg" class="mention hashtag" rel="tag">#<span>Codeberg</span></a> if you want to see my work:<br /><a href="https://codeberg.org/christopherphan/cphan_advent_2025" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">codeberg.org/christopherphan/c</span><span class="invisible">phan_advent_2025</span></a></p></details><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115675095908861933"><span class="date"><time datetime="2025-12-06T16:58:08-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='43.20180' y2='15.66657' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='62.85101' y2='71.44415' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 4:58"class="small_clock" />&nbsp;2025-12-06 / 2025-W49-6T16:58:08-06:00 / 0x6934b500</time></span></a></p></blockquote>
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115676673969345059"><p>&quot;I&#39;m also using <a href="https://hachyderm.io/tags/Clippy" class="mention hashtag" rel="tag">#<span>Clippy</span></a> (the <a href="https://hachyderm.io/tags/Rust" class="mention hashtag" rel="tag">#<span>Rust</span></a> tool, not the turn-of-the-century animated annoyance in Microsoft Office) ...&quot;</p><p>I just spent way too much time making this graphic to go along with that aside.</p><div class="masto-image" id="div_115676673969345059_0_905_604_png"><img src="/masto_pics/115676673969345059_0.png" width="587" height="392" alt="An animated anthropomorphized rusty paper clip says  Looks like you're writing a Rust program!  and gives tips to improve some Rust code:  warning: unnecessary use of `get(b).is_some()` .filter(|b| self.hampster_dancers.get(b).is_some()) help: replace it with: `contains_key(b)` (run `cargo clippy --fix --lib -p dancing-rodents` to apply 134 suggestions)" id="pic_115676673969345059_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115676673969345059"><span class="date"><time datetime="2025-12-06T23:39:27-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='20.74674' y2='69.21580' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='45.54068' y2='25.40093' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:39"class="small_clock" />&nbsp;2025-12-06 / 2025-W49-6T23:39:27-06:00 / 0x6935130f</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115676805999180338"><p>Okay, <a href="https://hachyderm.io/tags/storytime" class="mention hashtag" rel="tag">#<span>storytime</span></a>:  Decades ago, when I was probably 19 or 20, I wrote a snarky rant titled &quot;Why the Paper Clip Sucks&quot; about my disdain for the animated paper clip and posted it to my college web site. It ended up being quoted by <span class="h-card" translate="no"><a href="https://mastodon.social/@davew" class="u-url mention">@<span>davew</span></a></span> on his site &quot;Scripting News&quot;, which was one of the first blogs!</p><p><a href="http://scripting.com/2001/03/05.html" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">http://</span><span class="">scripting.com/2001/03/05.html</span><span class="invisible"></span></a></p><p>Sadly (or maybe not so sadly), after I graduated from college, my site went away. I have a saved copy of that essay on my machine, and maybe I will repost it some day. </p><p>Now I feel old! <a href="https://hachyderm.io/tags/XennialAngst" class="mention hashtag" rel="tag">#<span>XennialAngst</span></a></p><div class="masto-image" id="div_115676805999180338_0_402_102_png"><img src="/masto_pics/115676805999180338_0.png" width="402" height="102" alt="Screenshot of Dave Winer's blog  Scripting News :  Christopher Phan: Why The Paper Clip Sucks.  Of course, you can always get rid of him. This is what I do every time I start up any Office application. But before he disappears from the screen, he takes a second to wink. " id="pic_115676805999180338_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115676805999180338"><span class="date"><time datetime="2025-12-07T00:13:02-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='84.26036' y2='42.84264' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='52.83731' y2='25.16153' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 12:13"class="small_clock" />&nbsp;2025-12-07 / 2025-W49-7T00:13:02-06:00 / 0x69351aee</time></span></a></p></blockquote>
</div>]]></content:encoded></item><item><title>Mastodon posts for 2025-W46 through W48</title><link>https:://chrisphan.com/posts/2025-11-06_mastodon_posts_2025-W46-48.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/posts/2025-11-06_mastodon_posts_2025-W46-48.html</guid><pubDate>Sun, 30 Nov 2025 22:10:00 -0600</pubDate><content:encoded><![CDATA[
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115537276003950782"><p>Anyone else keep accidentally going to &quot;Missouri Digital News&quot; when trying to get to MDN (Mozilla Developer Network) web docs? <a href="https://hachyderm.io/tags/programming" class="mention hashtag" rel="tag">#<span>programming</span></a> <a href="https://hachyderm.io/tags/webdesign" class="mention hashtag" rel="tag">#<span>webdesign</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115537276003950782"><span class="date"><time datetime="2025-11-12T08:48:43-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='17.61766' y2='36.71903' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='25.12110' y2='52.45767' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 8:48"class="small_clock" />&nbsp;2025-11-12 / 2025-W46-3T08:48:43-06:00 / 0x69149e4b</time></span></a></p></blockquote>
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115577735917424185"><p>I made a thing: <a href="https://chrisphan.com/posts/2025-11-19_pwn_checker.html" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">chrisphan.com/posts/2025-11-19</span><span class="invisible">_pwn_checker.html</span></a> </p><p>It&#39;s a <a href="https://hachyderm.io/tags/TUI" class="mention hashtag" rel="tag">#<span>TUI</span></a> app queries the <a href="https://hachyderm.io/tags/API" class="mention hashtag" rel="tag">#<span>API</span></a> for <span class="h-card" translate="no"><a href="https://infosec.exchange/@troyhunt" class="u-url mention">@<span>troyhunt</span></a></span> &#39;s Pwned Passwords service.</p><p>I wrote it in <a href="https://hachyderm.io/tags/python" class="mention hashtag" rel="tag">#<span>python</span></a> using <span class="h-card" translate="no"><a href="https://mastodon.social/@willmcgugan" class="u-url mention">@<span>willmcgugan</span></a></span> &#39;s wonderful <a href="https://hachyderm.io/tags/Textual" class="mention hashtag" rel="tag">#<span>Textual</span></a> package.</p><p>Available on @codeberg, under an MIT license: <a href="https://codeberg.org/christopherphan/pwn_checker" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">codeberg.org/christopherphan/p</span><span class="invisible">wn_checker</span></a></p><div class="masto-image" id="div_115577735917424185_0_1131_647_png"><img src="/masto_pics/115577735917424185_0.png" width="635" height="363" alt="A screen shot of a TUI app. A password has been typed in, and its hash is shown. The program reports that this password appears in the database over two million times." id="pic_115577735917424185_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115577735917424185"><span class="date"><time datetime="2025-11-19T12:18:12-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='83.05317' y2='61.51033' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='53.95395' y2='25.31465' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 12:18"class="small_clock" />&nbsp;2025-11-19 / 2025-W47-3T12:18:12-06:00 / 0x691e09e4</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115577786300747103"><p>I spent way too much time making this diagram (<a href="https://hachyderm.io/tags/SVG" class="mention hashtag" rel="tag">#<span>SVG</span></a> by hand!) for my blog post.</p><div class="masto-image" id="div_115577786300747103_0_809_813_png"><img src="/masto_pics/115577786300747103_0.png" width="479" height="481" alt="The user types in their password (in this case,  secret ) into their computer running the Pwn Checker app. The program calculates the SHA1 hash of the password (a 40-hex digit number), and then sends the first five digits (in this case, e5e9f) to the Pwned Passwords API. The API responds with a list of every hash in the database with the same five initial digits, as well as the number of times the corresponding password appears in the database. The program then checks the returned hashes and determines whether the password was stolen." id="pic_115577786300747103_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115577786300747103"><span class="date"><time datetime="2025-11-19T12:31:01-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='46.28076' y2='84.80183' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='56.68446' y2='25.91021' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 12:31"class="small_clock" />&nbsp;2025-11-19 / 2025-W47-3T12:31:01-06:00 / 0x691e0ce5</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115577813386037833"><p>On the bright side, I think I have a better (but still imperfect) handle on how <a href="https://hachyderm.io/tags/patterns" class="mention hashtag" rel="tag">#<span>patterns</span></a> work in <a href="https://hachyderm.io/tags/SVG" class="mention hashtag" rel="tag">#<span>SVG</span></a> now.</p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115577813386037833"><span class="date"><time datetime="2025-11-19T12:37:54-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='24.23660' y2='73.69066' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='58.11857' y2='26.35494' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 12:37"class="small_clock" />&nbsp;2025-11-19 / 2025-W47-3T12:37:54-06:00 / 0x691e0e82</time></span></a></p></blockquote>
</div>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115594743817185583"><p>Any other <a href="https://hachyderm.io/tags/Jeopardy" class="mention hashtag" rel="tag">#<span>Jeopardy</span></a> fans out there?</p><p>WOW, Harrison Whitaker is a machine! The way he dominated Friday’s game was just amazing.</p><p>(I watch Jeopardy on Peacock so I have to wait a day longer than everyone else to watch episodes.)</p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115594743817185583"><span class="date"><time datetime="2025-11-22T12:23:32-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='71.93113' y2='77.27683' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='55.09816' y2='25.52535' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 12:23"class="small_clock" />&nbsp;2025-11-22 / 2025-W47-6T12:23:32-06:00 / 0x6921ffa4</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115635317361733851"><p>Made this <a href="https://hachyderm.io/tags/holiday" class="mention hashtag" rel="tag">#<span>holiday</span></a> (and <a href="https://hachyderm.io/tags/probability" class="mention hashtag" rel="tag">#<span>probability</span></a>) themed <a href="https://hachyderm.io/tags/JavaScript" class="mention hashtag" rel="tag">#<span>JavaScript</span></a> doohickey the other day. <a href="https://chrisphan.com/posts/2025-11-27_merry_christmas.html" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">chrisphan.com/posts/2025-11-27</span><span class="invisible">_merry_christmas.html</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115635317361733851"><span class="date"><time datetime="2025-11-29T16:21:55-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='76.21345' y2='73.19170' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='68.87966' y2='66.38775' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 4:21"class="small_clock" />&nbsp;2025-11-29 / 2025-W48-6T16:21:55-06:00 / 0x692b7203</time></span></a></p></blockquote>]]></content:encoded></item><item><title>Merry Christmas (probably)</title><link>https:://chrisphan.com/posts/2025-11-27_merry_christmas.html</link><description><![CDATA[ Now that we are (almost, in my time zone) past Thanksgiving, Christmas decorations are appropriate. I will be putting up a Christmas tree in my]]></description><guid>https:://chrisphan.com/posts/2025-11-27_merry_christmas.html</guid><pubDate>Thu, 27 Nov 2025 23:37:00 -0600</pubDate><content:encoded><![CDATA[
<p>Now that we are (almost, in my time zone) past Thanksgiving, Christmas
decorations are appropriate. I will be putting up a Christmas tree in my
physical home soon. Here (in my virtual home) is a probability-themed Christmas
Tree for your enjoyment:</p>
<p><svg viewBox="0 0 250 500" xmlns="http://www.w3.org/2000/svg"
id="mainSvg" style="width: 80vw; height: 80vh;" role="img"
aria-label="Neon green rectangles are arranged in a triangular pattern, with one rectangle in the first row, two in the second row, and so on, resembling a Christmas tree. Small bits of tinsel move down the tree, randomly moving left or right half of the width of a rectangle each time they move down a row. The rectangles with tinsel in them have bright backgrounds of changing colors, resembling Christmas lights. The rectangles quickly fade to a dark green upon becoming empty. Below the Christmas tree is a histogram of the horizontal positions of the tinsels when reaching the bottom of the tree. The bars of the histogram are brown, but each bar flashes white whenever a bit of tinsel falls into its range. Over time, the histogram takes the shape of a bell-shaped curve.">
<rect x="0" y="0" width="250" height="500" fill="black" stroke="none"
id="background_rect"/>
<g id="gates"></g>
<g id="snakes"></g>
<g id="bars"></g>
<g id="fullscreen_layer"></g>
<rect x="-1" y="-1" width="0" height="0" fill="none" stroke="none"
id="warning_rect_0" class="warning_rect" />
<text x="-1" y="-1" id="error_text" lengthAdjust="spacingAndGlyphs"/>
</text>
</svg></p>]]></content:encoded></item><item><title>Fun with Unix time</title><link>https:://chrisphan.com/posts/2025-11-21_fun_with_unix_time.html</link><description><![CDATA[ I think Unix time can be a lot of fun! If you don't know what Unix time is, it's the way a lot of computers]]></description><guid>https:://chrisphan.com/posts/2025-11-21_fun_with_unix_time.html</guid><pubDate>Fri, 21 Nov 2025 22:40:00 -0600</pubDate><content:encoded><![CDATA[
<div id="posttime">1763786400</div>
<p>I think Unix time can be a lot of fun!</p>
<p>If you don't know what Unix time is, it's the way a lot of computers (anything
running Unix or Linux, which includes modern Macs, iPads, iPhones, Android
devices, and so much more) keep track of time, which is by counting the number
of seconds since the start of the year 1970
<abbr title="Universal Coordinated Time">UTC</abbr>. The current Unix time is
<span id="currentUnixTime" class="date">supposed to be written here, but maybe
there's something wrong with the JavaScript</span>.</p>
<p>However, I prefer to write Unix times in hexadecimal (base-16). The current Unix
time in hexadecimal is <span id="currentUnixTimeHex" class="date">—this
page requires JavaScript, sorry</span>. (Numbers written in hex are written with
the letters <code>a</code> through <code>f</code> as well as the traditional decimal digits <code>0</code>
through <code>9</code>. Often times, hex numbers are prefixed with <code>0x</code> to distinguish them
from decimal numbers.)</p>
<p>By the way, my blog's current setup shows each post's time as Unix time
hexadecimal, as well as the ISO Gregorian and week-date formats.</p>
<h2>Some dates of note</h2>
<p>To get us started, here are some dates of note in Unix time. At the time I am
posting this, we have a ways to go until we need another hex digit (except we
might have more trouble before that—more about that later).</p>
<table id="table_5">
</table>
<h2>Division by powers of 4</h2>
<p>Dividing by 16 (and rounding down) a number in hexadecimal is equivalent to
shifting all the digits one space to the right, similar to dividing by 10 when
working in decimal. However, because 16 is a perfect square, we can do a kind of
half-shift by dividing by four.</p>
<table id="table_0">
</table>
<h2>Rounding</h2>
<p>In this table, we round down and up to the nearest multiple of a power of 16.</p>
<table id="table_1">
</table>
<h2>Adding/subtracting powers of 4</h2>
<p>This is like changing one digit by 1 or 4.</p>
<table id="table_2">
</table>
<h2>Adding/subtracting multiples of <span id="add_amt">something</span></h2>
<p>Bascially, I'm changing the first digit here.</p>
<table id="table_3">
</table>
<h2>How long <span id="until">until</span> an epoch fail?</h2>
<table id="table_4">
</table>
<p>Okay, the sad truth is that older programs store the Unix time as a 32-bit
<em>signed</em> integer. Storing as a signed integer makes sense, as it allows dates
before 1970 to be stored. But storing as a 32-bit signed integer means that we
overflow into the negative a second after we hit <span
class="date">0x7ffffff</span>. This is called <a href="https://en.wikipedia.org/wiki/Year_2038_problem">the year 2038
problem</a>.</p>
<p>Fortunately, people tend to design things to store Unix time as a 64-bit integer
nowadays, which will last us roughly 300 billion years.</p>
<p>As of the writing of this page, about 12 years before the epochalypse, the
heading above reads &quot;How long until an epoch fail?&quot;
After <span class="date">2038-01-19 03:14:07</span> UTC, the word &quot;until&quot; will
be replaced with &quot;since&quot;, thanks to the magic of JavaScript.</p>]]></content:encoded></item><item><title>Pwn Checker</title><link>https:://chrisphan.com/posts/2025-11-19_pwn_checker.html</link><description><![CDATA[ I made a new thing: Pwn Checker , a TUI app to check whether a password appears in Pwned Passwords' database of breached passwords. Of]]></description><guid>https:://chrisphan.com/posts/2025-11-19_pwn_checker.html</guid><pubDate>Wed, 19 Nov 2025 12:06:00 -0600</pubDate><content:encoded><![CDATA[
<p>I made a new thing:
<a href="https://codeberg.org/christopherphan/pwn_checker">Pwn Checker</a>, a <a
href="https://en.wikipedia.org/wiki/Text-based_user_interface"><abbr
title="text-based user interface">TUI</abbr></a> app to check whether a password
appears in <a href="https://haveibeenpwned.com/Passwords">Pwned Passwords'</a> database of
breached passwords.</p>
<figure>
<img src="/2025-W47/secret_compromised.png" width="835" height="485" alt="A screen shot of a TUI app. A password has been typed in, and its hash is shown. The program reports that this password appears in the database over two million times." />
<figcaption>
You type a password into the app, and it queries the Pwned Passwords service for
you.
</figcaption>
</figure>
<p>Of course, most people would be justifiably reluctant to send their passwords to
a third party. However, that is now how the Pwned Passwords service works.
Rather than sending your password over the Internet, you first compute <a href="https://en.wikipedia.org/wiki/SHA-1">the
SHA1 hash</a> (a kind of digital fingerprint)
of your password and then send <em>only the first five hex digits</em> of that hash to
the API. The API then replies with all hashes in the database that have those
same first five hex digits.</p>
<figure>
<img src="/2025-W47/diagram.svg" width="800" height="800" alt="A diagram that illustrates the steps in the caption below." />
<figcaption>The user types in their password (in this case, <code>secret</code>)
into their computer running the Pwn Checker app. The program calculates the SHA1
hash of the password, and then sends the first five of 40 hex digits of the hash
to the Pwned Passwords API. The API responds with a list of every hash in the
database with the same five initial digits, as well as the number of times the
corresponding password appears in the database. The program then checks the
returned hashes and determines whether the password was stolen.</figcaption>
</figure>
<p>I wrote Pwn Checker in Python, using <a href="https://textual.textualize.io/">Textual</a>,
a cool package for making TUI apps. <a href="https://codeberg.org/christopherphan/pwn_checker/">Pwn Checker is now on
Codeberg</a>, and is offered
under the MIT license.</p>]]></content:encoded></item><item><title>Mastodon posts for 2025-W45</title><link>https:://chrisphan.com/posts/2025-11-10_mastodon_posts_2025-W45.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/posts/2025-11-10_mastodon_posts_2025-W45.html</guid><pubDate>Wed, 12 Nov 2025 08:45:00 -0600</pubDate><content:encoded><![CDATA[
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115503757505363518"><p>Spending my morning helping out with a <span class="h-card" translate="no"><a href="https://hachyderm.io/@thecarpentries" class="u-url mention">@<span>thecarpentries</span></a></span> workshop. It&#39;s a great organization that teaches people to use tools such as <a href="https://hachyderm.io/tags/Python" class="mention hashtag" rel="tag">#<span>Python</span></a>, <a href="https://hachyderm.io/tags/git" class="mention hashtag" rel="tag">#<span>git</span></a>, and the <a href="https://hachyderm.io/tags/Unix" class="mention hashtag" rel="tag">#<span>Unix</span></a> <a href="https://hachyderm.io/tags/shell" class="mention hashtag" rel="tag">#<span>shell</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115503757505363518"><span class="date"><time datetime="2025-11-06T10:44:31-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='15.04482' y2='51.77075' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='34.69744' y2='30.23053' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 10:44"class="small_clock" />&nbsp;2025-11-06 / 2025-W45-4T10:44:31-06:00 / 0x690cd06f</time></span></a></p></blockquote>
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115503873815105571"><p>Today in silly <a href="https://hachyderm.io/tags/python" class="mention hashtag" rel="tag">#<span>python</span></a> scripts</p><p><a href="https://hachyderm.io/tags/unicode" class="mention hashtag" rel="tag">#<span>unicode</span></a></p><div class="masto-image" id="div_115503873815105571_0_982_962_png"><img src="/masto_pics/115503873815105571_0.png" width="485" height="475" alt="Terminal screenshot. User entered command  bat ~/.config/misc_scripts/cool_text.py . In response, the computer displayed the source code for a Python script:  #!/usr/bin/env python3 import string import fileinput from typing import Final      Change text for stdin, replacing ASCII letters with corresponding outline letters.  Example: `$ cat example.txt | cool_text.py`      DIFFERENCE: Final[int] = (     0x1CCD6  # codepoint for Outlined Latin Capital Letter A     - 0x41  # codepoint for 'A' )   def transform(x: str) -> str:        Transform all ASCII letters to the corresponding outlined letters.         if len(x) == 1:  # Transform of a single character         if x in string.ascii_uppercase:             return chr(ord(x) + DIFFERENCE)         elif x in string.ascii_lowercase:             return chr(ord(x.capitalize()) + DIFFERENCE)         else:             return x     else:  # Call this function for every character in x         return   .join(transform(c) for c in x)   if __name__ ==  __main__ :     try:         for line in fileinput.input():             print(transform(line), end=  )     except KeyboardInterrupt:  # Supress printing of traceback if user quits with ^C         pass " id="pic_115503873815105571_0"/></div><div class="masto-image" id="div_115503873815105571_1_986_826_png"><img src="/masto_pics/115503873815105571_1.png" width="524" height="439" alt="Terminal screenshot. User entered the command  cat shopping_list_2025-W45.md . In response, the computer outputted the contents of a Markdown-formatted shopping list:  # Shopping list for 2025-W45  * bread * almond milk * yogurt * fruit * carrots * mushrooms * beets * ground pork * bacon * mozzarella * ricotta * cheddar * vegetable oil * frozen spinach * garbanzo beans  Then the user entered the command  cat shopping_list_2025-W45.md | cool_text.py   The computer responded similarly as above, except that every letter was capitalized and shown using the outline letters from the Symbols for Legacy Computing Supplement Unicode block." id="pic_115503873815105571_1"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115503873815105571"><span class="date"><time datetime="2025-11-06T11:14:06-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='84.84467' y2='46.70621' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='40.25181' y2='26.97886' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:14"class="small_clock" />&nbsp;2025-11-06 / 2025-W45-4T11:14:06-06:00 / 0x690cd75e</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115503888618312666"><p>To be clear, I don&#39;t think you should actually post this kind of output anywhere, because of the potential problems it poses to screen readers. <a href="https://hachyderm.io/tags/a11y" class="mention hashtag" rel="tag">#<span>a11y</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115503888618312666"><span class="date"><time datetime="2025-11-06T11:17:52-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='83.43474' y2='60.34978' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='41.01365' y2='26.67093' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:17"class="small_clock" />&nbsp;2025-11-06 / 2025-W45-4T11:17:52-06:00 / 0x690cd840</time></span></a></p></blockquote>
</div>
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115511804514123617"><p>It&#39;s called trim in Rust. 🤷‍♂️ </p><p><a href="https://docs.python.org/3/library/stdtypes.html#str.strip" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">docs.python.org/3/library/stdt</span><span class="invisible">ypes.html#str.strip</span></a></p><p><a href="https://doc.rust-lang.org/std/primitive.str.html#method.trim" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">doc.rust-lang.org/std/primitiv</span><span class="invisible">e.str.html#method.trim</span></a></p><div class="masto-image" id="div_115511804514123617_0_1033_119_png"><img src="/masto_pics/115511804514123617_0.png" width="1033" height="119" alt="Terminal screenshot, Python traceback (I've omitted the line that is just carets underneath the previous line):  Traceback (most recent call last):   File  /Users/chris/Documents/projects/sandbox_3/unidecoder/category_dict/make_gc_dict.py , line 10, in <module>     code = parts[1].trim() AttributeError: 'str' object has no attribute 'trim'. Did you mean: 'strip'?" id="pic_115511804514123617_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115511804514123617"><span class="date"><time datetime="2025-11-07T20:50:59-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='21.64854' y2='29.47697' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='25.07735' y2='51.96510' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 8:50"class="small_clock" />&nbsp;2025-11-07 / 2025-W45-5T20:50:59-06:00 / 0x690eb013</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115515357515418600"><p>I assumed this was a conscious decision, since I imagine I am not the only person who gets trim/strip confused. But looking at the source code last night, I could not find an explicit reference to “trim” or “strip” in the suggestions code. Rather, I think it’s probably just a (really nice) coincidence, since they have the same three middle letters.</p><p><a href="https://hachyderm.io/tags/python" class="mention hashtag" rel="tag">#<span>python</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115515357515418600"><span class="date"><time datetime="2025-11-08T11:54:33-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='31.09159' y2='20.54712' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='48.81144' y2='25.02827' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:54"class="small_clock" />&nbsp;2025-11-08 / 2025-W45-6T11:54:33-06:00 / 0x690f83d9</time></span></a></p></blockquote>
</div>
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115514720313071544"><p>I’m going to learn how to ferment stuff this morning!</p><p><a href="https://www.bluff.coop/event/fermentation-class-101/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://www.</span><span class="ellipsis">bluff.coop/event/fermentation-</span><span class="invisible">class-101/</span></a></p><p>I’ve been trying to ferment food recently but have had mixed success. I successfully made some sauerkraut and pickled some celery, but my attempts with carrots or mung bean sprouts have ended up moldy.</p><p><a href="https://hachyderm.io/tags/WinonaMN" class="mention hashtag" rel="tag">#<span>WinonaMN</span></a> <a href="https://hachyderm.io/tags/food" class="mention hashtag" rel="tag">#<span>food</span></a> <a href="https://hachyderm.io/tags/cooking" class="mention hashtag" rel="tag">#<span>cooking</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115514720313071544"><span class="date"><time datetime="2025-11-08T09:12:30-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='83.80740' y2='40.94133' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='25.14859' y2='47.27833' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 9:12"class="small_clock" />&nbsp;2025-11-08 / 2025-W45-6T09:12:30-06:00 / 0x690f5dde</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115515330061064055"><p>With any luck, this will be a jar of <a href="https://hachyderm.io/tags/sauerkraut" class="mention hashtag" rel="tag">#<span>sauerkraut</span></a> in a little while!</p><p><a href="https://hachyderm.io/tags/WinonaMN" class="mention hashtag" rel="tag">#<span>WinonaMN</span></a> <a href="https://hachyderm.io/tags/food" class="mention hashtag" rel="tag">#<span>food</span></a></p><div class="masto-image" id="div_115515330061064055_0_2494_3325_jpeg"><img src="/masto_pics/115515330061064055_0.jpeg" width="416" height="554" alt="A glass canning jar stuffed with wet green cabbage. On top is a metal lid and rim. The jar sits on a wood table next to a lime green wall. A window sill can be seen in the background." id="pic_115515330061064055_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115515330061064055"><span class="date"><time datetime="2025-11-08T11:47:34-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='16.25666' y2='40.70554' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='47.29279' y2='25.14701' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:47"class="small_clock" />&nbsp;2025-11-08 / 2025-W45-6T11:47:34-06:00 / 0x690f8236</time></span></a></p></blockquote>
</div>]]></content:encoded></item><item><title>Mastodon posts for 2025-W44</title><link>https:://chrisphan.com/posts/2025-11-06_mastodon_posts_2025-W44.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/posts/2025-11-06_mastodon_posts_2025-W44.html</guid><pubDate>Thu, 6 Nov 2025 13:00:00 -0600</pubDate><content:encoded><![CDATA[
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115472440855437737"><p>I agree with <span class="h-card" translate="no"><a href="https://mstdn.social/@emilydoesastro" class="u-url mention">@<span>emilydoesastro</span></a></span> : uv is really awesome for <a href="https://hachyderm.io/tags/python" class="mention hashtag" rel="tag">#<span>python</span></a> environment and package management. I have been using it a lot recently.</p><p><a href="https://emily.space/posts/251023-uv" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">emily.space/posts/251023-uv</span><span class="invisible"></span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115472440855437737"><span class="date"><time datetime="2025-10-31T23:00:17-05:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='51.03832' y2='15.01540' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='37.55357' y2='28.31852' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:00"class="small_clock" />&nbsp;2025-10-31 / 2025-W44-5T23:00:17-05:00 / 0x690585d1</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115472464475699837"><p><span class="h-card" translate="no"><a href="https://mstdn.social/@emilydoesastro" class="u-url mention">@<span>emilydoesastro</span></a></span> One neat thing that uv allows is for you to make standalone scripts that specify the external packages needed. </p><p><a href="https://docs.astral.sh/uv/guides/scripts/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="ellipsis">docs.astral.sh/uv/guides/scrip</span><span class="invisible">ts/</span></a></p><div class="masto-image" id="div_115472464475699837_0_669_453_png"><img src="/masto_pics/115472464475699837_0.png" width="583" height="395" alt="Screen shot of the start of a Python script:  file: build.py  #!/usr/bin/env -S uv run --script # # /// script # requires-python =  >=3.11  # dependencies = [ requests ,  psycopg[binary] ] # /// # # SPDX-License-Identifier: MIT    Build the U.S. Population Chains database.     from __future__ import annotations  __author__ =  Christopher L. Phan, Ph.D.  __copyright__ =  Copyright 2025, Christopher L. Phan, Ph.D.  __credits__ = {__author__} __date__ =  2025-10-29  __license__ =         Copyright 2025 Christopher L. Phan, Ph.D.  Screenshot cuts of there." id="pic_115472464475699837_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115472464475699837"><span class="date"><time datetime="2025-10-31T23:06:17-05:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='71.40345' y2='22.30718' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='38.70535' y2='27.69684' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:06"class="small_clock" />&nbsp;2025-10-31 / 2025-W44-5T23:06:17-05:00 / 0x69058739</time></span></a></p></blockquote>
</div>
<div class="masto-thread">
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115483968908095307"><p>Timestamp stored in microseconds, not seconds. Oops! 🤦🏽‍♂️ <a href="https://hachyderm.io/tags/python" class="mention hashtag" rel="tag">#<span>python</span></a></p><div class="masto-image" id="div_115483968908095307_0_1019_289_png"><img src="/masto_pics/115483968908095307_0.png" width="901" height="256" alt="Screenshot of terminal (I have removed some of the lines consisting of spaces, tildes, and carets that point to the exact position of the error in the source code):  Processed 29010 (90%) (641.74778 s) Saving the database import instructions to  import_to_maria_pop_chain_build_1762144120827454.sql... (641.76971) Traceback (most recent call last):   File  /Users/chris/Documents/projects/sandbox_3/pop_chains_reproducible/./build.py , line 1192, in <module>     timer, table = dump_pg(config, db, len(ident_list), timer)    File  /Users/chris/Documents/projects/sandbox_3/pop_chains_reproducible/./build.py , line 1172, in dump_pg     + f INSERT INTO db_info VALUES ('{db.creation.isoformat()}');     File  /Users/chris/Documents/projects/sandbox_3/pop_chains_reproducible/./build.py , line 572, in creation     return datetime.datetime.fromtimestamp(self.timestamp)  ValueError: year must be in 1..9999, not 55842094" id="pic_115483968908095307_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115483968908095307"><span class="date"><time datetime="2025-11-02T22:52:01-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='24.03085' y2='26.53507' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='36.02319' y2='29.27203' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 10:52"class="small_clock" />&nbsp;2025-11-02 / 2025-W44-7T22:52:01-06:00 / 0x690834f1</time></span></a></p></blockquote>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115483989566894300"><p>Let&#39;s hope they remove this limitation before the year 10000 🤣  <a href="https://hachyderm.io/tags/python" class="mention hashtag" rel="tag">#<span>python</span></a></p><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115483989566894300"><span class="date"><time datetime="2025-11-02T22:57:16-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='40.11805' y2='16.42401' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='36.98718' y2='28.65366' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 10:57"class="small_clock" />&nbsp;2025-11-02 / 2025-W44-7T22:57:16-06:00 / 0x6908362c</time></span></a></p></blockquote>
</div>
<blockquote class="masto-post" lang="en" cite="https://hachyderm.io/@chrisphan/115484198507829608"><p>Ten most populous Census-designated places in the USA. (Data from 2020 U.S. Census) <a href="https://hachyderm.io/tags/census" class="mention hashtag" rel="tag">#<span>census</span></a> <a href="https://hachyderm.io/tags/demographics" class="mention hashtag" rel="tag">#<span>demographics</span></a> <a href="https://hachyderm.io/tags/SQL" class="mention hashtag" rel="tag">#<span>SQL</span></a></p><div class="masto-image" id="div_115484198507829608_0_597_509_png"><img src="/masto_pics/115484198507829608_0.png" width="520" height="443" alt="Screenshot of terminal. User has entered this SQL statement:  SELECT place_name, state_name, population FROM places WHERE place_type = 'cdp' ORDER BY population DESC LIMIT 10;  The results are shown in a table. They are:  Urban Honolulu, Hawaii, population 350964 Arlington, Virginia, population 238643 Enterprise, Nevada, population 221831 Spring Valley, Nevada, population 215597 Sunrise Manor, Nevada, population 205618 Paradise, Nevada, population 191238 Metairie, Louisiana, population 143507 East Los Angeles, California, population 118786 Brandon, Florida, population 114626 The Woodlands, Texas, population 114436" id="pic_115484198507829608_0"/></div><p class="masto-poster-info">&mdash; <a href="https://hachyderm.io/@chrisphan">Chris Phan</a>, <span class="date"><a href="https://hachyderm.io/@chrisphan/115484198507829608"><span class="date"><time datetime="2025-11-02T23:50:25-06:00"><img src="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' ><g><circle cx='50' cy='50' r='40' style='stroke: white; stroke-width: 5; fill: black;'/><line x1='50' y1='50' x2='20.48130' y2='31.19451' style='stroke: white; stroke-width: 5;' /><line x1='50' y1='50' x2='47.91168' y2='25.08737' style='stroke: white; stroke-width: 5;' /></g></svg>" alt="An analog clock reading 11:50"class="small_clock" />&nbsp;2025-11-02 / 2025-W44-7T23:50:25-06:00 / 0x690842a1</time></span></a></p></blockquote>]]></content:encoded></item><item><title>44° North</title><link>https:://chrisphan.com/posts/2025-10-08_44_north_hotel.html</link><description><![CDATA[ There is a hotel being built along the Mississippi River in downtown Winona, Minnesota. It appears to be close to complete. When I saw the]]></description><guid>https:://chrisphan.com/posts/2025-10-08_44_north_hotel.html</guid><pubDate>Wed, 8 Oct 2025 23:15:00 -0500</pubDate><content:encoded><![CDATA[
<p>There is a hotel being built along the Mississippi River in downtown Winona,
Minnesota. It appears to be close to complete. When I saw the name, it reminded
me about
<a href="/posts/2025-07-15_same_latitude.html">Winona and Eugene being at the same
latitude</a>!</p>
<figure><img src="/44_north_small.jpg" alt="A five-story building with brick facade, with four floors of balonies. Near the center-top of the building a label reads 44° North. Below on the ground level is a sign reading Latitude Bar & Lounge. The building is nearly complete, at least the part of the exterior you can see,although a small bit of white housewrap is visible. The parking lot is still unpaved, and some construction materials and two portable toilets are in front of the building." width="1200" height="685" /><figcaption>The new Hotel 44&deg; North being completed in downtown Winona.</figcaption>]]></content:encoded></item><item><title>ISO week-date calendar terminal app</title><link>https:://chrisphan.com/posts/2025-08-30_iso_weekdate.html</link><description><![CDATA[ As I've stated before , I love the ISO week-date calendar . One indication is that (in its current incarnation), this site shows dates in]]></description><guid>https:://chrisphan.com/posts/2025-08-30_iso_weekdate.html</guid><pubDate>Sat, 30 Aug 2025 15:30:00 -0500</pubDate><content:encoded><![CDATA[
<p>As <a href="/posts/2024-12-30_happy_new_year.html">I've stated before</a>, I love the <a href="https://en.wikipedia.org/wiki/ISO_week_date">ISO
week-date calendar</a>. One indication
is that (in its current incarnation), this site shows dates in the ISO week-date
format as well as the Gregorian ISO 8601/<a href="https://www.rfc-editor.org/rfc/rfc3339">RFC
3339</a> format.</p>
<p>A few years ago, I wrote a simple Python script to produce ISO week-date
calendars from the command line:</p><div class="code_block"><pre class=""  id="block-28ed856d-fad6-496c-ad62-e235d96ac1ea"><code><code class="checker "><span style="color:#839496;">$ isocal --year 2021</span></code>
<code class="checker "><span style="color:#839496;"></span></code>
<code class="checker "><span style="color:#839496;"></span></code>
<code class="checker "><span style="color:#839496;">                                     2021                                      </span></code>
<code class="checker "><span style="color:#839496;">                            ISO week-date calendar                             </span></code>
<code class="checker "><span style="color:#839496;">Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   </span></code>
<code class="checker "><span style="color:#839496;">53 28 29 30 31│ 1  2  3   │18  3  4  5  6  7  8  9   │   ─────┘                 </span></code>
<code class="checker "><span style="color:#839496;">   ───────────┘           │19 10 11 12 13 14 15 16 M │36  6  7  8  9 10 11 12   </span></code>
<code class="checker "><span style="color:#839496;">01  4  5  6  7  8  9 10   │20 17 18 19 20 21 22 23   │37 13 14 15 16 17 18 19 S </span></code>
<code class="checker "><span style="color:#839496;">02 11 12 13 14 15 16 17 J │21 24 25 26 27 28 29 30   │38 20 21 22 23 24 25 26   </span></code>
<code class="checker "><span style="color:#839496;">03 18 19 20 21 22 23 24   │     ┌──────────────────  │              ┌─────────  </span></code>
<code class="checker "><span style="color:#839496;">04 25 26 27 28 29 30 31   │22 31│ 1  2  3  4  5  6   │39 27 28 29 30│ 1  2  3   </span></code>
<code class="checker "><span style="color:#839496;">   ─────────────────────  │   ──┘                    │   ───────────┘           </span></code>
<code class="checker "><span style="color:#839496;">05  1  2  3  4  5  6  7   │23  7  8  9 10 11 12 13   │40  4  5  6  7  8  9 10   </span></code>
<code class="checker "><span style="color:#839496;">06  8  9 10 11 12 13 14   │24 14 15 16 17 18 19 20 J │41 11 12 13 14 15 16 17 O </span></code>
<code class="checker "><span style="color:#839496;">07 15 16 17 18 19 20 21 F │25 21 22 23 24 25 26 27   │42 18 19 20 21 22 23 24   </span></code>
<code class="checker "><span style="color:#839496;">08 22 23 24 25 26 27 28   │           ┌────────────  │43 25 26 27 28 29 30 31   </span></code>
<code class="checker "><span style="color:#839496;">   ─────────────────────  │26 28 29 30│ 1  2  3  4   │   ─────────────────────  </span></code>
<code class="checker "><span style="color:#839496;">09  1  2  3  4  5  6  7   │   ────────┘              │44  1  2  3  4  5  6  7   </span></code>
<code class="checker "><span style="color:#839496;">10  8  9 10 11 12 13 14   │27  5  6  7  8  9 10 11   │45  8  9 10 11 12 13 14   </span></code>
<code class="checker "><span style="color:#839496;">11 15 16 17 18 19 20 21 M │28 12 13 14 15 16 17 18 J │46 15 16 17 18 19 20 21 N </span></code>
<code class="checker "><span style="color:#839496;">12 22 23 24 25 26 27 28   │29 19 20 21 22 23 24 25   │47 22 23 24 25 26 27 28   </span></code>
<code class="checker "><span style="color:#839496;">           ┌────────────  │                    ┌───  │        ┌───────────────  </span></code>
<code class="checker "><span style="color:#839496;">13 29 30 31│ 1  2  3  4   │30 26 27 28 29 30 31│ 1   │48 29 30│ 1  2  3  4  5   </span></code>
<code class="checker "><span style="color:#839496;">   ────────┘              │   ─────────────────┘     │   ─────┘                 </span></code>
<code class="checker "><span style="color:#839496;">14  5  6  7  8  9 10 11   │31  2  3  4  5  6  7  8   │49  6  7  8  9 10 11 12   </span></code>
<code class="checker "><span style="color:#839496;">15 12 13 14 15 16 17 18 A │32  9 10 11 12 13 14 15 A │50 13 14 15 16 17 18 19 D </span></code>
<code class="checker "><span style="color:#839496;">16 19 20 21 22 23 24 25   │33 16 17 18 19 20 21 22   │51 20 21 22 23 24 25 26   </span></code>
<code class="checker "><span style="color:#839496;">                 ┌──────  │34 23 24 25 26 27 28 29   │                 ┌──────  </span></code>
<code class="checker "><span style="color:#839496;">17 26 27 28 29 30│ 1  2   │        ┌───────────────  │52 27 28 29 30 31│ 1  2   </span></code>
<code class="checker "><span style="color:#839496;">   ──────────────┘        │35 30 31│ 1  2  3  4  5   │   ──────────────┘        </span></code>
<code class="checker "><span style="color:#839496;">Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su</span></code>
</code></pre></div>
<p>I had intended to release this under an open-source license, but never got
around to it. Well, today I updated the code and <a href="https://codeberg.org/christopherphan/iso-week-date-cal">posted it to
Codeberg</a>.</p>
<figure><img src="/iso_2025-W35-6.png" alt="Screen shot of this program being run in a terminal session. The output is a 2025 calendar in color with the ISO weeks indicated." width="1047" height="787" /><figcaption>The program can produce a color output.</figcaption></figure>]]></content:encoded></item><item><title>Producing booklets from the command line</title><link>https:://chrisphan.com/posts/2025-07-28_booklet.html</link><description><![CDATA[ I’m writing this mostly for my own future reference, but perhaps it will be useful to someone else. Today, I wanted to print out a]]></description><guid>https:://chrisphan.com/posts/2025-07-28_booklet.html</guid><pubDate>Mon, 28 Jul 2025 22:00:00 -0500</pubDate><content:encoded><![CDATA[
<p>I’m writing this mostly for my own future reference, but perhaps it will
be useful to someone else.</p>
<p>Today, I wanted to print out a PDF so that I could turn it into a booklet by
folding the pages in half and stapling in the middle. The pages need to be in a
different order. Suppose you have a PDF with \(n\) pages, numbered 0 through
\(n - 1\). Then the first sheet out of your printer should have pages
\(n - 1\) and 0 on one side, and pages 1 and \(n - 2\) on the other. The
next sheet should have pages \(n - 3\) and 2 on one side and pages 3 and
\(n - 4\) on the other, and so on.</p>
<p>At first, I considered manually rearranging the pages in the macOS Preview app.
But this would be time-consuming and I wanted to have a script I could use in
the future. I briefly considered writing my own program to achieve this, before
thinking to myself “This has to be a solved problem.”</p>
<p>Indeed, it was. After a few seconds using a search engine<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>, I found a <a href="https://iffybooks.net/wp-content/uploads/zines/Iffy_Books_pdfbook2_screen.pdf">some
instructions</a>
from a Philadelphia-based zine publisher named Iffy Books.
The guide points to the program <a href="https://github.com/jenom/pdfbook2"><code>pdfbook2</code></a>.
This program is included in many TeX distributions and was already on my
machine.</p>
<p>When you go to print your booklet, be sure to print double-sided with
<em>short</em>-edge binding.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>I tend to use the <a href="https://memory-alpha.fandom.com/wiki/DuckDuckGo">same search engine as alternate-timeline James
T. Kirk</a>. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>Same latitude</title><link>https:://chrisphan.com/posts/2025-07-15_same_latitude.html</link><description><![CDATA[ The community where I lived the longest is Sandy, Oregon , where I grew up. In second and third place are, respectively, Winona, Minnesota and]]></description><guid>https:://chrisphan.com/posts/2025-07-15_same_latitude.html</guid><pubDate>Tue, 15 Jul 2025 18:20:00 -0500</pubDate><content:encoded><![CDATA[
<p>The community where I lived the longest is <a href="https://traveloregon.com/places-to-go/sandy/">Sandy,
Oregon</a>, where I grew up. In
second and third place are, respectively, <a href="https://visitwinona.com/">Winona,
Minnesota</a> and <a href="https://www.eugenecascadescoast.org/eugene/">Eugene,
Oregon</a>. Winona is the town where I
have made my home, having moved here almost 13 years ago. I lived in Eugene for
nearly six years, between 2003 and 2009,
when I attended graduate school at the University of Oregon.</p>
<figure><img src="/2025-W29-2/map.svg" alt="Map of the contiguous United States, with Oregon and Minnesota highlighted. The locations of Eugene and Winona are marked with a dot, and their common line of lattitude is shown." width="600" height="400" /><figcaption>Eugene and Winona are both at the same latitude, just north of 44&deg; N. State boundary data from the U.S. Census Bureau&rsquo;s <a href="https://www.census.gov/geographies/mapping-files/time-series/geo/tiger-line-file.html">TIGER/Line shapefiles</a>. Great Lakes shoreline data from <a href="https://www.glerl.noaa.gov/pubs/tech_reports/glerl-016/dr-016.html">Great Lakes Environmental Research Laboratory</a></figcaption></figure>
<p>Winona and Eugene are very different places. Although both college towns, they
have significant differences in size, climate, and vibe. However, one eerie
similarity, which I did not notice until several years after moving to Winona,
is that they are essentially at the same latitude, just above 44°N.</p>
<figure><img src="/2025-W29-2/osm_0.png" alt="Two maps from OpenStreetMap. One is a low-resolution map of Eugene, Oregon. The other is a low-resolution map of Winona, Minnesota" width="800" height="231" /><figcaption>Maps of Eugene and Winona
centered at the same latitude. Maps provided by <a
href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>.</figcaption></figure>
<p>What I found even more surprising was that my (former) home in Winona (where I
lived from the summer of 2013 until late last year), and Fenton Hall (one of the
two buildings that house the University of Oregon’s math department) are
at the same latitude. That is to say, if you stood in my former front yard and
headed due west for several thousand kilometers, you would eventually find
yourself in front of Fenton Hall.</p>
<figure><img src="/2025-W29-2/fenton_house.jpg" alt="Two photographs: on the left is a brown university campus building with stairs in front and a sign that says Fenton Hall. There is a conifer tree in front. On the right is a two-story house with beige siding. The ground is covered in snow." width="900" height="303" /><figcaption>Left: Fenton Hall, University of Oregon, October 2005. Right: My former home in Winona, Minnesota. Both these buildings are at about 44.0457&deg;N latitude.</figcaption></figure>
<figure><img src="/2025-W29-2/osm_1.png" alt="Two maps from OpenStreetMap. One shows the University of Oregon campus. The other shows a residential neighborhood of Winona, Minnesota" width="800" height="231" /><figcaption>Maps of University of Oregon campus and my former Winona neighborhood,
centered at the same latitude. Maps provided by <a
href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>.</figcaption></figure>]]></content:encoded></item><item><title>System time before Unix epoch?</title><link>https:://chrisphan.com/posts/2025-04-21_system_time.html</link><description><![CDATA[ On what operating systems is it possible to set the system time before 1970? That's a question I had after reading this example from the]]></description><guid>https:://chrisphan.com/posts/2025-04-21_system_time.html</guid><pubDate>Mon, 21 Apr 2025 15:00:00 -0500</pubDate><content:encoded><![CDATA[
<p>On what operating systems is it possible to set the system time before 1970?</p>
<p>That's a question I had after reading <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2021&amp;gist=4ff985ad67dcb76f4af986f313896c2f">this
example</a>
from <a href="https://doc.rust-lang.org/std/time/constant.UNIX_EPOCH.html#examples">the Rust standard library
documentation</a>:</p><div class="code_block"><div class="code-header"><span class="filename">src/main.rs</span> <span class="code-lang">Rust</span></div><pre class=""  id="block-2e7f8f46-9744-446f-a965-ff62bed8281a"><code class="language-rust"><code class="code-elipsis" id="block-2e7f8f46-9744-446f-a965-ff62bed8281a-elipsis-start"></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">use </span><span style="color:#839496;">std::time::</span><span style="color:#657b83;">{</span><span style="color:#839496;">SystemTime, </span><span style="color:#cb4b16;">UNIX_EPOCH</span><span style="color:#657b83;">}</span><span style="color:#839496;">;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">match </span><span style="color:#839496;">SystemTime::now</span><span style="color:#657b83;">()</span><span style="color:#839496;">.</span><span style="color:#859900;">duration_since</span><span style="color:#657b83;">(</span><span style="color:#cb4b16;">UNIX_EPOCH</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">      </span><span style="color:#859900;">Ok</span><span style="color:#657b83;">(</span><span style="color:#839496;">n</span><span style="color:#657b83;">) </span><span style="color:#859900;">=&gt; println!</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">1970-01-01 00:00:00 UTC was </span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;"> seconds ago!</span><span style="color:#839496;">&quot;, n.</span><span style="color:#859900;">as_secs</span><span style="color:#657b83;">())</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">      </span><span style="color:#859900;">Err</span><span style="color:#657b83;">(</span><span style="color:#859900;">_</span><span style="color:#657b83;">) </span><span style="color:#859900;">=&gt; panic!</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">SystemTime before UNIX EPOCH!</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#657b83;">}</span></code>
<code class="code-elipsis" id="block-2e7f8f46-9744-446f-a965-ff62bed8281a-elipsis-end"></code>
</code></pre></div>
<p>Here's an explanation of what's going on:</p>
<ul>
<li>
<p><a href="https://doc.rust-lang.org/std/time/struct.SystemTime.html"><code>SystemTime</code></a> is a
<code>struct</code> that stores timestamp information.</p>
</li>
<li>
<p><a href="https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.now"><code>SystemTime::now()</code></a>
returns the current reading of your computer's clock as a <code>SystemTime</code>.</p>
</li>
<li>
<p>If \(x\) and \(y\) are <code>SystemTime</code>s, then
<a href="https://doc.rust-lang.org/std/time/struct.SystemTime.html#method.duration_since">\(y\)<code>.duration_since(</code>\(x\)<code>)</code></a>
returns a <code>Result&lt;Duration, SystemTimeError&gt;</code>:</p>
<ul>
<li>
<p>If \(y\) occurs at the same time or <em>after</em> \(x\), then <code>duration_since</code>
will return
<a href="https://doc.rust-lang.org/std/result/enum.Result.html#variant.Ok"><code>Ok(</code>\(n\)<code>)</code></a>,
where \(n\) is a
<a href="https://doc.rust-lang.org/std/time/struct.Duration.html"><code>Duration</code></a>
representing the amount of time between \(x\) and \(y\).</p>
</li>
<li>
<p>If \(y\) occurs <em>before</em> \(x\), then <code>duration_since</code> will return
<a href="https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err"><code>Err(</code>\(z\)<code>)</code></a>,
where \(z\) is a
<a href="https://doc.rust-lang.org/std/time/struct.SystemTimeError.html"><code>SystemTimeError</code></a>.</p>
</li>
</ul>
</li>
<li>
<p><a href="https://doc.rust-lang.org/std/time/constant.UNIX_EPOCH.html"><code>UNIX_EPOCH</code></a> is
a constant of type <code>SystemTime</code> that represents the <a href="https://en.wikipedia.org/wiki/Unix_time">Unix
epoch</a>, that is,
1970-01-01T00:00:00 UTC, the exact start of the year 1970 in Coordinated
Universal Time (which is roughly the same as Greenwich Mean Time).</p>
</li>
<li>
<p>So, <code>SystemTime::now().duration_since(UNIX_EPOCH)</code> returns either:</p>
<ul>
<li>
<p><code>Ok(</code>\(n\)<code>)</code>, where \(n\) is the duration between now and the Unix
epoch, if the system clock is set to the Unix epoch or afterwards, or</p>
</li>
<li>
<p><code>Err(</code>\(z\)<code>)</code>, where \(z\) is a <code>SystemTimeError</code>, if (for some bizarre
reason) the system clock is set to before the Unix epoch.</p>
</li>
</ul>
</li>
<li>
<p>If \(n\) is a <code>Duration</code>, then
<a href="https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs">\(n\)<code>.as_secs()</code></a>
will return the number of seconds in \(n\), rounded down to the nearest
integer.</p>
</li>
</ul>
<p>So the overall behavior of this code is:</p>
<ul>
<li>
<p>If the system clock is set to the Unix epoch or afterwards, output to the standard
output something like &quot;1970-01-01 00:00:00 UTC was 1745265600 seconds ago!&quot;</p>
</li>
<li>
<p>If the system clock is set before the Unix epoch (for some bizarre reason),
<a href="https://doc.rust-lang.org/std/macro.panic.html"><code>panic</code></a> (i.e., crash) with
the error message &quot;SystemTime before UNIX EPOCH!&quot;</p>
</li>
</ul>
<p>So, my question was, after reading this: On which operating systems is it
possible to set the system clock to before the Unix epoch?</p>
<p>The reason I asked is that on Unix and Unix-like systems (such as MacOS, iOS,
Android, Linux), the system time is actually represented internally as the
time since the Unix epoch—this is usually referred to as &quot;Unix time&quot;.
For example, this post is timestamped to 2025-04-21T15:00:00-05:00 (April 21,
2015 at 3:00 p.m., in a timezone five hours behind UTC, which in my case is
North America's Central Daylight Time), but that can also be represented in Unix
time as 1745265600 seconds (or, in hexadecimal, <code>0x6806a3c0</code> seconds, which my
blog is currently configured to display at the top of this post).</p>
<p>Now, Unix time is usually represented (in seconds<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>) as a <em>signed</em>
integer<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup>, making it possible to represent dates before 1970 (e.g., the
birthday of anyone currently aged 56 and higher). However, a number of systems
use the (reasonable) assumption that the <em>current date</em> is in 1970 or later.
See, for example, <a href="https://askubuntu.com/questions/1215322/why-cant-i-change-system-time-to-less-than-1970">this
question</a>
from someone who is trying (and failing) to set their computer to a date before 1970.</p>
<p>A hint to the answer to my question is in <a href="https://en.wikipedia.org/w/index.php?title=Epoch_(computing)&amp;oldid=1284704256#Notable_epoch_dates_in_computing">a
table</a>
on Wikipedia, which lists the epochs used by various operating systems and
computer languages. For example, modern Windows systems use the beginning of
the year 1601. I knew Windows used a different epoch, but I didn't realize it
was before 1970 until I read this table.</p>
<p>Still, it would be interesting to see which of these operating systems actually
allow the system time to be set that far in the past.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Leap seconds are ignored; if leap seconds were taken into account, it would
be impossible to precisely specify future dates in Unix time more than about
six months in advance. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>Early systems stored the Unix time as a signed <em>32-bit</em> integer, which can
represent the values between -2<sup>31</sup> and
2<sup>31</sup> - 1 (i.e., roughly ±2.1 billion), a timespan of roughly
±68 years from the Unix epoch. Unfortunately, this leads to the <a href="https://en.wikipedia.org/wiki/Year_2038_problem">Year
2038 problem</a> (the binary
cousin of the Year 2000 problem), in which the latest datetimes you can
represent are in January of 2038. <a href="https://en.wikipedia.org/w/index.php?title=Year_2038_problem&amp;oldid=1286280146">Quoth
Wikipedia</a>,</p>
<blockquote>
<p>Modern systems and software updates to legacy systems address this problem
by using signed 64-bit integers instead of 32-bit integers, which will
take 292 billion years to overflow—approximately 21 times the estimated
age of the universe.</p>
</blockquote>
<a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a>
</li>
</ol>
</section>]]></content:encoded></item><item><title>About me</title><link>https:://chrisphan.com/about_me/index.html</link><description><![CDATA[ A photo of me, a 44-year-old man, smiling. I'm wearing glasses and a hoodie and have a mustache. Behind me, you can see a small]]></description><guid>https:://chrisphan.com/about_me/index.html</guid><pubDate>Tue, 14 Jan 2025 18:30:00 -0600</pubDate><content:encoded><![CDATA[
<p><img src="/selfie_2025-W03-2.jpg" alt="A photo of me, a 44-year-old man, smiling. I'm wearing glasses and a hoodie and have a mustache. Behind me, you can see a small portion of a print of M.C. Escher's &quot;Moebius Strip II&quot;, as well as a metal cabinet with a bunch of pictures of my kids, some kids' artwork, and a magnet featuring the Minnesota state flag." /></p>
<ul>
<li>
<p>Mailing address: Chris Phan, PO Box 244, Winona MN 55987</p>
</li>
<li>
<p>I live in <a href="https://visitwinona.com">Winona, Minnesota</a>, a beautiful college
town on the Mississippi River, surrounded by bluffs, in southeastern
Minnesota.</p>
</li>
<li>
<p>I have two wonderful children.</p>
</li>
<li>
<p>I spent the first 28 years of my life living in Oregon. Then I spent short
amounts of time living in Illinois, Scotland, and Pennsylvania, before making
my home in Minnesota.</p>
</li>
<li>
<p>I have a Ph.D. in mathematics from the University of Oregon. For a while, I
was a full-time mathematics professor in a series of contingent academic jobs,
most recently at a state university. Then I spent six years as a stay-at-home
dad. Recently, I have been teaching part time. See <a href="/math/">my math page</a> for
information about my work in mathematics.</p>
<p>See also my <a href="/disclaimer/">disclaimer</a>.</p>
</li>
<li>
<p>I volunteer for the Minnesota Democratic-Farmer-Labor Party, including service
as a party officer. Again, see also my
<a href="/disclaimer/">disclaimer</a>.</p>
</li>
<li>
<p>Pronouns: he/him/his</p>
</li>
</ul>]]></content:encoded></item><item><title>Turbofish</title><link>https:://chrisphan.com/posts/2025-01-13_turbofish.html</link><description><![CDATA[ Today, I found this really cool site: The turbofish is a strange-looking piece of syntax in the Rust programming language . It takes the form]]></description><guid>https:://chrisphan.com/posts/2025-01-13_turbofish.html</guid><pubDate>Mon, 13 Jan 2025 16:00:00 -0600</pubDate><content:encoded><![CDATA[
<p>Today, I found this really cool site: <a href="https://turbo.fish"><code>turbo.fish</code></a></p>
<p>The turbofish is a strange-looking piece of syntax in the <a href="https://www.rust-lang.org">Rust programming
language</a>. It takes the form <code>::&lt;Foo&gt;</code>, and is used
to convey type information to the compiler. Consider line 559 of <a href="https://codeberg.org/christopherphan/rust_self_ssg/src/commit/8f2ed71fecb37cb4b2e7f8d10955bcdccc2127f1/src/code_highlight.rs#L557">the
following</a>
(taken from <a href="https://codeberg.org/christopherphan/rust_self_ssg">the program</a> I
currently use to produce this site):</p><div class="code_block"><div class="code-header"><span class="filename">src/code_highlight.rs</span> <span class="code-lang">Rust</span></div><pre class=""  id="block-5ca46bc4-272c-48c7-8d36-2682e7ed7c8d"><code class="language-rust"><code class="code-elipsis" id="block-5ca46bc4-272c-48c7-8d36-2682e7ed7c8d-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                </span><span style="color:#268bd2;">let</span><span style="color:#839496;"> lineno_start: Option&lt;</span><span style="color:#268bd2;">usize</span><span style="color:#839496;">&gt; </span><span style="color:#859900;">= match</span><span style="color:#839496;"> specs.</span><span style="color:#859900;">get</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">) {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                    </span><span style="color:#859900;">Some</span><span style="color:#657b83;">(</span><span style="color:#859900;">&amp;</span><span style="color:#839496;">&quot;&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">=&gt; None</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                    </span><span style="color:#859900;">Some</span><span style="color:#657b83;">(</span><span style="color:#839496;">w</span><span style="color:#657b83;">) </span><span style="color:#859900;">=&gt;</span><span style="color:#839496;"> w.parse::&lt;</span><span style="color:#268bd2;">usize</span><span style="color:#839496;">&gt;</span><span style="color:#657b83;">()</span><span style="color:#839496;">.</span><span style="color:#859900;">ok</span><span style="color:#657b83;">()</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                    </span><span style="color:#859900;">None =&gt; None</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                </span><span style="color:#657b83;">}</span><span style="color:#839496;">;</span></code>
<code class="code-elipsis" id="block-5ca46bc4-272c-48c7-8d36-2682e7ed7c8d-elipsis-end"></code>
</code></pre></div>
<p>The turbofish <code>::&lt;usize&gt;</code> on line 559 tells the compiler that we want to attempt
to parse the string slice <code>w</code> as a
<a href="https://doc.rust-lang.org/nightly/std/primitive.usize.html"><code>usize</code></a>
(pointer-sized unsigned integer).</p>
<p>I was aware of this terminology, but not its origin. As explained on the
<a href="https://turbo.fish/about"><code>turbo.fish</code> site</a>, it was the whimsical
coinage of a software developer named Anna Harren, who used it in a <a href="https://www.reddit.com/r/rust/comments/3fimgp/comment/ctozkd0/">Reddit
thread</a>. The
term caught on and now it's in official documentation and such. Alas, Harren
passed away in 2021, but in the Rust source code, in a file named
<code>bastion-of-the-turbofish.rs</code>, there remains <a href="https://github.com/rust-lang/rust/blob/7a202a9056ea19058a2a4b1b4f508f7f4ec3a0f6/tests/ui/parser/bastion-of-the-turbofish.rs#L32">a memorial to
Harren</a>.</p>]]></content:encoded></item><item><title>Happy ISO Week-Date New Year!</title><link>https:://chrisphan.com/posts/2024-12-30_happy_new_year.html</link><description><![CDATA[ Happy New Year! Of course, under the Gregorian calendar, the year doesn't start until Wednesday. But under the ISO week date calendar , today is]]></description><guid>https:://chrisphan.com/posts/2024-12-30_happy_new_year.html</guid><pubDate>Mon, 30 Dec 2024 14:20:00 -0600</pubDate><content:encoded><![CDATA[
<p>Happy New Year!</p>
<p>Of course, under the Gregorian calendar, the year doesn't start until Wednesday.
But under the <a href="https://en.wikipedia.org/wiki/ISO_week_date">ISO week date
calendar</a>, today is the first day
of 2025.</p>
<p>In our familiar Gregorian calendar, a year either has 365 or 366 days, split
into 12 months, each of which has between 28 and 31 days. In the ISO week date
calendar, a year is split into 52 or 53 weeks, each of which starts on Monday
and has seven days.</p>
<p>Today's date in the ISO week date calendar is 2025-W01-1, i.e., the first day
(Monday) of the first week of 2025.</p>
<p>Here are some other example dates in the ISO week date calendar:</p>
<table>
<thead>
<tr>
<th align="left">Typical American rendering</th>
<th align="left">ISO Gregorian</th>
<th align="left">ISO week date</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">Monday, December 30, 2024</td>
<td align="left">2024-12-30</td>
<td align="left">2025-W01-1</td>
</tr>
<tr>
<td align="left">Tuesday, December 29, 1998</td>
<td align="left">1998-12-29</td>
<td align="left">1998-W53-2</td>
</tr>
<tr>
<td align="left">Wednesday, October 21, 2015</td>
<td align="left">2015-10-21</td>
<td align="left">2015-W43-3</td>
</tr>
<tr>
<td align="left">Thursday, February 3, 1983</td>
<td align="left">1983-02-03</td>
<td align="left">1983-W05-4</td>
</tr>
<tr>
<td align="left">Friday, April 22, 2005</td>
<td align="left">2005-04-22</td>
<td align="left">2005-W16-5</td>
</tr>
<tr>
<td align="left">Saturday, July 11, 2020</td>
<td align="left">2020-07-11</td>
<td align="left">2020-W28-6</td>
</tr>
<tr>
<td align="left">Sunday, January 3, 2010</td>
<td align="left">2010-01-03</td>
<td align="left">2009-W53-7</td>
</tr>
</tbody>
</table>
<p>In the ISO week date calendar, every week (starting on Monday and ending on
Sunday) is in the same year. For most weeks, the entire week is in the same
Gregorian year, so it is assigned to that year in the ISO week date calendar.
However, any week containing both December 31 and January 1 (such as the current
week) will be split between two Gregorian years. These weeks are assigned to the
year with the most days in that week. For example, our current week has two days
in 2024 (Monday and Tuesday), and five days in 2025 (Wednesday through Sunday),
so in the ISO week date calendar, this is the first week of 2025. (Equivalently,
each week is assigned to the same ISO week date year as the Gregorian year of
its Thursday.)</p>
<p>Today is an example of a day whose ISO week date year is ahead of its Gregorian
year. On the other hand, on the table above, we see that January 3, 2010 is
assigned to 2009.</p>
<p>There are many ways to get the current ISO week date, or convert between
Gregorian and week date. For example, at any Unix or Unix-like shell, you can do
this:</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">date</span><span style="color:#839496;"> +</span><span style="color:#859900;">%</span><span style="color:#268bd2;">G</span><span style="color:#839496;">-W</span><span style="color:#859900;">%</span><span style="color:#268bd2;">V</span><span style="color:#839496;">-</span><span style="color:#859900;">%</span><span style="color:#268bd2;">u</span></code>
</code></pre></div><div class="repl_output">
<pre>
2025-W01-1
</pre>
</div></div></div>
<p>For most interfaces that understand <code>strptime</code>/<code>strftime</code> codes, like the
version of <code>date</code> on my Mac, <code>%G</code> is the ISO week date year, <code>%V</code> is the ISO
week date week, and <code>%u</code> is the day of the week. For example, in Python:</p><div class="code_block"><div class="code-header"><span class="code-lang">Python (REPL)</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#cb4b16;">from </span><span style="color:#839496;">datetime </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">date</span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#839496;">date.</span><span style="color:#b58900;">strftime</span><span style="color:#657b83;">(</span><span style="color:#839496;">date.</span><span style="color:#b58900;">today</span><span style="color:#657b83;">()</span><span style="color:#839496;">, &quot;</span><span style="color:#cb4b16;">%G</span><span style="color:#2aa198;">-W</span><span style="color:#cb4b16;">%V</span><span style="color:#2aa198;">-</span><span style="color:#cb4b16;">%u</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
'2025-W01-1'
</pre>
</div></div></div>
<p>Python's
<a href="https://docs.python.org/3/library/datetime.html#date-objects"><code>datetime.date</code></a>
objects have methods to convert between Gregorian and ISO week date:</p><div class="code_block"><div class="code-header"><span class="code-lang">Python (REPL)</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#cb4b16;">from </span><span style="color:#839496;">datetime </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">date</span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#b58900;">date</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">1983</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">2</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">3</span><span style="color:#657b83;">)</span><span style="color:#839496;">.</span><span style="color:#b58900;">isocalendar</span><span style="color:#657b83;">()</span></code>
</code></pre></div><div class="repl_output">
<pre>
datetime.IsoCalendarDate(year=1983, week=5, weekday=4)
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#839496;">date.</span><span style="color:#b58900;">fromisocalendar</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">2025</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">23</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">7</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
datetime.date(2025, 6, 8)
</pre>
</div></div></div>
<p>The Unix command <code>ncal</code> can be used to print a calendar with week numbers:</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">ncal</span><span style="color:#268bd2;"> -w</span><span style="color:#839496;"> 5 2025</span></code>
</code></pre></div><div class="repl_output">
<pre>
    May 2025
Mo     5 12 19 26
Tu     6 13 20 27
We     7 14 21 28
Th  1  8 15 22 29
Fr  2  9 16 23 30
Sa  3 10 17 24 31
Su  4 11 18 25
   18 19 20 21 22
</pre>
</div></div></div>
<p>And I wrote a Python program that prints nice year calendars with ISO week
numbers:</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">isocal</span><span style="color:#268bd2;"> -y</span><span style="color:#839496;"> 2025</span></code>
</code></pre></div><div class="repl_output">
<pre>

                                     2025
                            ISO week-date calendar
Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su
01 30 31│ 1  2  3  4  5   │   ────────┘              │37  8  9 10 11 12 13 14
   ─────┘                 │19  5  6  7  8  9 10 11   │38 15 16 17 18 19 20 21 S
02  6  7  8  9 10 11 12   │20 12 13 14 15 16 17 18 M │39 22 23 24 25 26 27 28
03 13 14 15 16 17 18 19 J │21 19 20 21 22 23 24 25   │        ┌───────────────
04 20 21 22 23 24 25 26   │                    ┌───  │40 29 30│ 1  2  3  4  5
                 ┌──────  │22 26 27 28 29 30 31│ 1   │   ─────┘
05 27 28 29 30 31│ 1  2   │   ─────────────────┘     │41  6  7  8  9 10 11 12
   ──────────────┘        │23  2  3  4  5  6  7  8   │42 13 14 15 16 17 18 19 O
06  3  4  5  6  7  8  9   │24  9 10 11 12 13 14 15 J │43 20 21 22 23 24 25 26
07 10 11 12 13 14 15 16 F │25 16 17 18 19 20 21 22   │                 ┌──────
08 17 18 19 20 21 22 23   │26 23 24 25 26 27 28 29   │44 27 28 29 30 31│ 1  2
                 ┌──────  │     ┌──────────────────  │   ──────────────┘
09 24 25 26 27 28│ 1  2   │27 30│ 1  2  3  4  5  6   │45  3  4  5  6  7  8  9
   ──────────────┘        │   ──┘                    │46 10 11 12 13 14 15 16 N
10  3  4  5  6  7  8  9   │28  7  8  9 10 11 12 13   │47 17 18 19 20 21 22 23
11 10 11 12 13 14 15 16 M │29 14 15 16 17 18 19 20 J │48 24 25 26 27 28 29 30
12 17 18 19 20 21 22 23   │30 21 22 23 24 25 26 27   │   ─────────────────────
13 24 25 26 27 28 29 30   │              ┌─────────  │49  1  2  3  4  5  6  7
     ┌──────────────────  │31 28 29 30 31│ 1  2  3   │50  8  9 10 11 12 13 14
14 31│ 1  2  3  4  5  6   │   ───────────┘           │51 15 16 17 18 19 20 21 D
   ──┘                    │32  4  5  6  7  8  9 10   │52 22 23 24 25 26 27 28
15  7  8  9 10 11 12 13   │33 11 12 13 14 15 16 17 A │           ┌────────────
16 14 15 16 17 18 19 20 A │34 18 19 20 21 22 23 24   │01 29 30 31│ 1  2  3  4
17 21 22 23 24 25 26 27   │35 25 26 27 28 29 30 31   │   ────────┘
           ┌────────────  │   ─────────────────────  │
18 28 29 30│ 1  2  3  4   │36  1  2  3  4  5  6  7   │
Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su   │Wk Mo Tu We Th Fr Sa Su
</pre>
</div></div></div>
<p>I really should release the source code for this.</p>
<p>Happy New Year!</p>]]></content:encoded></item><item><title>Some personal news</title><link>https:://chrisphan.com/posts/2024-09-08_some_personal_news/index.html</link><description><![CDATA[ This is probably only pertinent if you know me personally: about a month ago, my wife of over 13 years served me with a divorce]]></description><guid>https:://chrisphan.com/posts/2024-09-08_some_personal_news/index.html</guid><pubDate>Sun, 8 Sep 2024 14:35:00 -0500</pubDate><content:encoded><![CDATA[
<p>This is probably only pertinent if you know me personally: about a month ago, my
wife of over 13 years served me with a divorce petition. We are now going
through the legal process of dissolving our marriage.</p>]]></content:encoded></item><item><title>IMPORTANT message for MathJax users</title><link>https:://chrisphan.com/posts/2024-06-25_mathjax_polyfill_io_warning/index.html</link><description><![CDATA[ If you have ever used MathJax (an awesome tool that makes it easy to display mathematics on your website), you may have copied the following]]></description><guid>https:://chrisphan.com/posts/2024-06-25_mathjax_polyfill_io_warning/index.html</guid><pubDate>Tue, 25 Jun 2024 22:20:00 -0500</pubDate><content:encoded><![CDATA[
<p>If you have ever used <a href="https://www.mathjax.org/">MathJax</a> (an awesome tool that
makes it easy to display mathematics on your website), you may have copied
the following into your HTML, following the directions on their website:</p><div class="code_block"><div class="code-header"><span class="code-lang">HTML</span></div><pre class=""  id="block-259b129e-33e4-4ff9-b6d2-d1f51081fabc"><code class="language-html"><code class="checker "><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">script </span><span style="color:#b58900;">src</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">https://polyfill.io/v3/polyfill.min.js?features=es6</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;&lt;/</span><span style="color:#268bd2;">script</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker "><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">script </span><span style="color:#b58900;">id</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">MathJax-script</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">async src</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;&lt;/</span><span style="color:#268bd2;">script</span><span style="color:#586e75;">&gt;</span></code>
</code></pre></div>
<p>If you did that, <strong>you are going to want to delete that first line
immediately</strong>. This loads a piece of JavaScript from the domain <code>polyfill.io</code>,
and as <a href="https://simonwillison.net/2024/Jun/25/polyfill-supply-chain-attack/">Simon Willison put
it</a></p>
<blockquote>
<p>if you are loading assets from the <code>cdn.polyfill.io</code> domain you need to remove
that right now: the new owners of the domain (as of a few months ago) appear
to be using it to serve malicious JavaScript.</p>
</blockquote>
<p>(Yes, the code from the MathJax site loads <code>polyfill.min.js</code> from <code>polyfill.io</code>,
not <code>cdn.polyfill.io</code>, but the warning still applies.)</p>
<p>Willison further explains that the purpose of the <code>polyfill.io</code> service</p>
<blockquote>
<p>was to serve up a set of JavaScript polyfills - pieces of code that
implemented missing web platform features for older browsers - dynamically,
based on the incoming user-agent. This required a CDN that varied its output
dynamically based on the user-agent, hence the popularity of the single hosted
service.</p>
<p>Andrew Betts, the original author of the service, has been warning people to
move off it since February 20[2]4 [...]</p>
<p>He now works for Fastly, which started offering <a href="https://community.fastly.com/t/new-options-for-polyfill-io-users/2540">a free <code>polyfill-fastly.io</code>
alternative</a>
in February. Andrew says you probably don't need that either, given that
modern browsers have much better compatibility than when the
service was first introduced over a decade ago.</p>
</blockquote>
<p>I use MathJax a lot on this site, which allows me to show mathematical content
such as
\[\int_{-1}^1 \sqrt{1 - x^2}\; dx\]
or
\[\mu: V^{\otimes j} \otimes V^{\otimes k} \rightarrow V^{\otimes (k + j)}.\]</p>
<p>Every page with MathJax content on this site (and there are quite a few)
contained the two lines of HTML displayed at the start of this post. I removed
the first line (without specifying an alternative) and everything seems to be
working fine.</p>]]></content:encoded></item><item><title>Minnesota&apos;s new flag: from scratch</title><link>https:://chrisphan.com/posts/2024-04-28_minnesotas_new_flag/index.html</link><description><![CDATA[ A new flag Minnesota is soon getting a new state flag. In May 2023, the Minnesota Legislature passed, and the governor signed, HF 1830 ,]]></description><guid>https:://chrisphan.com/posts/2024-04-28_minnesotas_new_flag/index.html</guid><pubDate>Tue, 30 Apr 2024 12:40:00 -0500</pubDate><content:encoded><![CDATA[
<h2>A new flag</h2>
<p>Minnesota is soon getting a new state flag.</p>
<figure><img src="/2024-04-mn_flag/flag.svg" alt="New flag of Minnesota. The flag is divided into two parts. The right is water blue, and the left is night sky blue. The boundary between the two sides is a V-shape, pointing left. In the middle of the left portion is an eight-pointed star." width="500" height="300" /><figcaption>New design for Minnesota's flag, to be adopted 2024-05-11.</figcaption></figure>
<p>In May 2023, the Minnesota Legislature passed, and the governor signed, <a href="https://www.revisor.mn.gov/bills/bill.php?b=House&amp;f=HF1830&amp;ssn=0&amp;y=2023">HF
1830</a>,
a state government finance bill that also created a commission to redesign
Minnesota's state flag and state seal. <a href="https://commons.wikimedia.org/w/index.php?title=File:Flag_of_Minnesota.svg&amp;oldid=841553678">The previous flag
design</a>
uses the classic &quot;seal on a bedsheet&quot; arrangement decried by vexillologists.<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup>
Seals and flags have opposite purposes: seals are supposed to be complicated
while flags are supposed to be simple and recognizable from a distance.<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup></p>
<figure><img src="/2024-04-mn_flag/old_flag.svg" alt="Old flag of Minnesota. It's the state seal, which includes the word MINNESOTA, on a blue background."
width="500" height="300" /><figcaption>The previous flag design (Public Domain, from Wikipedia)</figcaption></figure>
<p>In the second half of 2023, the <a href="https://www3.mnhs.org/serc">State Emblems Redesign
Commission</a> invited members of the public to submit
proposed designs for Minnesota's new flag and seal. <a href="https://serc.mnhs.org/flags">Many designs were
proposed.</a> The winning proposal was <a href="https://www3.mnhs.org/serc-finalist-f1953">proposal
F1953</a>, designed and submitted by
<a href="https://www.mprnews.org/story/2023/11/28/minnesota-state-flag-redesign-finalists-luverne-designer">Andrew Prekker of Luverne,
Minnesota</a>.
The commission adopted a simplified version of Prekker's design this past
December. This design will be adopted on May 11, the 166th anniversary of
Minnesota statehood. The new design is <a href="https://www.mprnews.org/story/2023/12/19/new-minnesota-flag-final-design">thought to be one of the best in the
nation</a>.</p>
<p>In this post, I will explain how to implement the design of this flag as a short
manually-coded SVG file.</p>
<h2>The specifications</h2>
<p>The new flag as a very simple design, specified by the State Emblems Redesign
Commission in <a href="https://21588026.fs1.hubspotusercontent-na1.net/hubfs/21588026/State%20Emblems%20Redesign%20Commission/2023_SERC_Final_Report.pdf">its official
report</a>
(p. 21). You can make the flag out of three shapes:</p>
<figure>
<p><img src="/2024-04-mn_flag/specification.png" alt="diagram from the SERC report, showing the shapes described below" /></p>
<figcaption>Official specification from the State Emblems Redesign
Commission</figcaption>
</figure>
<ul>
<li>
<p>A water blue (<code>#52c9e8</code>) rectangle. Two sides of the rectangle have length
\(n\)
and the other two sides have length \(5n/3\).</p>
</li>
<li>
<p>A night sky blue (<code>#002d5d</code>) pentagon with three sides lying on the edges of
the rectangle: one side that is the entire edge of the rectangle with length
\(n\), and the two neighboring perpendicular sides that have a length of
\(14n/15\). The last two sides meet at a vertex halfway between the long edges of
the rectangle and a distance \(13n/20\) away from the opposite edge of the
pentagon.</p>
<figure><img src="/2024-04-mn_flag/rect_and_pent.svg" alt="The rectangle and pentagon shapes described above" width="600" height="400" /><figcaption>Specifications for the water blue and night blue portions of the flag.</figcaption></figure>
</li>
<li>
<p>A white eight-pointed star, which is a <a href="https://en.wikipedia.org/wiki/Octagram">regular
octogram</a>. The center of the star is
halfway between the long edges of the rectangle, and a distance of
\(21n/60\) from the short edge of the rectangle that is also an edge of the
pentagon. The points of the star are eight evenly spaced points along a circle
of radius \(11n/60\), with two points on a line perpendicular to the long sides
of the rectangle and two points on a line perpendicular to the short sides.
An outline of this polygon can be constructed by connecting each of these
eight points with the points three away.</p>
<figure><img src="/2024-04-mn_flag/star_lines.svg" alt="illustration of the star points" width="400" height="400" /><figcaption>the eight points of the star are equally spaced around the circle of radius \(11n/60\).</figcaption></figure>
<figure><img src="/2024-04-mn_flag/star_place.svg" alt="illustration of the star points" width="350" height="300" /><figcaption>The center of the star has a distance of \(21n/60\) from the left edge and is centered vertically.</figcaption></figure>
</li>
</ul>
<h2>Coding the flag</h2>
<p>We can use these descriptions to write our SVG file.</p>
<h3>Outside element</h3>
<p>We begin with the outside
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg"><code>svg</code></a>
element, which defines the viewport. Since the flag sits inside of a \(n \times
5n/3\) rectangle, we'll set \(n = 300\), so that the flag's dimensions are
500 × 300.</p>
<p>Typically, in computer graphics, the \(y\) coordinates increase as you go
<em>down</em>, which is the opposite of the convention used in mathematics.
So, our viewport's upper-left corner will be at \((0, 0)\),
and the lower right corner will be at \((500, 300)\). This is expressed in SVG
with the attribute <code>viewbox=&quot;0 0 500 300&quot;</code> in the <code>svg</code> element.</p><div class="code_block"><div class="code-header"><span class="filename">mn_flag.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-dd530674-1d05-414d-a253-f3dc48068a07"><code class="language-svg"><code class="checker lineno dig-0"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">svg </span><span style="color:#b58900;">viewbox</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0 0 500 300</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">xmlns</span><span style="color:#839496;">=&#39;</span><span style="color:#2aa198;">http://www.w3.org/2000/svg</span><span style="color:#839496;">&#39;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">svg</span><span style="color:#586e75;">&gt;</span></code>
</code></pre></div>
<h3>Water blue rectangle</h3>
<p>The next element to add is a water blue (<code>#52c9e8</code>) rectangle with the same
dimensions as the viewport. We'll use the
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect"><code>rect</code></a> element
for this. We insert the <code>rect</code> inside the <code>svg</code> element.</p><div class="code_block"><div class="code-header"><span class="filename">mn_flag.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-86e106c1-3308-4ea0-936b-29746f719835"><code class="language-svg"><code class="checker lineno dig-0"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">svg </span><span style="color:#b58900;">viewbox</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0 0 500 300</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">xmlns</span><span style="color:#839496;">=&#39;</span><span style="color:#2aa198;">http://www.w3.org/2000/svg</span><span style="color:#839496;">&#39;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">rect </span><span style="color:#b58900;">x</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">width</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">500</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">height</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">300</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">stroke</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">none</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">#52c9e8</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">svg</span><span style="color:#586e75;">&gt;</span></code>
</code></pre></div>
<h3>Night sky blue pentagon</h3>
<p>The next element to add is the night-sky blue (<code>#002d5d</code>) pentagon. For this,
we'll use the
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon"><code>polygon</code></a>
element.<sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup> Setting \(n
= 300\), we see that the points of the vertices of the pentagon are at the
following coordinates:
\[(0, 0), (280, 0), (195, 150), (280, 300), (0, 300).\]
So, we insert after the <code>rect</code>:</p><div class="code_block"><div class="code-header"><span class="filename">mn_flag.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-df251d56-64c3-4f9a-963d-3ba224fbb4c3"><code class="language-svg"><code class="code-elipsis" id="block-df251d56-64c3-4f9a-963d-3ba224fbb4c3-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">polygon </span><span style="color:#b58900;">points</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0,0 280,0 195,150 280,300 0,300</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#b58900;">stroke</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">none</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">#002d5d</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="code-elipsis" id="block-df251d56-64c3-4f9a-963d-3ba224fbb4c3-elipsis-end"></code>
</code></pre></div>
<h3>White star</h3>
<p>Last, and most tricky, is the eight-pointed star that goes inside the pentagon.
To get these points, we are going to use some trigonometry. If a circle has
radius \(r\) and center at the origin, then each point \(P\) on the circle
has the form
\[P = (r \cos \theta, r \sin \theta),\]
where \(\theta\) is the angle between the positive \(x\)-axis and the ray
starting at the center of the circle and passing through \(P\). For a circle
with arbitrary center \((h, k),\) we translate to get the parameterization
\[P = (h + r \cos \theta, k + r \sin \theta).\]</p>
<figure><img src="/2024-04-mn_flag/circle_point.svg" alt="diagram illustrating the above" width="500" height="400" /><figcaption>Parameterization of an arbitrary point on a circle</figcaption></figure>
<p>In our case, the points of the star sit on a circle with center \(105, 150)\) and
radius 55. There are eight points equally spaced around the circle, with two
points on the same horizontal line as the center, so the appropriate angles are
0°, 45°, 90°, 135°, and so on—or, in radians,
\(0, \pi/4, \pi/2, 3\pi/4, \dots\). However, we create the star by attaching
each point to a point three away, so the first point has an angle of \(0\),
the next an angle of \(3\pi/4\), the next an angle of \(3\pi/2\), etc.
Specifically, the \(j\)th point will have an angle of \(3j\pi/4\), and so
the \(j\)th point will have coordinates
\[(105 + 55 \cos(3j\pi/4), 150 + 55 \sin(3j\pi/4)).\]</p>
<p>We could compute these by hand (using knowledge of trigonometry and a decimal approximation for \(\sqrt{2}/2\)), but a short Python script is perfect for this.</p><div class="code_block"><div class="code-header"><span class="filename">star_points.py</span> <span class="code-lang">Python</span></div><pre class=""  id="block-03eda570-65e4-4b30-8a99-8c5663db5850"><code class="language-python"><code class="checker lineno dig-1"><span style="color:#586e75;">&quot;&quot;&quot;Calculate the points of the star on the Minnesota flag&quot;&quot;&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">math</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">center_x </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">105</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">center_y </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">150</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">r </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">55</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">theta </span><span style="color:#657b83;">= [</span><span style="color:#6c71c4;">3 </span><span style="color:#657b83;">* </span><span style="color:#839496;">k </span><span style="color:#657b83;">* </span><span style="color:#839496;">math.pi </span><span style="color:#657b83;">/ </span><span style="color:#6c71c4;">4 </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">9</span><span style="color:#657b83;">)]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">p </span><span style="color:#657b83;">= [(</span><span style="color:#839496;">center_x </span><span style="color:#657b83;">+ </span><span style="color:#839496;">r </span><span style="color:#657b83;">* </span><span style="color:#839496;">math.</span><span style="color:#b58900;">cos</span><span style="color:#657b83;">(</span><span style="color:#839496;">k</span><span style="color:#657b83;">)</span><span style="color:#839496;">, center_y </span><span style="color:#657b83;">+ </span><span style="color:#839496;">r </span><span style="color:#657b83;">* </span><span style="color:#839496;">math.</span><span style="color:#b58900;">sin</span><span style="color:#657b83;">(</span><span style="color:#839496;">k</span><span style="color:#657b83;">)) </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in </span><span style="color:#839496;">theta</span><span style="color:#657b83;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">for </span><span style="color:#839496;">pt </span><span style="color:#859900;">in </span><span style="color:#839496;">p</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">{</span><span style="color:#839496;">pt</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span><span style="color:#cb4b16;">:08.8f</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">,</span><span style="color:#657b83;">{</span><span style="color:#839496;">pt</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">1</span><span style="color:#268bd2;">]</span><span style="color:#cb4b16;">:08.8f</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div>
<p>We run this script to get the coordinates:</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">python3</span><span style="color:#839496;"> star_points.py</span></code>
</code></pre></div><div class="repl_output">
<pre>
160.00000000,150.00000000
66.10912703,188.89087297
105.00000000,95.00000000
143.89087297,188.89087297
50.00000000,150.00000000
143.89087297,111.10912703
105.00000000,205.00000000
66.10912703,111.10912703
160.00000000,150.00000000
</pre>
</div></div></div>
<p>Now, we use the
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline"><code>polyline</code></a>
SVG element, inserting the following after the pentagon in our SVG file:</p><div class="code_block"><div class="code-header"><span class="filename">mn_flag.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-10fad7a7-2435-4fe9-9f3c-536eec6d89e2"><code class="language-svg"><code class="code-elipsis" id="block-10fad7a7-2435-4fe9-9f3c-536eec6d89e2-elipsis-start"></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">polyline </span><span style="color:#b58900;">points</span><span style="color:#839496;">=&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    160.00000000,150.00000000</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    66.10912703,188.89087297</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    105.00000000,95.00000000</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    143.89087297,188.89087297</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    50.00000000,150.00000000</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    143.89087297,111.10912703</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    105.00000000,205.00000000</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    66.10912703,111.10912703</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    160.00000000,150.00000000</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#b58900;">stroke</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">none</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">white</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="code-elipsis" id="block-10fad7a7-2435-4fe9-9f3c-536eec6d89e2-elipsis-end"></code>
</code></pre></div>
<h2>Final result</h2>
<p>The final result is this short SVG file:</p><div class="code_block"><div class="code-header"><span class="filename">mn_flag.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-92c265cc-6380-4da8-93b2-028ce5011fa8"><code class="language-svg"><code class="checker lineno dig-1"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">svg </span><span style="color:#b58900;">viewbox</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0 0 500 300</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">xmlns</span><span style="color:#839496;">=&#39;</span><span style="color:#2aa198;">http://www.w3.org/2000/svg</span><span style="color:#839496;">&#39;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">rect </span><span style="color:#b58900;">x</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">y</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">width</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">500</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">height</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">300</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">stroke</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">none</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">#52c9e8</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">polygon </span><span style="color:#b58900;">points</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">0,0 280,0 195,150 280,300 0,300</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#b58900;">stroke</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">none</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">#002d5d</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">polyline </span><span style="color:#b58900;">points</span><span style="color:#839496;">=&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    160.00000000,150.00000000</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    66.10912703,188.89087297</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    105.00000000,95.00000000</span></code>
<code class="checker lineno dig-1"><span style="color:#2aa198;">    143.89087297,188.89087297</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    50.00000000,150.00000000</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    143.89087297,111.10912703</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    105.00000000,205.00000000</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    66.10912703,111.10912703</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">    160.00000000,150.00000000</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#b58900;">stroke</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">none</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">fill</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">white</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">svg</span><span style="color:#586e75;">&gt;</span></code>
</code></pre></div>
<p>And it looks like this:</p>
<img src="/2024-04-mn_flag/flag.svg" alt="New flag of Minnesota. The flag is divided into two parts. The right is water blue, and the left is night sky blue. The boundary between the two sides is a V-shape, pointing left. In the middle of the left portion is an eight-pointed star." width="500" height="300" />
<p>What a beautiful flag!</p>
<h2>Footnotes</h2>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>The seal in question was also considered distasteful by many for its
celebration of settler-colonialism, and so the same commission that
redesigned the flag also came up with a new seal. But even if the seal had
been perfectly fine, as the new seal is, putting your state seal on a flag
is a terrible flag design. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>The North American Vexillological Association has identified <a href="https://nava.org/good-flag-bad-flag">five principles of
flag design</a>, several of which the
old design clearly violates. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p>We could have used a <code>polygon</code> for the sky blue rectangle as well. <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>New look!</title><link>https:://chrisphan.com/posts/2024-04-25_new_look/index.html</link><description><![CDATA[ This site has a new look. Also, I'm using a new static site generator: a custom one I wrote for myself. I was inspired to]]></description><guid>https:://chrisphan.com/posts/2024-04-25_new_look/index.html</guid><pubDate>Thu, 25 Apr 2024 22:05:00 -0500</pubDate><content:encoded><![CDATA[
<p>This site has a new look.</p>
<p>Also, I'm using a new static site generator: a custom one I wrote for
myself. I was inspired to write my own SSG by
<a href="https://arne.me/blog/write-your-own-ssg">Arne Bahlo</a>. It was a nontrivial
amount of work.</p>]]></content:encoded></item><item><title>Note about tweets</title><link>https:://chrisphan.com/note_about_tweets/index.html</link><description><![CDATA[ Some of the posts here include reposts from the social media site previously known as Twitter, many from a now-deleted account of mine. I have]]></description><guid>https:://chrisphan.com/note_about_tweets/index.html</guid><pubDate>Thu, 25 Apr 2024 14:48:00 -0500</pubDate><content:encoded><![CDATA[
<p>Some of the posts here include reposts from the social media site previously
known as Twitter, many from a now-deleted account of mine. I have tried to
replace these with links to the <a href="https://web.archive.org">Wayback Machine</a>, when
the material in question is available there. Alas, in some cases the material is
not (in which case, I will link to this page).</p>]]></content:encoded></item><item><title>Happy π Day!</title><link>https:://chrisphan.com/posts/2024-03-14_happy_pi_day/index.html</link><description><![CDATA[ Check out my celebration of π Day, 2024 ! (Also available as a GitHub gist .)]]></description><guid>https:://chrisphan.com/posts/2024-03-14_happy_pi_day/index.html</guid><pubDate>Wed, 13 Mar 2024 23:20:00 -0500</pubDate><content:encoded><![CDATA[
<p>Check out my <a href="/pi_day_2024/">celebration of π Day, 2024</a>!</p>
<p>(Also available as a <a href="https://gist.github.com/christopherphan/6ebf27191c79ea5ff96b6016e5ab019e">GitHub
gist</a>.)</p>]]></content:encoded></item><item><title>PGP key</title><link>https:://chrisphan.com/pgp-key/index.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/pgp-key/index.html</guid><pubDate>Tue, 27 Feb 2024 13:26:00 -0600</pubDate><content:encoded><![CDATA[<div class="code_block"><pre class=""  id="block-75511565-8e70-4fbd-a78d-a888df1a0945"><code><code class="checker "><span style="color:#839496;">-----BEGIN PGP PUBLIC KEY BLOCK-----</span></code>
<code class="checker "><span style="color:#839496;">Comment: GPGTools - https://gpgtools.org</span></code>
<code class="checker "><span style="color:#839496;"></span></code>
<code class="checker "><span style="color:#839496;">mQINBFHgUTABEADMzdpCGHMaPlcrvdJenv9TYiGs/k2SqL2f+Fgm578RtgWq4gRi</span></code>
<code class="checker "><span style="color:#839496;">AgZkZWEzzkXiZFItdRazDwWLmuCcKC4OjPD+KVdwBeOJHZBJkUr90h+aR6LPX+0V</span></code>
<code class="checker "><span style="color:#839496;">45Wb6S4tERpEdInL9l4O10FtI3kUsUVAyQAlUibgwMfzkedJZm3Ogr0lUN+by/g8</span></code>
<code class="checker "><span style="color:#839496;">GPoKpZYgebKRriCCwcYJQba1XoU5zuqvK93ILx+YRk+6NS9uUY+GhUFYYswmm5XI</span></code>
<code class="checker "><span style="color:#839496;">0HmHiCCLf0md8k1RsVqEukBRRGWSaoch4eZvNIkxIZB1MC8qzfYcvQTE4/KsPLfJ</span></code>
<code class="checker "><span style="color:#839496;">Jc3GC8zAKfpCjZZCNyZv8KJYmRHojZRvZWTcUbwxv3ViQnF9skTqRLO0Dv30gXEO</span></code>
<code class="checker "><span style="color:#839496;">Jm6lvCPNv4v/biQUyBjD3bUwbWBt0VwjMBbOJK7gfG7GA/DhcdFKqU66UooQPlDx</span></code>
<code class="checker "><span style="color:#839496;">GhUKcgdiCrz7Jm7tH9S4j0LdkdAZaUBkUq1jCcOKxrHV2ng0GFywNG/KmTuA2e2P</span></code>
<code class="checker "><span style="color:#839496;">bajB5yNhruqWfwUkxW4Kd6g6SXBVZuPWuAXOpygOe19Ty6pifoDaWxF6jL//fYGl</span></code>
<code class="checker "><span style="color:#839496;">kiBBGkKcBvgr+VVzZS4b22DEPWAbLW+/IqEMT1OcBgqg7BfPn5tyVK2GCPR//iuj</span></code>
<code class="checker "><span style="color:#839496;">Jml31ZmwpggNL90VhhH0aJ/WjkdsA+VJlpmmyVUuZRI6hE0rrPEJx9HL0QARAQAB</span></code>
<code class="checker "><span style="color:#839496;">tCZDaHJpc3RvcGhlciBQaGFuIDxjcGhhbkBjaHJpc3BoYW4uY29tPokCQAQTAQoA</span></code>
<code class="checker "><span style="color:#839496;">KgIbLwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAIZAQUCZS1gwQUJFS5DEQAKCRA0</span></code>
<code class="checker "><span style="color:#839496;">0x/u/HOFnJoxEACnLQ4xxv8PH+TVrx5I0khF6Z19Xn3jVfHL0u202ApgmDIR9TG+</span></code>
<code class="checker "><span style="color:#839496;">iE04Axj0rDSqYdgeIWaY9DPE1kdne3P9El8yUU1NbEfwyz19KgBMfemB27CYJpuD</span></code>
<code class="checker "><span style="color:#839496;">x6e+e3NdZcSqgx0Ecr2lfSdtlKAkCAwu6NyQE63XcXaofzfeaTQlysHwd33NdtRS</span></code>
<code class="checker "><span style="color:#839496;">1ZGY2CNPOPhpzKt/jgm1Ko0dUlzjqNpbJb8koons6Gt2c+Zr+jU/tKCmxqA3bA6P</span></code>
<code class="checker "><span style="color:#839496;">/dXITL1nJnp7CLaQsvwEy1lMw7uo1bq4O/+8I7PRFIG04N/T185CVggtTFkTfTI+</span></code>
<code class="checker "><span style="color:#839496;">9FDduMq+AcdsNhANtbjjDh+VBsAh5kM0T4CD9DUp+EFG5BqVVyWPq8Q+khRHLakr</span></code>
<code class="checker "><span style="color:#839496;">O3qLYa2YuLEAOy9dEFc7cFkCuFUs3hYiGSGsUDcQ8RAZs4MH/G2GOvLWsr7GfwpC</span></code>
<code class="checker "><span style="color:#839496;">J3OBWxrV6MZ6CYoHggG4yTj9S1Zs5I0oT21JNl2yveBrYRZ37IASOVogTuJ14Nvu</span></code>
<code class="checker "><span style="color:#839496;">Jwq4Us6NHXqLFTBOdY8GIvrv7Nrjz9r50rfdhw6vfx93iL1gINS6lrNwLbguNYHW</span></code>
<code class="checker "><span style="color:#839496;">4szP8OD3QM+zvqUBgE1VYofynrT14fGAsrdiiJnRiRjmAOwob/jSLzAC2pX5pVzn</span></code>
<code class="checker "><span style="color:#839496;">FWV7N8xgEdZbzfICd5aAc634UY5nxg3G1ThbPeEchaBnrf4/SI8fak+uGIkCPQQT</span></code>
<code class="checker "><span style="color:#839496;">AQoAJwIbLwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAUCWWjd2gUJCWnAKgAKCRA0</span></code>
<code class="checker "><span style="color:#839496;">0x/u/HOFnNDjD/9o2OWhMOpweIl3Vgw13MMez/CWpjOjPAn6VpuAL8zLxQd2ztUj</span></code>
<code class="checker "><span style="color:#839496;">bvZiRCTKNF/scBru24FA/hTSWfbQon+7tQ5XZ8GYJ7iFZPWWcnGlH2zmni3so8g7</span></code>
<code class="checker "><span style="color:#839496;">C09KDlw0l8gI2fffyTG/XdJxHM7eQc2x6REJMmB2m0488K2VfvSiNc+oH6+y7rOu</span></code>
<code class="checker "><span style="color:#839496;">Ddd1sVRfO2AcFHUg/O4tSjerNakxQvSDBMskqA8fL8X938F0yPFb6Ua9WdfN8UMV</span></code>
<code class="checker "><span style="color:#839496;">Jd2GBRjMX5UopcpJzrVNeYq8BnCUCrOl5XjW153nQNllJeTCcolUSuTz+K4xCVp5</span></code>
<code class="checker "><span style="color:#839496;">G85t+N1xbA5+kx7clL0KbFMoTND0r2iFb8o4tmuVjYV1eIMKiP+hvA9Y+PjfIjpN</span></code>
<code class="checker "><span style="color:#839496;">Y2TcL2cvPmEdRObRrueGsPhWnPWHoNLFpQXfj0sss7EhNr+vQMYhVn5PDlTJjMVx</span></code>
<code class="checker "><span style="color:#839496;">C+4DZD8o3fT7m3SETPssd2qbPSxBPcHPoBgdX9CjF8R/u9WC1vikXJ9yBj5A40t/</span></code>
<code class="checker "><span style="color:#839496;">HM/nYO2IyAUkM5yNaP6Rjp6VHn1hcEMg8GpGLOyP8NEDjvZXUaDFWttT0/UHG4gE</span></code>
<code class="checker "><span style="color:#839496;">vorBXcUGeiVJSgY7OlpppcOzEDPl7MyljOCH6QTH/ob5FcU8q0Z5uZpBajt12ukw</span></code>
<code class="checker "><span style="color:#839496;">XJRDwLotW4YSzeVuTjCofJavWagnpJZDCkrHOGs3lbqwGGBkwBYU3G4utokCPQQT</span></code>
<code class="checker "><span style="color:#839496;">AQoAJwUCUeBRMAIbLwUJB4YfgAULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRA0</span></code>
<code class="checker "><span style="color:#839496;">0x/u/HOFnP2kD/4ilhaias/dhCVCEToMyN6Tw6begitThvGujOYY3VLaE3AD/ONX</span></code>
<code class="checker "><span style="color:#839496;">OJwsfjHUEl5QI9Q9nzJskCjUXvEoulVe8Q8XxZFlAp14J5h0XTm34oXRc4ZV1UAz</span></code>
<code class="checker "><span style="color:#839496;">2gjZVEUgfpmCaIz63UxZFNJ19nsqgIHm7OtfYlbQMQhsWDpbtcj64EC90LysvmLY</span></code>
<code class="checker "><span style="color:#839496;">Y+7HycgKEY704UTeZ+U5nCXhW76Fb0yKv5MuZyKcMMBsFIO6Yl8kTMjfHzssNQM2</span></code>
<code class="checker "><span style="color:#839496;">m0hp7wQEcuRT0Av+ZtVVgvWDO4h8PcThLVRFourCUD25RQADDa8Y37gLI00wKDX9</span></code>
<code class="checker "><span style="color:#839496;">Kufkk9Hf8LRjRKRCCCFQOcWx8gCEF5Vr1DgYsD2VTUJWvfo3c1q3leRuP2DWqp9z</span></code>
<code class="checker "><span style="color:#839496;">ICGDxUQ58uiHxoppWOcvZ5pJlEvNIWgoyIKHl82j6NJzYmKvCcAA/e0PRGpozeBr</span></code>
<code class="checker "><span style="color:#839496;">Sid2HrqAcTHF41xsTS0dYx+OI7N9ZqjNjTWPf64xvBUDaHvMpbnRUsm52HCNVcuF</span></code>
<code class="checker "><span style="color:#839496;">ePkN4uz1/fxggn2cze8Kletn5xbVMO60MZhl4g2xAE6/D02UzK3DpqG/rJb+F99O</span></code>
<code class="checker "><span style="color:#839496;">qovL4+Gge33xDCjvwVTeYWkZy0wq71MevuuEr6fbeJQ18QsjgrN7EtDGaco8MDaH</span></code>
<code class="checker "><span style="color:#839496;">dbMNJB5PzI3u/R6V9net+DTAZPEia4pw48JVtkd3qHqxGEMk2O6dPvS7GLQwQ2hy</span></code>
<code class="checker "><span style="color:#839496;">aXN0b3BoZXIgUGhhbiA8Y2hyaXMucGhhbi5wb2xpdGljc0BnbWFpbC5jb20+iQI9</span></code>
<code class="checker "><span style="color:#839496;">BBMBCgAnAhsvBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheABQJlLWDDBQkVLkMRAAoJ</span></code>
<code class="checker "><span style="color:#839496;">EDTTH+78c4WcFLsP/Ap8wPy6bDItgd4W2BBDL8FtAmf3wDw/giAOJ1uDgXFTbmoK</span></code>
<code class="checker "><span style="color:#839496;">whLYf2EPJCycyVmPbGr3KL75kZWPewHa8bs9ETramgJgFzqhCB0vxPd4HBiMKc28</span></code>
<code class="checker "><span style="color:#839496;">cBb6CuFLB4a+HJGMK7SKOqrDpuX1r4I8EC+aH8lGbw+BlypndgxNJALKUdQ6LwXF</span></code>
<code class="checker "><span style="color:#839496;">U+Df4v8ek5Iq0vAskgf8mwZmgTUmOb9iPThKWy1gO7Dw0+kdV/NsQgaaWcyKj3Z6</span></code>
<code class="checker "><span style="color:#839496;">OXmssO88emaTA/2UMQA9cj7N6sNk8nTIWZsO0/yzBXP0PSOc8K9sKeQJsKj0GmRs</span></code>
<code class="checker "><span style="color:#839496;">gmgwGhti+Av9W7KfkM75O/JAbScq7MChuL+JCxexrgzkjsdkLAsQ1vzUmq8cD3Li</span></code>
<code class="checker "><span style="color:#839496;">N/KNYSOCAoMI0nnQQKmw1szNIhyHQfmBU9lLMQDvHk5CEg/mR7Dkipb4kdvB+P8G</span></code>
<code class="checker "><span style="color:#839496;">X053paKWr4rQBURmtMkvQl1DXExr4CM8PFrsoxZ8ZdQYWLLYhXBmMlvAQn2biWgl</span></code>
<code class="checker "><span style="color:#839496;">ea8ZiO03TUnC+mPu9oFFbjQDUQBZqaywCEQD3T99CkJjkptPtyHeTfyHt5HfvNVm</span></code>
<code class="checker "><span style="color:#839496;">QaQzSLr8kRFWur6icX+AHqTovZIC/gNY2xoq05LO2+4/pBE+3GT0eR5ONN2GXWWu</span></code>
<code class="checker "><span style="color:#839496;">SC44OpK7IVYF7PnoGwKsGeF/fo3YEKwVkCplH66UIAl/i/gvoF7mz/qr8QnttCdD</span></code>
<code class="checker "><span style="color:#839496;">aHJpc3RvcGhlciBQaGFuIDxjaHJpcy5waGFuQGdtYWlsLmNvbT6JAj0EEwEKACcC</span></code>
<code class="checker "><span style="color:#839496;">Gy8FCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAmUtYMMFCRUuQxEACgkQNNMf7vxz</span></code>
<code class="checker "><span style="color:#839496;">hZyV5A//X0liWgr7nG3VOKcLvVg9Q31ELDkWdbuP1WtS417U1xQnQRloV0C2z9pQ</span></code>
<code class="checker "><span style="color:#839496;">JMfXb/oPqKKqcOawld+hoZRHl1Wlj0ZqmU0va9MFyiKNBMenyY9ViVG0Mzc/eqf2</span></code>
<code class="checker "><span style="color:#839496;">1jdXLz1zVgBnTnN8oHS4dV4lEsYbhg0egZwns6noroDMVXDkUYQmK3deeWx3fp2z</span></code>
<code class="checker "><span style="color:#839496;">zwsHpwMvJSEvALaqJf8XB+yLsGj0JlvcS0QY3Nso/0lPIF5WQqLyO7cfkvlLQpZ6</span></code>
<code class="checker "><span style="color:#839496;">W4YvGLW0IDJ7O8rt3eDgQKFmvGqbRK0jzNE4N+j7sTMzKlUMXpOSpUMptfoapbK2</span></code>
<code class="checker "><span style="color:#839496;">hQHOwfzVDR0MuwmiEh3t2ZYFmdphCGlnr4b8Boaoto2igsStEbDA7eEhI3qvo7N0</span></code>
<code class="checker "><span style="color:#839496;">d+ca80io0J3dP9QKtJYQwV4t4ZUhZwybJawdfKbnTF/c90qwPkRxylh5Hb7bTJF8</span></code>
<code class="checker "><span style="color:#839496;">TsJrPr4MnuwGcPGd43K8d2SM45sUbe6+6L9C+DWky1Sp8XgP7YByOkzJK07vJI3j</span></code>
<code class="checker "><span style="color:#839496;">0pFeIXgEryEb6/lpMu0sqoO/iHlTldAj2NwzKVGMtPQHLEm0OYbBsk9HnlN2Z9Ee</span></code>
<code class="checker "><span style="color:#839496;">qAGhAwQ+l5AU++HpjjTta0hOXFzugy4UnarSuGVZcjrhuLpDNxPHU7B1mJwxpyTN</span></code>
<code class="checker "><span style="color:#839496;">KqlsPnERD9Jj49uBcZYsnuOmNa5Wno48wNm8o6t+Wi7hSyKRCFOJAj0EEwEKACcC</span></code>
<code class="checker "><span style="color:#839496;">Gy8FCwkIBwMFFQoJCAsFFgIDAQACHgECF4AFAllo3doFCQlpwCoACgkQNNMf7vxz</span></code>
<code class="checker "><span style="color:#839496;">hZyinQ//cCzZRxtnjBkHrsW2dPjhK1oUNXohhZCaoRscRL8tGQ2nM/UpT814H0Qd</span></code>
<code class="checker "><span style="color:#839496;">CDrraldFvnez2EIwAHR0InhhZdBoFlIw2r0AWzMYl5cH0wuy8BGkKndhQ+9dHf+S</span></code>
<code class="checker "><span style="color:#839496;">DzkfN0ClWE1ZMc+gukNYmxad9H83SprLX8Mr7ZHXPM73P0m10cVJ9xPjU+4JpB2D</span></code>
<code class="checker "><span style="color:#839496;">rfTsablaxqWXv0XqiEWEO7pGG7SyDBKjeCgjJ8S1dhusvzpnS1TUJzn7iJe2B1NT</span></code>
<code class="checker "><span style="color:#839496;">I0MA17a4X49nWiZMUtvl17O3B8TKlP7jPKy7wiH4SHqygWHT+JMbW0zKcYUwA2Ux</span></code>
<code class="checker "><span style="color:#839496;">TnDxieUeSWU6azmrD8lXtFe8dQmB8omXNyLr2xR+/5Brz9LOI0twZA+PeYn0u8Ky</span></code>
<code class="checker "><span style="color:#839496;">e94qpLuncZwV4l0/fwfZZOgswTzGDvPjxPcmJDHGm5Pawe8/EL5S+eZQsJQkVGqc</span></code>
<code class="checker "><span style="color:#839496;">zMhyXcIK50ygqnDELiFXUDu96TEtCtLrnrtPSdb9P+RYp/Ac86sf3wvT2dAz5+ga</span></code>
<code class="checker "><span style="color:#839496;">HNC4QSnq7r5JS/QwjEha8mjitISa0dlzSSbssJubFp39URYqX/Ye8C/pN7PIcxRw</span></code>
<code class="checker "><span style="color:#839496;">nWOCR6jIGN8xChLVO6F8ImgBhoiikJKO0CD6Ei5m85Tl76xT49VSH8m7H5JuKYM+</span></code>
<code class="checker "><span style="color:#839496;">ypJCJmdyzYP6f4RQ2ZLMhRggdfajHtX0ngGEJ2pMjiP9ja6Jf3WJAj0EEwEKACcF</span></code>
<code class="checker "><span style="color:#839496;">AlHhoJYCGy8FCQeGH4AFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQNNMf7vxz</span></code>
<code class="checker "><span style="color:#839496;">hZysAw//XL/gUJxPy1wIANdAWFIvDxoqGivQGkiGy32+yUVHxth8Xy2rVVSPHvbx</span></code>
<code class="checker "><span style="color:#839496;">/w92KNF8pi3MpOi7wfcsc7+A8mn+vt2wz61ihb+Hle4B77DK0HfsVuI585vfk+HF</span></code>
<code class="checker "><span style="color:#839496;">KRDea+RMk2vWLCkCjahrteWGgcMv8ykSQSHdtf+Q+MFuB4BLA7EAPuEj96XdACO+</span></code>
<code class="checker "><span style="color:#839496;">9hLSmJdDFk2skiepqaEyUhb/0BSMvU97oLGt9zilmRJY7/pWehb10u1IhW8lZRGu</span></code>
<code class="checker "><span style="color:#839496;">1zDaDM3Haw9fMZwDz+4KWXjwwDJ+reOWjL3P2UeOSvTQjRdc+hmGPGOS0FdlEmYB</span></code>
<code class="checker "><span style="color:#839496;">Jll4LMeQJa2wRsWepVxmNqolQrWnKH0ksAMCWk14Ctj3WQl4X39r9nbb5OEkyulU</span></code>
<code class="checker "><span style="color:#839496;">wNGN1yEASBj5SVXbNVQOr/IZZgJBv3bAFt7yiV+pPAtT3Z2Wi3pHRs6S6xNpOq29</span></code>
<code class="checker "><span style="color:#839496;">sqpi5ZlRAV8EvRguyLUeHd7ES7zdI7vTh8UYQLex7ubJY3jRVVLKqlZKxCe4Yl+S</span></code>
<code class="checker "><span style="color:#839496;">uaw6BdAcpur5pLy1zJwwaMifbS5afd1Fnt/4KDtP6VEKTf31iyrkHT69CkqQLbGs</span></code>
<code class="checker "><span style="color:#839496;">A6ykX32/WU8nF93qJQoG0uXCuAqEWtDCwgfqTYrzUKXYruFdiTEqiQNpi63npsnh</span></code>
<code class="checker "><span style="color:#839496;">CBydjDBJLOQsVfATJBusbUYQt5NS/fD1jge54rC0p+OQFmp3HZi5Ag0EUeBRMAEQ</span></code>
<code class="checker "><span style="color:#839496;">ALEVZjsJJyDfnlzgeBeGTXaEB78UUA0cCdAOphtQp/fzy9VsU1gfqtjErXiuWJCa</span></code>
<code class="checker "><span style="color:#839496;">7kkQZ/xv2YVL4By2enzO97PwGB92z908WdWP2SaKlSrCMO/ZNfT/P7hXoR2rY3+p</span></code>
<code class="checker "><span style="color:#839496;">N9ATmMD5SjEn2DZK9ElFAoVwCEC4wG47p+iI90as5sFclj2r2HelkwR7PTgnq8IN</span></code>
<code class="checker "><span style="color:#839496;">CRVl+qvXZUKcZneKQ0eNecHnszdT7APNGzJ/w3lGG+6IieD2kM3+IYqTqaHYkQEN</span></code>
<code class="checker "><span style="color:#839496;">Vj1Ny6grVYp60yovY5IHNa8QHxL+rRHfIn6SK4NfqmTdt4rMQYxmAfBOBbXZArhU</span></code>
<code class="checker "><span style="color:#839496;">AJ2RWgfiv4SKh8V5+Q1vU6yo+91G4VFoQ+8+dfF8TLCG27W9eKC/acRFeFRPaC8D</span></code>
<code class="checker "><span style="color:#839496;">adiDOCnUfRKUAvSKWb3ccsfwTf/3xZ8XsW9V9KMIxOkLuQGNsLygI3RHUa4xddpD</span></code>
<code class="checker "><span style="color:#839496;">9PmJAcBAax8sVLCJxWBPDqcOPKNtZ+StNKYbYoi29drwX9zHTdAewNUNaKOqzzne</span></code>
<code class="checker "><span style="color:#839496;">Fbk8rcIt+mXULBB5PkNzZ+npN0SoAAuZGR7D6ua0Av1IIXjDAmMtTnu6mfM8Usfx</span></code>
<code class="checker "><span style="color:#839496;">psdWWxSV2UPSLgSKch1rqQIESF+3yAN3XBZy6ehNN+mT0/GoWLehHoc90Xt2ktzf</span></code>
<code class="checker "><span style="color:#839496;">LKtdSeSShvG7tkDCx3DaOhP67VE3UsuKyKgNRnkS3fTFABEBAAGJBEQEGAEKAA8C</span></code>
<code class="checker "><span style="color:#839496;">Gy4FAmUtYO0FCRUuQz0CKcFdIAQZAQoABgUCUeBRMAAKCRClp2i9OXvTetp/D/0f</span></code>
<code class="checker "><span style="color:#839496;">BRIbDU7+X7bieYHShRlhxCqAZbHALNm52ug6LjpodYeKvpMzHjfH060oJ1KvUBEv</span></code>
<code class="checker "><span style="color:#839496;">+SntuldlNfOSZ1GSmAm7sixrGG+FoKnmuKq3rEVX8QqrBXP3bs67iUiFK+d3wdQQ</span></code>
<code class="checker "><span style="color:#839496;">ZM26WaDregroPLQ/yEHCbfwMhxR1ZFWmZaLVqzkQ4Svb2SN68QKdIaowWpfwkYEU</span></code>
<code class="checker "><span style="color:#839496;">MHngmDvsVz0bMPeehWBQIaOpNtqBluPFC/e5PP3cUsx4cxgL3FIpuVaUgfPII6zN</span></code>
<code class="checker "><span style="color:#839496;">3OpxJF1QSESTNA4MG4O+CSpiC+mRjVfwpn/QaxWypBj3OkWwZby+TeyP25W1s1TC</span></code>
<code class="checker "><span style="color:#839496;">+eajx9DKQyo40mezrKBbPP6DinioDJrjnMuDcYtPhN9T4K0pGYkOQI8gy15AwAGP</span></code>
<code class="checker "><span style="color:#839496;">ut40lIFu2I4P5Y3+ap3xi8kuAzHA/Yr7lYkQtIozkA3KmemBlNXR7tl3SzMw4JNk</span></code>
<code class="checker "><span style="color:#839496;">FsKWMY5F66/YjqQW7awJn60FmhBqllXjiMoscETnm1eVm03txzFiEvogj6zxFgav</span></code>
<code class="checker "><span style="color:#839496;">UkpYUFlyAYtp66yO5AvhW9fNjMFhEheG3rioLs9gHuepBrbul2CQmmDTBsmgvDXZ</span></code>
<code class="checker "><span style="color:#839496;">kBX9LJ2UhIpCkYGt+G0h572YEODxHQWYNjewNOKHuyUiu4DP7dJIEC66U9gtCrSp</span></code>
<code class="checker "><span style="color:#839496;">m7NdvXqxaw0gikPJWhtVYJWBt5zVXfZEfcoKy3jbuwkQNNMf7vxzhZzEzg/9EZuc</span></code>
<code class="checker "><span style="color:#839496;">hNLN99TGPE2S9m8ZxiHP66adkqSNVwmdHMlZJeZ8Ugm3dz8/grJ9sDD8Wy/Mdf3x</span></code>
<code class="checker "><span style="color:#839496;">vUvmXQILOBtANYoE4EpmrlGOUBTIppVAVys/rDfMavz8iTNeaFQVakfySp8i7Ndl</span></code>
<code class="checker "><span style="color:#839496;">ufoC4yK3zOPBST93x+80kyoefBZwVUOxT//BSZ37Ktb1EUNVxY9tG40KeOp2W9VD</span></code>
<code class="checker "><span style="color:#839496;">PUA/ubrxcYJ9pD2CvfaP/lVoEsu0zIuHf0VuFK66hPYscrIBFIqkIQcQ05pbRkkB</span></code>
<code class="checker "><span style="color:#839496;">ela+PyhXW5b4vhk+4BIJbY6k5LaMn7u0jXMtc6AFUWXxEKkpuJ8vOKA9aFpwznJl</span></code>
<code class="checker "><span style="color:#839496;">hnDtWP29nInz15gOR4K/k/00KG2iQy/il9XsUYXygpHeinpJ7iNSPY2PT6LVkV6N</span></code>
<code class="checker "><span style="color:#839496;">JlGoGHkhK3ALzPBlgL/N5yOA59m/on8LJNRrYAUwc+mnk8BZKmjMaOEVgeiZ0bjc</span></code>
<code class="checker "><span style="color:#839496;">6O0SbgLMNDIQzDsQKNRL0V81NGEzEqsOOTtlSvFkH/42BlIaMljcPa4kppAdDlBX</span></code>
<code class="checker "><span style="color:#839496;">ReyvB5p5hhbHMo9dwAlvv+RwE9IxvMAxN19T8/4Y/dbGSxJNQFYF/AyOeYzZfIrg</span></code>
<code class="checker "><span style="color:#839496;">T4kGNrJadrRm/fsl53paxwT7wKf+bWaWYTf6v98zlkebgoDwWY5QZ2yZ84IWErtq</span></code>
<code class="checker "><span style="color:#839496;">u38Wyj64kOWVX8F+KoQBs/s+5wQB/EhyN2b1Kus=</span></code>
<code class="checker "><span style="color:#839496;">=NMBc</span></code>
<code class="checker "><span style="color:#839496;">-----END PGP PUBLIC KEY BLOCK-----</span></code>
</code></pre></div>]]></content:encoded></item><item><title>Made a link page</title><link>https:://chrisphan.com/posts/2023-07-16_made_a_link_page/index.html</link><description><![CDATA[ I made a link page, to add as a link to social media, etc. Link page]]></description><guid>https:://chrisphan.com/posts/2023-07-16_made_a_link_page/index.html</guid><pubDate>Sun, 16 Jul 2023 14:12:00 -0500</pubDate><content:encoded><![CDATA[
<p>I made a link page, to add as a link to social media, etc.</p>
<ul>
<li><a href="https://chrisphan.com/link_page/">Link page</a></li>
</ul>]]></content:encoded></item><item><title>Color contrast checker</title><link>https:://chrisphan.com/posts/2023-07-15_color_contrast_checker/index.html</link><description><![CDATA[ Screenshot: A widget in which the user can enter as hex triplets (or using the system color-picker) two colors. The widget then shows the relative]]></description><guid>https:://chrisphan.com/posts/2023-07-15_color_contrast_checker/index.html</guid><pubDate>Sat, 15 Jul 2023 11:05:00 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/color_contrast_screenshots/screenshot_2023.png" alt="Screenshot: A widget in which the user can enter as hex triplets (or using the system color-picker) two colors. The widget then shows the relative luminance of each color as well as the contrast ratio and the WCAG 2.0 accessibility ratings for that contrast ratio" /></p>
<p><a href="/color_contrast">I made this color contrast checker.</a> You can specify colors either by entering
hex triplets (e.g. <code>#00ffdd</code>) or using your browser's built-in color-selecting
widget. It will compute the <a href="https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio">contrast
ratio</a> and determine if the
color contrast meets the WCAG 2.1 accessibility success criterion
<a href="https://www.w3.org/TR/WCAG21/#contrast-minimum">1.4.3</a> (AA) or
<a href="https://www.w3.org/TR/WCAG21/#contrast-enhanced">1.4.6</a> (AAA).</p>
<ul>
<li>
<p><a href="/color_contrast">Color contrast checker</a></p>
</li>
<li>
<p><a href="https://codeberg.org/christopherphan/color_contrast">Source code (Codeberg)</a>
(<a href="https://codeberg.org/christopherphan/color_contrast/src/branch/main/LICENSE.md">MIT License</a>)</p>
</li>
</ul>]]></content:encoded></item><item><title>Now on Hackyderm</title><link>https:://chrisphan.com/posts/2023-07-11_hackyderm/index.html</link><description><![CDATA[ I have an account on the Mastodon instance Hackyderm now!]]></description><guid>https:://chrisphan.com/posts/2023-07-11_hackyderm/index.html</guid><pubDate>Tue, 11 Jul 2023 21:30:00 -0500</pubDate><content:encoded><![CDATA[
<p>I have an account on the Mastodon instance
<a href="https://hachyderm.io/about">Hackyderm</a> now!</p>
<ul>
<li><a href="https://hachyderm.io/@chrisphan"><code>@chrisphan@hackyderm.io</code></a></li>
</ul>]]></content:encoded></item><item><title>Code to make treemap</title><link>https:://chrisphan.com/posts/2023-07-06_code_to_make_treemap/index.html</link><description><![CDATA[ Earlier this week I posted about this treemap I made. Treemap showing the population of every U.S. county or equivalent, with counties grouped by core-based]]></description><guid>https:://chrisphan.com/posts/2023-07-06_code_to_make_treemap/index.html</guid><pubDate>Thu, 6 Jul 2023 18:00:00 -0500</pubDate><content:encoded><![CDATA[
<p><a href="/posts/2023-07-04_this_is_america/">Earlier this week</a> I
posted about this treemap I made.</p>
<p><img src="/US_population_distribution/treemap.svg" alt="Treemap showing the population of every U.S. county or equivalent, with counties grouped by core-based statistical areas and combined statistical areas" /></p>
<p>(<a href="/US_population_distribution/">Interactive version</a>)</p>
<p>Today, I have placed the code to produce this treemap in <a href="https://codeberg.org/christopherphan/US_pop_dist_data">a Codeberg
repo</a>. It's not the most
beautiful code in the world. (If I were really ambitious, I'd turn it into a
proper library.)</p>]]></content:encoded></item><item><title>This is America</title><link>https:://chrisphan.com/posts/2023-07-04_this_is_america/index.html</link><description><![CDATA[ Treemap showing the population of every U.S. county or equivalent, with counties grouped by core-based statistical areas and combined statistical areas This is a treemap]]></description><guid>https:://chrisphan.com/posts/2023-07-04_this_is_america/index.html</guid><pubDate>Tue, 4 Jul 2023 23:54:00 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/US_population_distribution/treemap.svg" alt="Treemap showing the population of every U.S. county or equivalent, with counties grouped by core-based statistical areas and combined statistical areas" /></p>
<p>This is a treemap of every county (or county equivalent) in the United States,
where the area of each rectangle is proportional to the population of the
corresponding county.</p>
<p>Counties that are part of the same core-based statistical area are grouped
together. (These have a thicker green border.) Moreover, core-based statistical areas that belong to the same
combined statistical area are grouped together. (CSAs have an even-thicker red
border.)</p>
<p>For example, the red rectangle in the upper-left corner represents the New
York-Newark, NY-NJ-CT-PA CSA:</p>
<p><img src="/2023_07_04_explain.svg" alt="Explanation of the diagram" /></p>
<p>Check out the interactive version, where you can mouse over each rectangle and
get information about that county and any statistical area of which it is part.</p>
<ul>
<li><a href="/US_population_distribution/">Interactive version</a></li>
<li><a href="https://codeberg.org/christopherphan/US_population_distribution">Source code</a></li>
</ul>
<p>Later, I will post the code I used to make this treemap.</p>]]></content:encoded></item><item><title>Silly Decorator #2: @plus_one</title><link>https:://chrisphan.com/posts/2022-04-14_silly_decorator_2_plus_one/index.html</link><description><![CDATA[ It's like a off-by-one error on your wedding day. ( Source )]]></description><guid>https:://chrisphan.com/posts/2022-04-14_silly_decorator_2_plus_one/index.html</guid><pubDate>Thu, 14 Apr 2022 14:22:00 -0500</pubDate><content:encoded><![CDATA[
<p>It's like a off-by-one error on your wedding day.</p>
<!-- prettier-ignore-start --><div class="code_block"><div class="code-header"><span class="code-lang">Python (REPL)</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#cb4b16;">from </span><span style="color:#839496;">plusonedecorator </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">plus_one</span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#839496;">@</span><span style="color:#268bd2;">plus_one</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#859900;">def </span><span style="color:#b58900;">cost</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">quantity</span><span style="color:#839496;">: </span><span style="color:#859900;">int</span><span style="color:#839496;">, </span><span style="color:#268bd2;">marginal_cost</span><span style="color:#839496;">: </span><span style="color:#859900;">float</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; </span><span style="color:#859900;">float</span><span style="color:#657b83;">:</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;">    </span><span style="color:#586e75;">&quot;&quot;&quot;Compute the cost of production.&quot;&quot;&quot;</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;">    </span><span style="color:#859900;">return </span><span style="color:#839496;">quantity </span><span style="color:#657b83;">* </span><span style="color:#839496;">marginal_cost</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;"></span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#b58900;">cost</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">1000</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.25</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
251.0
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#839496;">@</span><span style="color:#268bd2;">plus_one</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#859900;">def </span><span style="color:#b58900;">invite</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">name</span><span style="color:#839496;">: </span><span style="color:#859900;">str</span><span style="color:#839496;">, </span><span style="color:#268bd2;">pronoun</span><span style="color:#839496;">: </span><span style="color:#859900;">str</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; </span><span style="color:#859900;">str</span><span style="color:#657b83;">:</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;">    </span><span style="color:#586e75;">&quot;&quot;&quot;Decide to invite someone to your wedding.&quot;&quot;&quot;</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;">    </span><span style="color:#859900;">return </span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Let&#39;s be sure to invite </span><span style="color:#657b83;">{</span><span style="color:#839496;">name</span><span style="color:#657b83;">}</span><span style="color:#2aa198;"> and </span><span style="color:#657b83;">{</span><span style="color:#839496;">pronoun</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">.</span><span style="color:#839496;">&quot;</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;"></span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#b58900;">invite</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Emilia</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">her</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
"Let's be sure to invite Emilia and her plus one."
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#b58900;">invite</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Maxwell</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">his</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
"Let's be sure to invite Maxwell and his plus one."
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#b58900;">invite</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Taylor</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">their</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div><div class="repl_output">
<pre>
"Let's be sure to invite Taylor and their plus one."
</pre>
</div></div></div>
<!-- prettier-ignore-end -->
<p>(<a href="https://github.com/christopherphan/silly-python-decorators/blob/main/plus_one/plusonedecorator.py">Source</a>)</p>]]></content:encoded></item><item><title>Silly Decorator #1: @a_hole</title><link>https:://chrisphan.com/posts/2022-03-23_silly_decorator_1_ahole_decorator/index.html</link><description><![CDATA[ I'm like a pâtissier, except I decorate functions instead of cakes, and I decorate with U+1F4A9 instead of frosting. ( Source )]]></description><guid>https:://chrisphan.com/posts/2022-03-23_silly_decorator_1_ahole_decorator/index.html</guid><pubDate>Wed, 23 Mar 2022 17:00:00 -0500</pubDate><content:encoded><![CDATA[
<blockquote>
<p>I'm like a pâtissier, except I decorate functions instead of cakes, and I
decorate with U+1F4A9 instead of frosting.</p>
</blockquote>
<!-- prettier-ignore-start --><div class="code_block"><div class="code-header"><span class="code-lang">Python (REPL)</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#cb4b16;">from </span><span style="color:#839496;">aholedecorator </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">a_hole</span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#839496;">@</span><span style="color:#268bd2;">a_hole</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#859900;">def </span><span style="color:#b58900;">hello</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">name</span><span style="color:#839496;">: </span><span style="color:#859900;">str </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">friend</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; </span><span style="color:#859900;">str</span><span style="color:#657b83;">:</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;">    </span><span style="color:#859900;">return </span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Hello </span><span style="color:#657b83;">{</span><span style="color:#839496;">name</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">, I hope you are well.</span><span style="color:#839496;">&quot;</span></code>
<code class="python_repl_repl_prompt_1"><span style="color:#839496;"></span></code>
<code class="python_repl_repl_prompt_0"><span style="color:#b58900;">hello</span><span style="color:#657b83;">()</span></code>
</code></pre></div><div class="repl_output">
<pre>
'Hello friend, I hope you are well.'
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-python"><code class="python_repl_repl_prompt_0"><span style="color:#b58900;">hello</span><span style="color:#657b83;">()</span></code>
</code></pre></div><div class="repl_output">
<pre>
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/chris/Documents/projects/gists/a_hole_decorator/aholedecorator.py", line 70, in new_func
    raise AHoleError(choice(_MESSAGES))
aholedecorator.AHoleError: I'm like a pâtissier, except I decorate functions
  instead of cakes, and I decorate with U+1F4A9 instead of frosting.
</pre>
</div></div></div>
<!-- prettier-ignore-end -->
<p>(<a href="https://github.com/christopherphan/silly-python-decorators/blob/main/a_hole/aholedecorator.py">Source</a>)</p>]]></content:encoded></item><item><title>Hexagonal snowflakes</title><link>https:://chrisphan.com/posts/2021-12-13-hexagonal-snowflakes/index.html</link><description><![CDATA[ A hexagonal piece of blue paper with various holes cut into it, resembling a snowflake. Remember back in elementary school, where you made paper snowflakes]]></description><guid>https:://chrisphan.com/posts/2021-12-13-hexagonal-snowflakes/index.html</guid><pubDate>Mon, 13 Dec 2021 23:54:00 -0600</pubDate><content:encoded><![CDATA[
<figure>
<p><img src="/2021-12-13-snowflakes/pic_07_small.jpeg" alt="A hexagonal piece of blue paper with various holes cut into it, resembling a snowflake." /></p>
<figcaption>A hexagonal paper snowflake</figcaption>
</figure>
<p>Remember back in elementary school, where you made paper snowflakes by folding a square
piece of paper into a small triangle and then cut notches into it? One thing that always
bothered me is that you end up with a square snowflake, whereas real snowflakes are
hexagonal. Recently, when I was doing craft projects with my daughter, I wondered if I
could come up with a way to make hexagonal snowflakes.</p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_00_small.jpeg" alt="A square piece of blue paper with various holes cut into it." /></p>
<figcaption>The classic square paper snowflake. Real snowflakes are hexagonal, not quadrilateral.</figcaption>
</figure>
<p>After some trial and error, here’s what I came up with. (I suspect that this construction
is already known, e.g., by people who have studied origami.)</p>
<p>In these diagrams, green lines represent the folds to make in that step, white lines
represent pre-existing creases, and purple lines represent the cuts to make in that step.</p>
<p>First, fold a piece of paper in half lengthwise.</p>
<p><img src="/2021-12-13-snowflakes/diag1.svg" alt="A sheet of US letter paper in portrait orientation with a green vertical line." /></p>
<p>Next, fold the paper in half lengthwise, again.</p>
<p><img src="/2021-12-13-snowflakes/diag2.svg" alt="The left half of a sheet of paper in portrait orientation, with a green vertical line." /></p>
<p>Unfold the paper. The paper should now be divided into four equal strips lengthwise. Fold
the paper in half widthwise.</p>
<p><img src="/2021-12-13-snowflakes/diag3.svg" alt="A sheet of paper in portrait with four vertical creases and a green horizontal line." /></p>
<p>Next, fold the paper in half again, along the first crease you made. Orient the resulting
twice-folded paper so that the folded edges are on the top and right, and the paper's
original edge are on the bottom and left.</p>
<p><img src="/2021-12-13-snowflakes/diag4.svg" alt="The bottom half of a sheet of paper in portrait orientation, with four vertical creases, the central of which is green." /></p>
<p>Now, fold over the top left corner, so that the resulting crease starts at the top-right
corner, and so the corner of the resulting fold touches the middle crease.</p>
<p><img src="/2021-12-13-snowflakes/diag5.svg" alt="The bottom-left quarter of a sheet of paper in portrait orientation, with a vertical crease and a green diagonal line from the left edge to the upper-right corner." />
<img src="/2021-12-13-snowflakes/diag5a.svg" alt="The sheet of paper in the last diagram, except that the top left portion of the paper is folded over, so that its corner touches the vertical crease." /></p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_01_small.jpeg" alt="A hand performs the fold just described." /></p>
<figcaption>The corner of the fold should touch the crease.</figcaption>
</figure>
<p>Flip the paper around and repeat the same move. Then unfold once, so that you have a
half-sheet with two corners down, as in the diagram. Note that it's important that the two
creases meet in the middle.</p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_02_small.jpeg" alt="A thumb and index finger push the flap down so that its fold aligns with the fold of the other flap." /></p>
<figcaption>When you fold the second flap, its top should line up with the top of the first flap.</figcaption>
</figure>
<p><img src="/2021-12-13-snowflakes/diag5b.svg" alt="The bottom half of a US letter size piece of paper in a portrait orientation, with four vertical creases, and the top two corners folded down so that the corner of each flap touches a vertical crease." /></p>
<p>Now, make two new folds. Each of these folds will go through the corner of the previous
folds, and the new crease should be perpendicular to the diagonal folded edge. Fold these
flaps back. You want the top edge of the flaps on the back to line up with the top
diagonal folded edge of the rest of the paper.</p>
<p><img src="/2021-12-13-snowflakes/diag6.svg" alt="The bottom half of a US letter size piece of paper in a portrait orientation, with four vertical creases, and the top two corners folded down so that the corner of each flap touches a vertical crease. Each half of the diagram has a diagonal green line perpendicular to the diagonal fold and running through the corner of each flap." /></p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_03_small.jpeg" alt="A thumb presses into the paper to make the described fold." /></p>
<figcaption>The fold should go through the corner of the flap.</figcaption>
</figure>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_04_small.jpeg" alt="A close-up photograph of the resulting fold. We see that the two sides of the fold line up. The author's index finger is holding the paper down." /></p>
<figcaption>The top edges of the two sides of the fold should line
up.</figcaption>
</figure>
<p>Now, make a crease between the two bottom corners of the flaps (parallel to the bottom
edge of the paper and perpendicular to the middle crease). Then cut along that crease.</p>
<p><img src="/2021-12-13-snowflakes/diag7.svg" alt="A convex pentagonal piece of paper. The pentagon has vertical symmetry. The shortest edge is the only horizontal edge. The longest edges are adjacent to the horizontal edge and each makes a 120-degree angle with the horizontal edge. The other two edges meet at the top of the pentagon at a 120-degree angle. There is a vertical crease from the top point to the horizontal edge at the bottom. There are also two pocket flaps running from the top corner to a point on the longest edge. There is a purple horizontal line running from the bottommost corner of the two flaps." /></p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_05_small.jpeg" alt="A photograph of the crease being made. The part folded in fit snugly." /></p>
<figcaption>When you make this crease, the part you fold down will fit
snugly.</figcaption>
</figure>
<p>Next cut along the creases formed by folding the two flaps back.</p>
<p>Unfold the two flaps. At this point, you should have the bottom half of a hexagon. (If you
unfolded completely, you would have a regular hexagon.) Fold the resulting shape into an
equilateral triangle, by making new folds from each bottom corner to the top of the middle
crease.</p>
<p><img src="/2021-12-13-snowflakes/diag8.svg" alt="The same piece of paper as in the diagram above, but this time with the paper beneath the purple line removed." /></p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_06_small.jpeg" alt="A hand down a piece of blue paper shaped like a regular hexagon, with various creases in it." /></p>
<figcaption>You don't need to unfold the entire paper at this point, but if you do, it will be a
regular hexagon&mdash;or at least a close approximation.</figcaption>
</figure>
<p><img src="/2021-12-13-snowflakes/diag9.svg" alt="A diagram showing the bottom half of a regular hexagon. There is a crease along the top edge of the bottom half, indicating that it has been folded over. There are five other creases coming out of the center of the top edge, in 30-degree increments. The second and fourth crease are green. There are four equally-spaced vertical creases from the top edge (one of which is one of the five previously-mentioned creases)." /></p>
<p>Fold the resulting triangle in half along the middle crease to make a right triangle. Cut
out notches from the sides and corners as desired.</p>
<p><img src="/2021-12-13-snowflakes/diag10.svg" alt="A diagram showing an equilateral triangle, with the bottom edge horizontal. There is a green vertical crease from the bottom edge to the top corner; this crease divides the triangle into two right triangles." />
<img src="/2021-12-13-snowflakes/diag11.svg" alt="A diagram showing a right triangle, made by folding an equilateral triangle in half. Several possible notches from the edge of the triangle are illustrated with purple line segments." /></p>
<p>Unfold and you will have a hexagonal snowflake!</p>
<p><img src="/2021-12-13-snowflakes/diag12.svg" alt="A diagram showing paper snowflake. The shape has symmetry along six axes, as well as six-fold rotational symmetry about its center. If cut along the six axes of symmetry, the resulting pieces would be the same as the previous diagram after the suggested notches were removed." /></p>
<figure>
<p><img src="/2021-12-13-snowflakes/pic_07_small.jpeg" alt="A hexagonal piece of blue paper with various polygon holes cut into it, and notches on the side. The paper has creases along 6 axes through its center, through the centers of each pair of opposing sides of the hexagon, and through each pair of opposite corners of the hexagon. The holes and notches cut out of the paper exhibit reflectional symmetry about each of the crease-axes." /></p>
<figcaption>I'm sure some chemist will come along shortly and point out how my snowflake is still unrealistic. 🤣</figcaption>
</figure>]]></content:encoded></item><item><title>mypy sum error</title><link>https:://chrisphan.com/posts/2021-10-28-mypy-sum-error/index.html</link><description><![CDATA[ Recently, I've been exploring the type hints functionality in Python. The other day, I ran across what I think is a bug (already known) in]]></description><guid>https:://chrisphan.com/posts/2021-10-28-mypy-sum-error/index.html</guid><pubDate>Thu, 28 Oct 2021 17:40:00 -0500</pubDate><content:encoded><![CDATA[
<p>Recently, I've been exploring the <a href="https://docs.python.org/3/library/typing.html">type
hints</a> functionality in Python.
The other day, I ran across what I <em>think</em> is a bug (already known) in
<a href="http://mypy-lang.org">mypy</a>.</p>
<p>Here is a minimal working example of the issue I came across:</p>
<!-- prettier-ignore-start --><div class="code_block"><div class="code-header"><span class="filename">example.py</span> <span class="code-lang">Python</span></div><pre class=""  id="block-7d8c6f06-139b-4dcb-93b0-53689f531a07"><code class="language-python"><code class="checker lineno dig-0"><span style="color:#cb4b16;">from </span><span style="color:#839496;">fractions </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">Fraction</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">my_value </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">1 </span><span style="color:#657b83;">+ </span><span style="color:#859900;">sum</span><span style="color:#657b83;">([</span><span style="color:#b58900;">Fraction</span><span style="color:#657b83;">(</span><span style="color:#839496;">k </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">5 </span><span style="color:#657b83;">** </span><span style="color:#839496;">k</span><span style="color:#657b83;">) </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">)])</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">The result is </span><span style="color:#657b83;">{</span><span style="color:#839496;">my_value</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">.</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div>
<!-- prettier-ignore-end -->
<p>This program runs as you would expect.</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">python</span><span style="color:#839496;"> example.py</span></code>
</code></pre></div><div class="repl_output">
<pre>
The result is 64/25.
</pre>
</div></div></div>
<p>However, the type-check fails!</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">mypy</span><span style="color:#839496;"> example.py</span></code>
</code></pre></div><div class="repl_output">
<pre>
example.py:3: error: List comprehension has incompatible type List[Fraction]; expected List[int]
Found 1 error in 1 file (checked 1 source file)
</pre>
</div></div></div>
<p>At this point, I was really confused, but after searching for the error, I came across <a href="https://github.com/python/mypy/issues/8814">an
issue on GitHub that reported this</a>. In the
discussion, someone explained that the problem is that mypy isn't taking into account the
<a href="https://docs.python.org/3/reference/datamodel.html#object.__radd__"><code>__radd__</code></a> method.
(In general, <code>x + y</code> is shorthand for <code>x.__add__(y)</code>. However, if <code>x.__add__</code> doesn't know
how to deal with <code>y</code>, then Python tries to use <code>y.__radd__(x)</code> instead.)
Following the example in the discussion there, I modified the program as follows:</p>
<!-- prettier-ignore-start --><div class="code_block"><div class="code-header"><span class="filename">example.py</span> <span class="code-lang">Python</span></div><pre class=""  id="block-1f45d7fb-2249-410f-9103-f2f542b9ef3b"><code class="language-python"><code class="code-elipsis" id="block-1f45d7fb-2249-410f-9103-f2f542b9ef3b-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#839496;">my_value </span><span style="color:#657b83;">= </span><span style="color:#b58900;">Fraction</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">) + </span><span style="color:#859900;">sum</span><span style="color:#657b83;">([</span><span style="color:#b58900;">Fraction</span><span style="color:#657b83;">(</span><span style="color:#839496;">k </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">5 </span><span style="color:#657b83;">** </span><span style="color:#839496;">k</span><span style="color:#657b83;">) </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">)])</span></code>
<code class="code-elipsis" id="block-1f45d7fb-2249-410f-9103-f2f542b9ef3b-elipsis-end"></code>
</code></pre></div>
<!-- prettier-ignore-end -->
<p>The modified version type-checked okay.</p>
<p>At this point, I decided to come up with what <a href="https://cas.uoregon.edu/directory/mathematics-emeritus/all/shelton">my doctoral
advisor</a>
would call a &quot;Toy Example&quot;:</p>
<!-- prettier-ignore-start --><div class="code_block"><div class="code-header"><span class="filename">example.py</span> <span class="code-lang">Python</span></div><pre class=""  id="block-56923149-10af-435e-9d4a-41ced9addcea"><code class="language-python"><code class="checker lineno dig-1"><span style="color:#cb4b16;">from </span><span style="color:#839496;">__future__ </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">annotations </span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># Allow self-referential type hints</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">from </span><span style="color:#839496;">typing </span><span style="color:#cb4b16;">import </span><span style="color:#839496;">Union</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">class </span><span style="color:#b58900;">A</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">def __init__</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">self</span><span style="color:#839496;">: A, </span><span style="color:#268bd2;">value</span><span style="color:#839496;">: </span><span style="color:#859900;">int</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; </span><span style="color:#b58900;">None</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#d33682;">self</span><span style="color:#839496;">.value </span><span style="color:#657b83;">= </span><span style="color:#839496;">value</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">def __repr__</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">self</span><span style="color:#839496;">: A</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; </span><span style="color:#859900;">str</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">return </span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">{</span><span style="color:#d33682;">self</span><span style="color:#839496;">.</span><span style="color:#859900;">__class__</span><span style="color:#839496;">.</span><span style="color:#859900;">__name__</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">(</span><span style="color:#657b83;">{</span><span style="color:#d33682;">self</span><span style="color:#839496;">.value</span><span style="color:#93a1a1;">!r</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">)</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">def __add__</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">self</span><span style="color:#839496;">: A, </span><span style="color:#268bd2;">other</span><span style="color:#839496;">: Union</span><span style="color:#268bd2;">[</span><span style="color:#839496;">A, </span><span style="color:#859900;">int</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; A</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Calling </span><span style="color:#657b83;">{</span><span style="color:#d33682;">self</span><span style="color:#93a1a1;">!r</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">.__add__(</span><span style="color:#657b83;">{</span><span style="color:#839496;">other</span><span style="color:#93a1a1;">!r</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">)</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if isinstance</span><span style="color:#657b83;">(</span><span style="color:#839496;">other, A</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#d33682;">self</span><span style="color:#839496;">.</span><span style="color:#859900;">__class__</span><span style="color:#657b83;">(</span><span style="color:#d33682;">self</span><span style="color:#839496;">.value </span><span style="color:#657b83;">+ </span><span style="color:#839496;">other.value</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">elif isinstance</span><span style="color:#657b83;">(</span><span style="color:#839496;">other, </span><span style="color:#859900;">int</span><span style="color:#657b83;">)</span><span style="color:#839496;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#d33682;">self</span><span style="color:#839496;">.</span><span style="color:#859900;">__class__</span><span style="color:#657b83;">(</span><span style="color:#d33682;">self</span><span style="color:#839496;">.value </span><span style="color:#657b83;">+ </span><span style="color:#839496;">other</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#b58900;">NotImplemented</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">def __radd__</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">self</span><span style="color:#839496;">: A, </span><span style="color:#268bd2;">other</span><span style="color:#839496;">: </span><span style="color:#859900;">int</span><span style="color:#657b83;">) </span><span style="color:#839496;">-&gt; A</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Calling </span><span style="color:#657b83;">{</span><span style="color:#d33682;">self</span><span style="color:#93a1a1;">!r</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">.__radd__(</span><span style="color:#657b83;">{</span><span style="color:#839496;">other</span><span style="color:#93a1a1;">!r</span><span style="color:#657b83;">}</span><span style="color:#2aa198;">)</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if isinstance</span><span style="color:#657b83;">(</span><span style="color:#839496;">other, </span><span style="color:#859900;">int</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#d33682;">self</span><span style="color:#839496;">.</span><span style="color:#859900;">__class__</span><span style="color:#657b83;">(</span><span style="color:#d33682;">self</span><span style="color:#839496;">.value </span><span style="color:#657b83;">+ </span><span style="color:#839496;">other</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#b58900;">NotImplemented</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">if __name__ </span><span style="color:#657b83;">== </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">__main__</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    values_to_sum </span><span style="color:#657b83;">= [</span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#839496;">k</span><span style="color:#657b83;">) </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">)]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #1: </span><span style="color:#657b83;">{</span><span style="color:#859900;">sum</span><span style="color:#657b83;">(</span><span style="color:#839496;">values_to_sum</span><span style="color:#657b83;">)</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #2: </span><span style="color:#657b83;">{</span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">) + </span><span style="color:#859900;">sum</span><span style="color:#657b83;">(</span><span style="color:#839496;">values_to_sum</span><span style="color:#657b83;">)</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #3: </span><span style="color:#657b83;">{</span><span style="color:#6c71c4;">5 </span><span style="color:#657b83;">+ </span><span style="color:#859900;">sum</span><span style="color:#657b83;">(</span><span style="color:#839496;">values_to_sum</span><span style="color:#657b83;">)</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #4: </span><span style="color:#657b83;">{</span><span style="color:#859900;">sum</span><span style="color:#657b83;">(</span><span style="color:#839496;">values_to_sum</span><span style="color:#657b83;">) + </span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">)</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #5: </span><span style="color:#657b83;">{</span><span style="color:#859900;">sum</span><span style="color:#657b83;">(</span><span style="color:#839496;">values_to_sum</span><span style="color:#657b83;">) + </span><span style="color:#6c71c4;">5</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #6: </span><span style="color:#657b83;">{</span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">) + </span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">)</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #7 </span><span style="color:#657b83;">{</span><span style="color:#6c71c4;">5 </span><span style="color:#657b83;">+ </span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">)</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">f</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Computation #8 </span><span style="color:#657b83;">{</span><span style="color:#b58900;">A</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">) + </span><span style="color:#6c71c4;">6</span><span style="color:#839496;">=</span><span style="color:#657b83;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
</code></pre></div>
<!-- prettier-ignore-end -->
<p>Then it executes just fine, but <code>mypy</code> is upset about line 33, in which
<code>A(10).__radd__(5)</code> is called. (In the output below, the <code>Calling ...</code> text is output
before the result of the computation.)</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">python3</span><span style="color:#839496;"> example.py</span></code>
</code></pre></div><div class="repl_output">
<pre>
Calling A(1).__radd__(0)
Calling A(1).__add__(A(2))
Calling A(3).__add__(A(3))
Calling A(6).__add__(A(4))
Computation #1: sum(values_to_sum)=A(10)
Calling A(1).__radd__(0)
Calling A(1).__add__(A(2))
Calling A(3).__add__(A(3))
Calling A(6).__add__(A(4))
Calling A(5).__add__(A(10))
Computation #2: A(5) + sum(values_to_sum)=A(15)
Calling A(1).__radd__(0)
Calling A(1).__add__(A(2))
Calling A(3).__add__(A(3))
Calling A(6).__add__(A(4))
Calling A(10).__radd__(5)
Computation #3: 5 + sum(values_to_sum)=A(15)
Calling A(1).__radd__(0)
Calling A(1).__add__(A(2))
Calling A(3).__add__(A(3))
Calling A(6).__add__(A(4))
Calling A(10).__add__(A(5))
Computation #4: sum(values_to_sum) + A(5)=A(15)
Calling A(1).__radd__(0)
Calling A(1).__add__(A(2))
Calling A(3).__add__(A(3))
Calling A(6).__add__(A(4))
Calling A(10).__add__(5)
Computation #5: sum(values_to_sum) + 5=A(15)
Calling A(5).__add__(A(6))
Computation #6: A(5) + A(6)=A(11)
Calling A(6).__radd__(5)
Computation #7 5 + A(6)=A(11)
Calling A(5).__add__(6)
Computation #8 A(5) + 6=A(11)
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">mypy</span><span style="color:#839496;"> example.py</span></code>
</code></pre></div><div class="repl_output">
<pre>
example.py:33: error: Argument 1 to "sum" has incompatible type "List[A]"; expected "Iterable[int]"
Found 1 error in 1 file (checked 1 source file)
</pre>
</div></div></div>
<p>If you remove line 33 in the script (the one that evaluates <code>5 + sum(values_to_sum)</code>),
then mypy has no problem!</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">mypy</span><span style="color:#839496;"> example.py</span></code>
</code></pre></div><div class="repl_output">
<pre>
Success: no issues found in 1 source file
</pre>
</div></div></div>
<p>Note that line 33 isn't the only place that <code>__radd__</code> ends up being called. It's called
every time <code>sum(values_to_sum)</code> is evaluated (since you start each sum with a value of the
integer 0). It's also called in line 37, in the computation of <code>5 + A(6)</code>. These other
invocations of <code>__radd__</code> do not mess up mypy. It's only messed up when you <code>__radd__</code> the
result of a <code>sum</code>.</p>]]></content:encoded></item><item><title>SArCAsTic cApiTalIZatioN GeNerATOr</title><link>https:://chrisphan.com/posts/2021-03-16_SArCAsTic_cApiTalIZatioN_GeNerATOr/index.html</link><description><![CDATA[ Here's another fun thing I made . GitHub repo]]></description><guid>https:://chrisphan.com/posts/2021-03-16_SArCAsTic_cApiTalIZatioN_GeNerATOr/index.html</guid><pubDate>Fri, 26 Mar 2021 14:54:07 -0500</pubDate><content:encoded><![CDATA[
<p><a href="../../text-transformer/index.html">Here's another fun thing I made</a>.</p>
<p><img src="../../text-transformer/text_transform_screen_shot.png" alt="" /></p>
<ul>
<li><a href="https://github.com/christopherphan/text-transformer">GitHub repo</a></li>
</ul>]]></content:encoded></item><item><title>Happy π Day!</title><link>https:://chrisphan.com/posts/2021-03-14_happy_pi_day/index.html</link><description><![CDATA[ I spent way too much time working on this . Enjoy!]]></description><guid>https:://chrisphan.com/posts/2021-03-14_happy_pi_day/index.html</guid><pubDate>Sun, 14 Mar 2021 19:27:05 -0500</pubDate><content:encoded><![CDATA[
<p>I spent <em>way too much time</em> working on <a href="https://chrisphan.com/pi_day_2021/">this</a>. Enjoy!</p>]]></content:encoded></item><item><title>What size are national legislatures?</title><link>https:://chrisphan.com/posts/2020-04-29_what_size_are_national_legislatures/index.html</link><description><![CDATA[ Introduction The other day, I came across something called the "cube root rule", which is a proposed reform to the size of the U.S. House]]></description><guid>https:://chrisphan.com/posts/2020-04-29_what_size_are_national_legislatures/index.html</guid><pubDate>Wed, 29 Apr 2020 13:45:00 -0500</pubDate><content:encoded><![CDATA[
<!-- prettier-ignore-start -->
<h2>Introduction</h2>
<p>The other day, I came across something called the &quot;cube root rule&quot;, which is a
proposed reform to the size of the U.S. House of Representative. Since 1913, the
size of the U.S. House has remained constant at 435 seats (except for a few
years when two seats were temporarily added to accommodate the addition of
Alaska and Hawaii). Under the cube root rule, the size of the U.S. House would
be increased to the cube root of the U.S. population (suitably rounded),
adjusted every census. As I write this, <a href="https://www.census.gov/popclock/">the U.S. Census bureau estimates that
the population is currently about 329.6
million</a>, and so adopting the cube root rule
would expand the U.S. House to 691 seats.</p>
<p>The cube root rule was first proposed by political scientist Rein Taagepera in
<a href="https://escholarship.org/uc/item/45g370k4#main">a 1972 paper</a>. In this paper,
he examines the size of national legislative bodies and concludes that \(n =
\sqrt[3]{P}\) is a reasonable for the size \(n\) of a nation's legislature as a
function of population \(P\). Then he gives a theoretical argument for why
\(\sqrt[3]{P}\) is an optimal value for \(n\).<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup></p>
<p>I do believe that we would benefit from having a larger U.S. House, for many of
the reasons articulated by the <em>New York Times</em> in a <a href="https://www.nytimes.com/interactive/2018/11/09/opinion/expanded-house-representatives-size.html">2018
editorial</a>,
and perhaps the Cube Root Rule would be a good way to accomplish that. However,
the point of this post is not to make that argument, but rather, see what kind
of models we can make for the <em>actual observed sizes</em> of legislative bodies.</p>
<h2>Disclaimer</h2>
<p>I want to be clear here that I don't think I'm doing anything novel here. I am
pretty sure that many actual political scientists (which I am <em>absolutely not</em>)
have tread this ground before. If I were writing an academic paper, rather than
just messing around on my blog, I would do a proper literature review and put it
here. This post is mostly about having fun programming than anything else.</p>
<h2>Regression for all countries</h2>
<p>In order to investigate this question, I needed a data set that contained the
size of legislative bodies and populations for a number of countries. If I were
a real political scientist, I would probably use some carefully curated data set
from some international organization, but because I'm just some guy messing
around on his blog, I turned to Wikipedia, namely the article <a href="https://en.wikipedia.org/w/index.php?title=List_of_legislatures_by_number_of_members&amp;oldid=951703531">&quot;List of
legislatures by number of
members&quot;</a>.<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup>
Fortunately, Pandas has <a href="https://pandas.pydata.org/docs/reference/api/pandas.read_html.html">the capacity to scrape web pages and extract data
frames from their
tables</a>.</p>
<p>For this analysis, I considered the size of the lower house of each legislature
(in cases where the legislature has more than one chamber). Wikipedia's table
doesn't just include sovereign nations, but also external territories of various
degrees of autonomy (e.g. Puerto Rico and Hong Kong), as well as the European
Union (which has an elected parliament). Note that countries are included even
if their legislatures are not elected using what we would consider free and fair
elections (such as North Korea).</p>
<p>I threw out countries where the size of the lower house was listed as &quot;maximum&quot;
or &quot;minimum&quot; (because who knows what the actual size is). If it said &quot;usually&quot;
or &quot;normally&quot;, I used the number listed. For Timor-Leste it gave a range (&quot;52 to
65&quot;), so I took the midpoint.</p>
<p>I took the logarithm<sup class="footnote-ref"><a href="#fn-5" id="fnref-5" data-footnote-ref>3</a></sup> of the population and lower house size and performed a least-squares linear regression, obtaining:
\[\log(n) = 0.3482\log(P) - 0.5369, ; r^2 = 0.8482.\]
This corresponds to \(n = 0.5846P^{0.3482}\).</p>
<p>Here is a scatterplot of the data along with \(n = 0.5846P^{0.3482}\) and \(n = \sqrt[3]{P}\):</p>
<p><img src="/leg_sizes_2020-04/legsizes_all_linear.png" alt="A scatterplot. The horizontal axis is population, the vertical is the size of the lower house. Most of the observations are clustered in the bottom left corner. A plot of the mentioned curves are shown. " /></p>
<p>And here is the same, but plotted in log scale (which makes more sense for this data):</p>
<p><img src="/leg_sizes_2020-04/legsizes_all_log.png" alt="The same scatterplot as above, except in log-log scale. The data points are spread out close to the diagonal lines that represent the mentioned curves." /></p>
<p>(It should be noted that a very similar plot appears in Taagepera's paper.)</p>
<h2>Regression for other subsets of countries</h2>
<p>As mentioned before, the data set includes countries that are not democracies (e.g. North Korea) as well as non-countries (territories and the European Union). We might restrict our attention to various subsets of countries, such as the members of:</p>
<ul>
<li>The North Atlantic Treaty Organization</li>
<li>The Organisation for Economic Co-operation and Development</li>
<li>The European Union</li>
</ul>
<p>The results are in this table:</p>
<table>
<thead>
<tr>
<th align="left">Group of countries</th>
<th align="left">Regression<sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup></th>
<th align="left">\(r^2\)</th>
<th align="left">Plots</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">all</td>
<td align="left">\(\log(n) = 0.3482\log(P) - 0.5369 \Rightarrow n = 0.5846P^{0.3482}\)</td>
<td align="left">\(r^2 = 0.8482\)</td>
<td align="left"><a href="/leg_sizes_2020-04/legsizes_all_linear.png">linear</a> <a href="/leg_sizes_2020-04/legsizes_all_log.png">log</a></td>
</tr>
<tr>
<td align="left">NATO</td>
<td align="left">\(\log(n) = 0.3990\log(P) - 1.0466 \Rightarrow n = 0.3511P^{0.3990}\)</td>
<td align="left">\(r^2 = 0.8764\)</td>
<td align="left"><a href="/leg_sizes_2020-04/legsizes_NATO_linear.png">linear</a> <a href="/leg_sizes_2020-04/legsizes_NATO_log.png">log</a></td>
</tr>
<tr>
<td align="left">OECD</td>
<td align="left">\(\log(n) = 0.3850\log(P) - 0.8940 \Rightarrow n = 0.4090P^{0.3850}\)</td>
<td align="left">\(r^2 = 0.8026\)</td>
<td align="left"><a href="/leg_sizes_2020-04/legsizes_OECD_linear.png">linear</a> <a href="/leg_sizes_2020-04/legsizes_OECD_log.png">log</a></td>
</tr>
<tr>
<td align="left">EU</td>
<td align="left">\(\log(n) = 0.4477\log(P) - 1.8032 \Rightarrow n = 0.1648P^{0.4477}\)</td>
<td align="left">\(r^2 = 0.8817\)</td>
<td align="left"><a href="/leg_sizes_2020-04/legsizes_EU_linear.png">linear</a> <a href="/leg_sizes_2020-04/legsizes_EU_log.png">log</a></td>
</tr>
<tr>
<td align="left">OECD, NATO, or EU</td>
<td align="left">\(\log(n) = 0.3796\log(P) - 0.7875 \Rightarrow n = 0.4550P^{0.3796}\)</td>
<td align="left">\(r^2 = 0.8339\)</td>
<td align="left"><a href="/leg_sizes_2020-04/legsizes_OECD_NATO_or_EU_linear.png">linear</a> <a href="/leg_sizes_2020-04/legsizes_OECD_NATO_or_EU_log.png">log</a></td>
</tr>
</tbody>
</table>
<p>For example, <a href="https://www.nytimes.com/interactive/2018/11/09/opinion/expanded-house-representatives-size.html">the aforementioned <em>New York Times</em> editorial</a> has a plot similar to this one:</p>
<p><img src="/leg_sizes_2020-04/legsizes_OECD_linear.png" alt="A scatterplot titled &quot;Population and lower legislative house size (linear scale, OECD countries)&quot;. The curve from the OECD regression in the table is shown, as well as a plot of the cube-root function. The observations are mostly situated around the curves. " /></p>
<h2>Source code</h2>
<p>The Python script to parse the Wikipedia article, run the regressions, and produce the plots can be downloaded here: <a href="https://gist.github.com/christopherphan/1fb909448a967d37b3b345e308c8f568"><code>leg_sizes.py</code></a></p>
<p>It is also shown below:</p><div class="code_block"><div class="code-header"><span class="filename">leg_sizes.py</span> <span class="code-lang">Python</span></div><pre class=""  id="block-d5b70236-b157-4a3d-8f92-b4d492f50d43"><code class="language-python"><code class="checker lineno dig-2"><span style="color:#586e75;">#!/usr/bin/env python3</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"># leg_sizes.py</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"># Christopher Phan</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"># cphan@chrisphan.com</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"># https://chrisphan.com/</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"># Takes data from the Wikipedia article &quot;List of legislatures by number of</span></code>
<code class="checker lineno dig-2"><span style="color:#586e75;"># members&quot;, and peforms a linear regression on n = kP^alpha</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># where n is the number of members of the lower house of a nation&#39;s legislature</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># and P is the population.</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># This script was written for Python 3.6.</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># To run this script, save</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># https://en.wikipedia.org/w/index.php?title=List_of_legislatures_by_number_of_members&amp;oldid=951703531</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># to legislatures.html</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">################################################################################</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># Copyright 2020 Christopher Phan</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># Permission is hereby granted, free of charge, to any person obtaining a copy</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># of this software and associated documentation files (the &quot;Software&quot;), to deal</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># in the Software without restriction, including without limitation the rights</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># copies of the Software, and to permit persons to whom the Software is</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># furnished to do so, subject to the following conditions:</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># The above copyright notice and this permission notice shall be included in all</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># copies or substantial portions of the Software.</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># SOFTWARE.</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">#</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">pandas </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">pd</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">scipy.stats </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">stats</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">numpy </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">np</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">matplotlib</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">matplotlib.pyplot </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">plt</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># See note above</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">data </span><span style="color:#657b83;">= </span><span style="color:#839496;">pd.</span><span style="color:#b58900;">read_html</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">legislatures.html</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">def </span><span style="color:#b58900;">contains_min_or_max</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">x</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">minimum</span><span style="color:#839496;">&quot; </span><span style="color:#859900;">in </span><span style="color:#839496;">x</span><span style="color:#657b83;">) </span><span style="color:#859900;">or </span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">maximum</span><span style="color:#839496;">&quot; </span><span style="color:#859900;">in </span><span style="color:#839496;">x</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">return </span><span style="color:#b58900;">True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">return </span><span style="color:#b58900;">False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># Get rid of entries with only a minimum or maximum leg size listed</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># (since we have no idea the actual size)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">data </span><span style="color:#657b83;">= </span><span style="color:#839496;">data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lowerhouse[1]</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span><span style="color:#839496;">contains_min_or_max</span><span style="color:#657b83;">) == </span><span style="color:#b58900;">False</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">def </span><span style="color:#b58900;">number_parse</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">x</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">if isinstance</span><span style="color:#657b83;">(</span><span style="color:#839496;">x, </span><span style="color:#859900;">int</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">return </span><span style="color:#839496;">x</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        num </span><span style="color:#657b83;">= </span><span style="color:#839496;">x.</span><span style="color:#b58900;">split</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">[</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">] </span><span style="color:#586e75;"># Get rid of footnotes</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">to</span><span style="color:#839496;">&quot; </span><span style="color:#859900;">in </span><span style="color:#839496;">num</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#586e75;"># Take the mean if it says &quot;a to b&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            splits </span><span style="color:#657b83;">= </span><span style="color:#839496;">num.</span><span style="color:#b58900;">split</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;"> to </span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            num </span><span style="color:#657b83;">= (</span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">splits</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">) + </span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">splits</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">1</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">))/</span><span style="color:#6c71c4;">2</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">        </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            </span><span style="color:#586e75;"># Get rid of words &quot;usually&quot; or &quot;normally&quot;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">            num </span><span style="color:#657b83;">= </span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">num.</span><span style="color:#b58900;">split</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot; &quot;</span><span style="color:#657b83;">)</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">return </span><span style="color:#839496;">num</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">countries </span><span style="color:#657b83;">= </span><span style="color:#839496;">data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">Country</span><span style="color:#839496;">&#39;</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">leg_size </span><span style="color:#657b83;">= </span><span style="color:#839496;">data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lowerhouse[1]</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span><span style="color:#839496;">number_parse</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">pop_size </span><span style="color:#657b83;">= </span><span style="color:#839496;">data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population[2]</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span><span style="color:#839496;">number_parse</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># List of OECD countries</span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># From http://www.oecd.org/about/members-and-partners/</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">oecd_countries </span><span style="color:#657b83;">= [</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Australia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Austria</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Belgium</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Canada</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Chile</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Czech Republic</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Denmark</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Estonia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Finland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">France</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Germany</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Greece</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Hungary</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Iceland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Ireland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Israel</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Italy</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Japan</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Korea, South</span><span style="color:#839496;">&quot;, </span><span style="color:#586e75;"># Changed from &quot;Korea&quot; to match Wikipedia</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Latvia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Lithuania</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Luxembourg</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Mexico</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Netherlands</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">New Zealand</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Norway</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Poland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Portugal</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Slovakia</span><span style="color:#839496;">&quot;, </span><span style="color:#586e75;"># Changed from &quot;Slovak Republic&quot; to match Wikipedia</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Slovenia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Spain</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Sweden</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Switzerland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Turkey</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">United Kingdom</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">United States</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># List of NATO countries</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># From https://www.nato.int/cps/en/natohq/nato_countries.htm</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">nato_countries </span><span style="color:#657b83;">= [</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Albania</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Belgium</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Bulgaria</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Canada</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Croatia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Czech Republic</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Denmark</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Estonia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">France</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Germany</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Greece</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Hungary</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Iceland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Italy</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Latvia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Lithuania</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Luxembourg</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Montenegro</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Netherlands</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">North Macedonia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Norway</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Poland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Portugal</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Romania</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Slovakia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Slovenia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Spain</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Turkey</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">United Kingdom</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">United States</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># List of European Union countries</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># From https://europa.eu/european-union/about-eu/countries_en</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">eu_countries </span><span style="color:#657b83;">= [</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Austria</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Italy</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Belgium</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Latvia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Bulgaria</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Lithuania</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Croatia</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Luxembourg</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Cyprus</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Malta</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Czech Republic</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Netherlands</span><span style="color:#839496;">&quot;, </span><span style="color:#586e75;"># Changed from &quot;Czechia&quot; to match Wikipedia</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Denmark</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Poland</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Estonia</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Portugal</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Finland</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Romania</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">France</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Slovakia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Germany</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Slovenia</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Greece</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Spain</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Hungary</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">Sweden</span><span style="color:#839496;">&quot;,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &quot;</span><span style="color:#2aa198;">Ireland</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># Output the parsed data to a new CSV file</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">newdata </span><span style="color:#657b83;">= </span><span style="color:#839496;">pd.</span><span style="color:#b58900;">DataFrame</span><span style="color:#657b83;">({</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &#39;</span><span style="color:#2aa198;">Country</span><span style="color:#839496;">&#39;: countries,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &#39;</span><span style="color:#2aa198;">Lower house size</span><span style="color:#839496;">&#39;: leg_size,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    &#39;</span><span style="color:#2aa198;">Population</span><span style="color:#839496;">&#39;: pop_size</span><span style="color:#657b83;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">OECD</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">] </span><span style="color:#657b83;">= </span><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Country</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: </span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">oecd_countries</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">NATO</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">] </span><span style="color:#657b83;">= </span><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Country</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: </span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">nato_countries</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">EU</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">] </span><span style="color:#657b83;">= </span><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Country</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: </span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">eu_countries</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">OECD, NATO, or EU</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">] </span><span style="color:#657b83;">= </span><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Country</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">.</span><span style="color:#b58900;">apply</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: (</span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">oecd_countries</span><span style="color:#657b83;">) </span><span style="color:#859900;">or</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#657b83;">(</span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">nato_countries</span><span style="color:#657b83;">) </span><span style="color:#859900;">or </span><span style="color:#657b83;">(</span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">eu_countries</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">newdata.</span><span style="color:#b58900;">to_csv</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Parsed_data.csv</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">all_table </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;&quot;&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">| Group of countries  | Regression[^4]               | $r^2$          | Plots         |</span></code>
<code class="checker lineno dig-0"><span style="color:#2aa198;">| :------------------ | :--------------------------- |:-------------- |:--------------|</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">&quot;&quot;&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">for </span><span style="color:#839496;">condition </span><span style="color:#859900;">in </span><span style="color:#657b83;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">all</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">NATO</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">OECD</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">EU</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">OECD, NATO, or EU</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">]:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;"># Calculate the regression</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">if </span><span style="color:#839496;">condition </span><span style="color:#657b83;">== </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">all</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        current_data </span><span style="color:#657b83;">= </span><span style="color:#839496;">newdata</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        current_data </span><span style="color:#657b83;">= </span><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">newdata</span><span style="color:#268bd2;">[</span><span style="color:#839496;">condition</span><span style="color:#268bd2;">] </span><span style="color:#657b83;">== </span><span style="color:#b58900;">True</span><span style="color:#268bd2;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    log_leg_size </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lower house size</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    log_pop_size </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    m, b, r, p, stderr </span><span style="color:#657b83;">= </span><span style="color:#839496;">stats.</span><span style="color:#b58900;">linregress</span><span style="color:#657b83;">(</span><span style="color:#839496;">log_pop_size, log_leg_size</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">def </span><span style="color:#b58900;">signstr</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">x</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#839496;">x </span><span style="color:#657b83;">&lt; </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">-</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">return </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">+</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    filename_str </span><span style="color:#657b83;">= </span><span style="color:#839496;">condition.</span><span style="color:#b58900;">replace</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot; &quot;, &quot;</span><span style="color:#2aa198;">_</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    filename_str </span><span style="color:#657b83;">= </span><span style="color:#839496;">filename_str.</span><span style="color:#b58900;">replace</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">,</span><span style="color:#839496;">&quot;, &quot;&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    bracket_to_brace </span><span style="color:#657b83;">= </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: </span><span style="color:#839496;">x.</span><span style="color:#b58900;">replace</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">[</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">{</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span><span style="color:#839496;">.</span><span style="color:#b58900;">replace</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">]</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">}</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">with open</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">regression_data_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">.txt</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        filename_str</span><span style="color:#657b83;">)</span><span style="color:#839496;">, &quot;</span><span style="color:#2aa198;">wt</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">as </span><span style="color:#839496;">outfile</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;"> countries:</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">condition</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">log(n) = </span><span style="color:#cb4b16;">{:0.4f}</span><span style="color:#2aa198;">*log(P) </span><span style="color:#cb4b16;">{} {:0.4f}</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                m, </span><span style="color:#b58900;">signstr</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#859900;">abs</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">)))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">n = </span><span style="color:#cb4b16;">{:0.4f}</span><span style="color:#2aa198;">P^</span><span style="color:#cb4b16;">{:0.4f}</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">exp</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">)</span><span style="color:#839496;">, m</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">r^2 = </span><span style="color:#cb4b16;">{:0.4f}</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">r</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    regression_text </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">$n = </span><span style="color:#cb4b16;">{:0.4f}</span><span style="color:#2aa198;">P^</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">exp</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    regression_text </span><span style="color:#657b83;">+= </span><span style="color:#b58900;">bracket_to_brace</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">[</span><span style="color:#cb4b16;">{:0.4f}</span><span style="color:#2aa198;">]$</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">m</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;"># Add to markdown table</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    all_table </span><span style="color:#657b83;">+= </span><span style="color:#268bd2;">r</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">|</span><span style="color:#2aa198;"> {} </span><span style="color:#859900;">| $</span><span style="color:#dc322f;">\l</span><span style="color:#2aa198;">og(n) = {:0</span><span style="color:#cb4b16;">.</span><span style="color:#2aa198;">4f}</span><span style="color:#dc322f;">\l</span><span style="color:#2aa198;">og(P) {} {:0</span><span style="color:#cb4b16;">.</span><span style="color:#2aa198;">4f}</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        condition, m, </span><span style="color:#b58900;">signstr</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#859900;">abs</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    all_table </span><span style="color:#657b83;">+= </span><span style="color:#268bd2;">r</span><span style="color:#839496;">&quot; </span><span style="color:#dc322f;">\R</span><span style="color:#2aa198;">ightarrow {}</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        regression_text</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">:</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    all_table </span><span style="color:#657b83;">+= </span><span style="color:#268bd2;">r</span><span style="color:#839496;">&quot;</span><span style="color:#859900;">| $</span><span style="color:#2aa198;">r</span><span style="color:#859900;">^</span><span style="color:#2aa198;">2 = {:0</span><span style="color:#cb4b16;">.</span><span style="color:#2aa198;">4f}</span><span style="color:#859900;">$ |</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">r</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    all_table </span><span style="color:#657b83;">+= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">[linear](/leg_sizes_2020-04/legsizes_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">_linear.png) </span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        filename_str</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    all_table </span><span style="color:#657b83;">+= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">[log](/leg_sizes_2020-04/legsizes_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">_log.png) |</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        filename_str</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;"># Make plots</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    source_txt </span><span style="color:#657b83;">= </span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">Sources listed at: https://chrisphan.com/2020-04-29_what_size_are_national_legislatures/#sources</span><span style="color:#839496;">&#39;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    maxpop </span><span style="color:#657b83;">= </span><span style="color:#859900;">max</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    maxsize </span><span style="color:#657b83;">= </span><span style="color:#859900;">max</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lower house size</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    minpop </span><span style="color:#657b83;">= </span><span style="color:#859900;">min</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    minsize </span><span style="color:#657b83;">= </span><span style="color:#859900;">min</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lower house size</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">for </span><span style="color:#839496;">scale </span><span style="color:#859900;">in </span><span style="color:#657b83;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">linear</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">log</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">]:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#839496;">scale </span><span style="color:#657b83;">== </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">linear</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            xmin </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">0</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            xmax </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">1.1</span><span style="color:#657b83;">*</span><span style="color:#839496;">maxpop</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            ymin </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">0</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            ymax </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">1.1</span><span style="color:#657b83;">*</span><span style="color:#839496;">maxsize</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            xmin </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**(</span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">minpop</span><span style="color:#657b83;">)/</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">)))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            xmax </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**(</span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">maxpop</span><span style="color:#657b83;">)/</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">) + </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            ymin </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**(</span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">minsize</span><span style="color:#657b83;">)/</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">)))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            ymax </span><span style="color:#657b83;">= </span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**(</span><span style="color:#859900;">int</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">maxsize</span><span style="color:#657b83;">)/</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">) + </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        fig </span><span style="color:#657b83;">= </span><span style="color:#839496;">plt.</span><span style="color:#b58900;">figure</span><span style="color:#657b83;">(</span><span style="color:#268bd2;">figsize</span><span style="color:#657b83;">=(</span><span style="color:#6c71c4;">8</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        ax </span><span style="color:#657b83;">= </span><span style="color:#839496;">fig.</span><span style="color:#b58900;">add_subplot</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">111</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#839496;">scale </span><span style="color:#657b83;">== </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">linear</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            xvals </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(</span><span style="color:#839496;">xmin</span><span style="color:#657b83;">/</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">6</span><span style="color:#839496;">, xmax</span><span style="color:#657b83;">/</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">)*</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">6</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">else</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            xvals </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">exp</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(</span><span style="color:#839496;">np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">xmin</span><span style="color:#657b83;">)</span><span style="color:#839496;">, np.</span><span style="color:#b58900;">log</span><span style="color:#657b83;">(</span><span style="color:#839496;">xmax</span><span style="color:#657b83;">) + </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        yvals </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">exp</span><span style="color:#657b83;">(</span><span style="color:#839496;">b</span><span style="color:#657b83;">)*(</span><span style="color:#839496;">xvals</span><span style="color:#657b83;">)**</span><span style="color:#839496;">m</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        yvals2 </span><span style="color:#657b83;">= </span><span style="color:#839496;">xvals</span><span style="color:#657b83;">**(</span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">/</span><span style="color:#6c71c4;">3</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">xscale</span><span style="color:#657b83;">(</span><span style="color:#839496;">scale</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">yscale</span><span style="color:#657b83;">(</span><span style="color:#839496;">scale</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">if </span><span style="color:#839496;">scale </span><span style="color:#657b83;">== </span><span style="color:#839496;">&#39;</span><span style="color:#2aa198;">linear</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            fmtx </span><span style="color:#657b83;">= </span><span style="color:#839496;">matplotlib.ticker.</span><span style="color:#b58900;">FuncFormatter</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                </span><span style="color:#268bd2;">lambda x</span><span style="color:#839496;">, </span><span style="color:#268bd2;">f</span><span style="color:#657b83;">: </span><span style="color:#839496;">&#39;</span><span style="color:#cb4b16;">{:,.0f}</span><span style="color:#2aa198;"> m</span><span style="color:#839496;">&#39;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">x</span><span style="color:#657b83;">/</span><span style="color:#6c71c4;">10</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            fmty </span><span style="color:#657b83;">= </span><span style="color:#839496;">matplotlib.ticker.</span><span style="color:#b58900;">FuncFormatter</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                </span><span style="color:#268bd2;">lambda y</span><span style="color:#839496;">, </span><span style="color:#268bd2;">f</span><span style="color:#657b83;">: </span><span style="color:#839496;">&#39;</span><span style="color:#cb4b16;">{:,.0f}</span><span style="color:#839496;">&#39;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">y</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            ax.yaxis.</span><span style="color:#b58900;">set_major_formatter</span><span style="color:#657b83;">(</span><span style="color:#839496;">fmty</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            ax.xaxis.</span><span style="color:#b58900;">set_major_formatter</span><span style="color:#657b83;">(</span><span style="color:#839496;">fmtx</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">xlim</span><span style="color:#657b83;">(</span><span style="color:#839496;">xmin, xmax</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">ylim</span><span style="color:#657b83;">(</span><span style="color:#839496;">ymin, ymax</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">plot</span><span style="color:#657b83;">(</span><span style="color:#839496;">current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            current_data</span><span style="color:#268bd2;">[</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lower house size</span><span style="color:#839496;">&quot;</span><span style="color:#268bd2;">]</span><span style="color:#839496;">, &quot;</span><span style="color:#2aa198;">b.</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">plot</span><span style="color:#657b83;">(</span><span style="color:#839496;">xvals, yvals, &#39;</span><span style="color:#2aa198;">r</span><span style="color:#839496;">&#39;, </span><span style="color:#268bd2;">label</span><span style="color:#657b83;">=</span><span style="color:#839496;">regression_text</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">plot</span><span style="color:#657b83;">(</span><span style="color:#839496;">xvals, yvals2, &#39;</span><span style="color:#2aa198;">g--</span><span style="color:#839496;">&#39;, </span><span style="color:#268bd2;">label</span><span style="color:#657b83;">= </span><span style="color:#268bd2;">r</span><span style="color:#839496;">&#39;</span><span style="color:#859900;">$</span><span style="color:#2aa198;">n = </span><span style="color:#cb4b16;">\s</span><span style="color:#2aa198;">qrt</span><span style="color:#cb4b16;">[3]</span><span style="color:#2aa198;">{P}</span><span style="color:#859900;">$</span><span style="color:#839496;">&#39;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">grid</span><span style="color:#657b83;">(</span><span style="color:#b58900;">True</span><span style="color:#839496;">, </span><span style="color:#268bd2;">which</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">both</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">legend</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        title </span><span style="color:#657b83;">= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population and lower legislative house size</span><span style="color:#839496;">&quot;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        title </span><span style="color:#657b83;">+= </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;"> (</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;"> scale, </span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;"> countries)</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            scale, condition</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">title</span><span style="color:#657b83;">(</span><span style="color:#839496;">title</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">xlabel</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Population ($P$)</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot; </span><span style="color:#657b83;">+ </span><span style="color:#839496;">source_txt</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">ylabel</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">Lower house size ($n$)</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">tight_layout</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        fig.</span><span style="color:#b58900;">savefig</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">legsizes_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">.png</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">filename_str, scale</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        fig.</span><span style="color:#b58900;">savefig</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">legsizes_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">.pdf</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">filename_str, scale</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        plt.</span><span style="color:#b58900;">close</span><span style="color:#657b83;">()</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">with open</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">regression_table.md</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">wt</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">as </span><span style="color:#839496;">markout</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    markout.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">all_table</span><span style="color:#657b83;">)</span></code>
</code></pre></div>
<h2>CSV file</h2>
<p>My script produces a CSV file of the data after its processed (but before the regression is run): <a href="/leg_sizes_2020-04/Parsed_data.csv"><code>Parsed_data.csv</code></a></p>
<p>It is also shown below:</p><div class="code_block"><div class="code-header"><span class="filename">Parsed_data.csv</span> <span class="code-lang">CSV</span></div><pre class=""  id="block-824fa1ec-b129-4d6f-8bf2-4e90e33cc9f9"><code class="language-csv"><code class="checker lineno dig-2"><span style="color:#839496;">,Country,Lower house size,Population,OECD,NATO,EU,&quot;OECD, NATO, or EU&quot;</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">0,&quot;China, People&#39;s Republic of&quot;,2980.0,1355692576,False,False,False,False</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">1,United Kingdom,650.0,63742977,True,True,False,True</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">2,Italy,630.0,61680122,True,True,True,True</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">3,France,577.0,66259012,True,True,True,True</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">4,India,545.0,1236344631,False,False,False,False</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">5,European Union,705.0,511434812,False,False,False,False</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">6,Germany,709.0,80996685,True,True,True,True</span></code>
<code class="checker lineno dig-2"><span style="color:#839496;">7,Japan,465.0,126451398,True,False,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">8,Indonesia,575.0,271407446,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">9,&quot;Korea, North&quot;,687.0,24851627,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">10,Morocco,395.0,32987206,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">11,Burma (Myanmar),440.0,55746253,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">12,Ethiopia,547.0,96633458,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">13,Thailand,500.0,67741401,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">14,Mexico,500.0,120286655,True,False,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">15,Russia,450.0,142470272,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">16,Cuba,612.0,11047251,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">17,&quot;Congo, Democratic Republic of the&quot;,500.0,77433744,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">18,Spain,350.0,47737941,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">19,Algeria,462.0,38813722,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">20,Brazil,513.0,202656788,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">21,Poland,460.0,38346279,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">22,Turkey,600.0,84339067,True,True,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">23,United States,435.0,318892103,True,True,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">24,Sudan,450.0,35482233,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">25,Vietnam,500.0,93421835,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">26,South Africa,400.0,48375645,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">27,Nigeria,360.0,177155754,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">28,Romania,329.0,20121641,False,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">29,Egypt,596.0,100388073,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">30,Ukraine,450.0,44291413,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">31,Pakistan,342.0,196174380,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">32,Kenya,349.0,45010056,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">33,Canada,338.0,34834841,True,True,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">34,Yemen,301.0,26052966,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">35,South Sudan,332.0,11562695,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">36,Uganda,375.0,35918915,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">37,Tanzania,357.0,49639138,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">38,CÃ´te d&#39;Ivoire,255.0,22848945,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">40,Zimbabwe,270.0,13771721,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">41,Sweden,349.0,9723809,True,False,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">42,Nepal,275.0,28982771,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">43,Argentina,257.0,43024374,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">44,Somalia,275.0,10428043,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">45,Iraq,325.0,32585692,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">46,Philippines,304.0,107668231,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">47,Bangladesh,300.0,166280712,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">48,Greece,300.0,10775557,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">49,&quot;Korea, South&quot;,300.0,49039986,True,False,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">50,Malaysia,222.0,30073353,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">51,Iran,290.0,80840713,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">52,Czech Republic,200.0,10627448,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">53,Cameroon,180.0,23130708,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">54,Ghana,275.0,25758108,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">55,Colombia,166.0,46245297,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">56,Mozambique,250.0,24692144,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">57,Serbia,250.0,7209764,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">58,Syria,250.0,17951639,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">59,Uzbekistan,150.0,28929716,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">60,Switzerland,200.0,8061516,True,False,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">61,Austria,183.0,8223062,True,False,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">62,Bulgaria,240.0,6924716,False,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">63,Portugal,230.0,10813834,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">64,Australia,150.0,22507617,True,False,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">65,Ireland,166.0,4832765,True,False,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">66,Netherlands,150.0,16877351,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">67,Sri Lanka,225.0,21866445,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">68,Gabon,120.0,1672597,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">69,Belgium,150.0,11420163,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">70,Angola,220.0,19088106,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">71,Tunisia,217.0,10937521,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">72,Dominican Republic,183.0,10349741,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">73,&quot;Congo, Republic of the&quot;,139.0,4662446,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">74,Jordan,150.0,7930491,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">75,Finland,200.0,5268799,True,False,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">76,Libya,200.0,6244174,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">77,Hungary,199.0,9919128,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">78,Malawi,193.0,17377468,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">79,Chad,188.0,11412107,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">80,Cambodia,123.0,15458332,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">81,Madagascar,151.0,23201926,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">82,Denmark,179.0,5569077,True,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">83,Belarus,110.0,9608058,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">84,Equatorial Guinea,100.0,722254,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">85,Norway,169.0,5147792,True,True,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">86,Bolivia,130.0,10631486,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">87,Venezuela,165.0,28868486,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">88,Mali,160.0,16455903,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">89,Chile,155.0,17574003,True,False,False,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">90,Guatemala,158.0,14647083,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">91,Zambia,158.0,14638505,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">92,Oman,84.0,3219775,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">94,Kazakhstan,107.0,17948816,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">95,Lesotho,120.0,1942008,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">96,Croatia,151.0,4470534,False,True,True,True</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">97,Eritrea,150.0,6380803,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">98,Georgia,150.0,4935880,False,False,False,False</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">99,Saudi Arabia,150.0,27345986,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">100,Senegal,150.0,13635927,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">101,Slovakia,150.0,5443583,True,True,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">102,Mauritania,146.0,3516806,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">103,Lithuania,141.0,2848000,True,True,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">104,Albania,140.0,3020209,False,True,False,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">105,Ecuador,137.0,15654411,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">106,Laos,149.0,6803699,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">108,Palestine,132.0,4816503,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">109,Peru,130.0,30147935,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">110,Slovenia,90.0,2070050,True,True,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">111,Haiti,99.0,9996731,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">112,Uruguay,99.0,3332972,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">113,Honduras,128.0,8598561,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">114,Lebanon,128.0,5882562,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">115,Burkina Faso,127.0,18365123,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">116,Azerbaijan,125.0,9686210,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">117,Paraguay,80.0,6703860,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">118,Turkmenistan,125.0,5171943,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">119,Sierra Leone,124.0,5743725,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">120,North Macedonia,123.0,2091719,False,True,False,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">121,Israel,120.0,7821850,True,False,False,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">122,Kosovo,120.0,1859203,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">123,Kyrgyzstan,120.0,5604212,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">124,New Zealand,120.0,4401916,True,False,False,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">125,Guinea,114.0,11474383,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">126,Niger,113.0,17466172,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">127,&quot;China, Republic of&quot;,113.0,23359928,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">128,Papua New Guinea,111.0,6552730,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">129,Rwanda,80.0,12337138,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">130,Central African Republic,105.0,5277959,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">131,Liberia,73.0,4092310,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">132,Guinea-Bissau,102.0,1693398,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">133,Estonia,101.0,1257921,True,True,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">134,Moldova,101.0,3583288,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">135,Latvia,100.0,2165165,True,True,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">136,Namibia,72.0,2198406,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">137,Tajikistan,63.0,8051512,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">138,Swaziland,65.0,1419623,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">139,Nicaragua,92.0,5848641,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">140,Togo,91.0,7351374,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">141,Singapore,87.0,5567301,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">142,Maldives,85.0,393595,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">143,El Salvador,84.0,6125512,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">144,Jamaica,63.0,2930050,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">145,Benin,83.0,10160556,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">146,Montenegro,81.0,650036,False,True,False,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">147,Bahrain,40.0,1314089,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">148,Cyprus,80.0,1172458,False,False,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">149,Puerto Rico,51.0,3620897,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">150,Mongolia,76.0,3251587,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">151,Bhutan,47.0,733643,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">152,Cabo Verde,72.0,538535,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">153,Trinidad and Tobago,41.0,1223916,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">154,Panama,71.0,3608431,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">155,Hong Kong,70.0,7112688,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">156,Mauritius,70.0,1331155,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">157,Djibouti,65.0,810179,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">158,Guyana,65.0,735554,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">159,Kuwait,65.0,2742711,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">160,Malta,65.0,412655,False,False,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">161,Timor-Leste,58.5,1201542,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">162,Botswana,63.0,2155784,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">163,Iceland,63.0,317351,True,True,False,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">164,Luxembourg,60.0,520672,True,True,True,True</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">165,San Marino,60.0,32742,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">166,Jersey,58.0,96513,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">167,Bosnia and Herzegovina,42.0,3871643,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">168,Costa Rica,57.0,4755234,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">169,French Polynesia,57.0,280026,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">170,SÃ£o TomÃ© and PrÃ­ncipe,55.0,190428,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">171,&quot;Bahamas, The&quot;,38.0,321834,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">172,New Caledonia,54.0,267840,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">173,&quot;Gambia, The&quot;,53.0,1925527,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">174,Vanuatu,52.0,266937,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">175,Barbados,30.0,289680,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">176,Suriname,51.0,573311,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">177,Fiji,50.0,903207,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">178,Solomon Islands,50.0,609883,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">179,Samoa,49.0,196628,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">180,Bermuda,36.0,69839,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">181,Kiribati,46.0,104488,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">182,Guernsey,45.0,65849,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">183,Qatar,45.0,2123160,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">184,Transnistria,45.0,469000,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">185,Belize,31.0,340844,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">186,United Arab Emirates,40.0,5628805,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">187,American Samoa,21.0,54517,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">188,Isle of Man,24.0,86866,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">189,Abkhazia,35.0,243206,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">190,Antigua and Barbuda,17.0,91295,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">191,Seychelles,34.0,91650,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">192,South Ossetia,34.0,53532,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">193,Artsakh,33.0,150932,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">194,Brunei,33.0,422675,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">195,Comoros,33.0,766865,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">196,Faroe Islands,33.0,49947,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">197,Macau,33.0,587914,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">198,Marshall Islands,33.0,70983,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">199,Dominica,32.0,73449,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">200,Greenland,31.0,57728,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">201,Northern Mariana Islands,20.0,51483,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">203,Grenada,15.0,110152,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">204,Saint Lucia,17.0,163362,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">205,Tonga,26.0,106440,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">206,Liechtenstein,25.0,37313,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">207,Palau,16.0,21186,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">208,Cook Islands,24.0,10134,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">209,Monaco,24.0,30508,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">210,Saint Martin,23.0,31530,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">211,Aruba,21.0,110663,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">212,Cayman Islands,21.0,54914,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">213,CuraÃ§ao,21.0,146836,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">214,Saint Vincent and the Grenadines,21.0,102918,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">215,Niue,20.0,1190,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">216,Tokelau,20.0,1337,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">217,Wallis and Futuna,20.0,15561,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">218,Nauru,19.0,9488,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">219,Saint Barthelemy,19.0,7267,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">220,Saint Pierre and Miquelon,19.0,5716,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">221,Turks and Caicos Islands,19.0,49070,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">222,Gibraltar,18.0,29185,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">223,&quot;Saint Helena, Ascension and Tristan da Cunha&quot;,17.0,7776,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">224,British Virgin Islands,15.0,32680,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">225,Guam,15.0,161001,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">226,Sint Maarten,15.0,39689,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">227,Tuvalu,15.0,10782,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">228,United States Virgin Islands,15.0,104170,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">229,&quot;Micronesia, Federated States of&quot;,14.0,105681,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">230,Saint Kitts and Nevis,14.0,51538,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">231,Anguilla,11.0,16086,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">232,Montserrat,11.0,5215,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">233,Falkland Islands,10.0,2840,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">234,Pitcairn Islands,10.0,48,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">235,Christmas Island,9.0,1530,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">236,Norfolk Island,9.0,2210,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">237,Cocos (Keeling) Islands,7.0,596,False,False,False,False</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">238,Vatican City,7.0,842,False,False,False,False</span></code>
</code></pre></div>
<h2>Sources</h2>
<ul>
<li>
<p>Wikipedia article &quot;List of legislatures by number of members&quot;: <a href="https://en.wikipedia.org/w/index.php?title=List_of_legislatures_by_number_of_members&amp;oldid=951703531">https://en.wikipedia.org/w/index.php?title=List_of_legislatures_by_number_of_members&amp;oldid=951703531</a></p>
</li>
<li>
<p>List of NATO countries: <a href="https://www.nato.int/cps/en/natohq/nato_countries.htm">https://www.nato.int/cps/en/natohq/nato_countries.htm</a></p>
</li>
<li>
<p>List of OECD countries: <a href="http://www.oecd.org/about/members-and-partners/">http://www.oecd.org/about/members-and-partners/</a></p>
</li>
<li>
<p>List of EU countries: <a href="https://europa.eu/european-union/about-eu/countries_en">https://europa.eu/european-union/about-eu/countries_en</a></p>
</li>
</ul>
<h2>Footnotes</h2>
<!-- prettier-ignore-end -->
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Taagepera's argument is, basically, that a member of the legislature should spend an equal amount of energy paying attention to conversations between members (of which there are \(n(n-1)/2\)) and their own discussions with politically-interested constituents (of which there are \(kP/n - 1\), where \(k\) is the proportion of the population that cares about politics). Setting these equal and solving for $P$, we get \[P = \frac{n^3 - n^2 + 2n}{2k},\] i.e. \(n\) should be asymptotically proportional to \(\sqrt[3]{P}\). Making what Taagepera calls the &quot;rather reasonable assumption that about one half of the population is politically active&quot;, i.e. that \(k = 1/2\), we have \(n \approx \sqrt[3]{P}\) for \(n\) sufficiently large. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>This link goes to the specific revision of the Wikipedia article that I used in my analysis. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-5">
<p>Natural logarithm. <a href="#fnref-5" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p>Linear regression on \(\log(n) = \alpha\log(P) + k\). <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>On (not) voting at a polling place</title><link>https:://chrisphan.com/posts/2020-04-23_on_not_voting_at_a_polling_place/index.html</link><description><![CDATA[ Because of the potential for COVID-19 to disrupt elections this fall, mail voting is getting a lot of attention. It's not a good idea to]]></description><guid>https:://chrisphan.com/posts/2020-04-23_on_not_voting_at_a_polling_place/index.html</guid><pubDate>Thu, 23 Apr 2020 14:06:00 -0500</pubDate><content:encoded><![CDATA[
<p>Because of the potential for COVID-19 to disrupt elections this fall, mail
voting is getting a lot of attention. It's not a good idea to make people choose
between their safety and exercising the franchise.</p>
<p>I grew up in Oregon, and spent the first decade of my adult life there, but now
I have spent more of my adult life living outside Oregon than within it. Since
moving from Oregon, I have shed many of my Oregonian habits: I have become used
to pumping my own gas. I have become used to paying sales tax. I haven't been to
Powell's in years. I no longer consider an outdoor temperature of 35°F to be
&quot;cold&quot;, or three inches of snow &quot;excessive&quot;. I don't feel like I'm losing money
whenever I put a pop can in a recycling bin.</p>
<p>But I still prefer to vote early rather than at a polling place on Election Day.</p>
<p>In November 1998—weeks before my 18th birthday—Oregonians passed a
citizen initiative which eliminated polling places and switched the state to
all-mail balloting. Under this system, each Oregon voter receives a ballot in
the mail weeks before Election Day, fills out the ballot out at home (or at a
microbrewery, or wherever), and then returns the ballot to elections officials.
To be counted, the ballot must be received by a certain time on the evening of
Election Day. A voter has the option of mailing back their completed ballot (in
which case, they must send it early enough to arrive at the elections office by
Election Day, as postmarks do not count). A voter may also return their ballot
to an official drop box (located at many public places, such libraries).
Sometimes, campaign workers or volunteers will offer to collect and return
ballots for their supporters. My preferred method was to use an official drop
box.</p>
<figure>
<img src="/tasty_ballot.jpg" alt="A 27-year-old man licking a mail envelope" 
width="800" height="600">
<figcaption>
Licking the return envelope for my 2008 primary ballot. Yes, I filled out the
spot for the return address despite using a drop box, rather than the mail.
</figcaption>
</figure>
<figure>
<img src="/ballot_drop_box.jpg" alt="A box looks like a U.S. mailbox except it's painted white and has
prominent lock." width="800" height="600" />
<figcaption>
An official Lane County, Oregon ballot drop box, located on the University of Oregon
campus, in 2008.
</figcaption>
</figure>
<p>My first election living outside Oregon was in the spring of 2010. For that
election, I was living overseas and hence voted absentee. (I remember mailing my
absentee ballot from a British Post Office.) It wasn't until November
2010—weeks before my 30th birthday—that I first voted at a polling
place on Election Day. At the time, I was living in Pennsylvania, which did not
have no-excuse absentee voting at the time. Although it was not inconvenient (my
polling place was located at the university where I worked at the time, and the
line was not very long), I did not really enjoy having to block out time on a
specific day to vote.</p>
<p>Before March 3 of this year, my last time voting at a polling place on Election
Day was for the 2012 General Election, a few months after my wife and I had
moved to Minnesota. In that election, voters put the Minnesota
Democratic-Farmer-Labor (DFL) Party in control of both chambers of the Minnesota
Legislature, The next year, the DFL-controlled legislature passed a law bringing
no-excuse absentee voting to Minnesota, which was subsequently signed by
then-Gov. Mark Dayton, also a DFLer.</p>
<p>This law brought the kind of voting I was used to—and prefer—to the
state I have made my home. For every election between the 2012 General Election
and this year's presidential primary, I have voted early in every election.
Sometimes I request a ballot to be mailed to my house, but more often I just go
to my county auditor-treasurer's office and vote early in person. (I have signed
up for a mail ballot this year.)</p>
<p>(It should be noted that some rural precincts in Minnesota conduct their
elections like Oregon, <a href="https://www.sos.state.mn.us/elections-voting/other-ways-to-vote/cities-and-towns-that-vote-by-mail/">having everyone vote by mail rather than operating
polling
places</a>.)</p>
<figure>
<img src="/2020_primary_ballot.jpg"
alt="An unmarked 2020 Minnesota DFL Party presidential primary ballot."
height="800" width="700" />
<figcaption>My 2020 presidential primary ballot, on the table inside a voting booth, moments before I marked it.</figcaption>
</figure>
<p>I did vote at my polling place on March 3 (which seems like <em>years</em> ago), in Minnesota's Super Tuesday presidential primary. The presidential race was very fluid this year, and I was worried that my preferred candidate could drop out right before Super Tuesday. (That did not happen, but my concern was <em>not</em> un<u>warren</u>ted, given that two other candidates did drop out within days of the vote.) So, I waited until Election Day to vote. As I have encouraged countless voters while door-knocking on behalf of DFL candidates, I made a voting plan, blocking out a specific time in my calendar to go to my polling place (the location of which I confirmed at <a href="https://mnvotes.org/">mnvotes.org</a>) and cast my ballot. And I did.</p>
<p>But most elections are not that fluid, and I typically know how I am going to vote weeks before Election Day. So, I vote early. (Campaigns like it when you vote early, because they know that you will turn out, and they don't have to use volunteer time and energy to contact you and remind you to vote.) It's possible that many people will be voting early for the first time this fall.</p>]]></content:encoded></item><item><title>Giving up Celsius</title><link>https:://chrisphan.com/posts/2020-04-20-giving-up-celsius/index.html</link><description><![CDATA[ When I was in elementary school, I came across a series of books in the school library about the metric system. I don't remember the]]></description><guid>https:://chrisphan.com/posts/2020-04-20-giving-up-celsius/index.html</guid><pubDate>Mon, 20 Apr 2020 14:12:00 -0500</pubDate><content:encoded><![CDATA[
<p>When I was in elementary school, I came across a series of books in the school library about the metric system. I don't remember the title or the author, but I do remember reading each of them and falling in love with the measurement system used by almost every country in the world other than my own. The advantages of the metric system, especially ease of conversion between units, are well-known, and I won't belabor them here. Let's just say (and this will not come as a surprise to those who know me well) I became a passionate fan of the metric system from a young age.<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup></p>
<p>That said, I have always felt that the metric unit with the weakest case is degrees Celsius.<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup> Yes, it's nice that water freezes and boils at 0 and 100, rather than 32 and 212, but frankly it's really not that hard to remember the numbers 32 and 212. The biggest advantage of the metric system, ease of conversion, really does not apply to temperature. It's a pain to remember that there are 5,280 feet in a mile or that there's 128 fluid ounces in a gallon<sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup>, compared to remembering that there are 1,000 meters in a kilometer or 1,000 milliliters in a liter, but we don't have to convert degrees Fahrenheit into any smaller or bigger units.</p>
<p><img src="/thermometer.jpg" alt="A thermometer reads 4 degrees Celsius and 40 degrees Fahrenheit." /></p>
<p>Some passionate advocates of the Fahrenheit scale will point out that the scale is more granular, allowing finer measurements for the air temperatures encountered in everyday life. For example, the National Weather Service <a href="https://www.wpc.ncep.noaa.gov/archives/web_pages/discussions/archive_nathilo.php?adate=12/25/2019&amp;sdate=20191225">reports</a> that the warmest high temperature in the contiguous United States on Christmas was 84°F in Falfurrias, Texas, and the lowest low temperature was -13°F in Copper Basin, Idaho, a difference of 97 Fahrenheit degrees. In Celsius, those temperatures would be reported as 29°C and -25°C, for a range of 54 Celsius degrees. Frankly, I think not a very strong argument, in terms of everday applications such as weather or cooking: most people can hardly detect a 1 Fahrenheit degree difference in air temperature, and most ovens are not so precisely calibrated. In these cases, the increased granularity of Fahrenheit is unnecessary.</p>
<p>By far the strongest argument for America adopting Celsius is its universality outside the U.S. Standardization of units makes commerce and communication between nations easier.</p>
<hr />
<p>After earning my PhD in mathematics in June 2009, my first job was a short stint as an adjunct instructor at a culinary school, where I taught my students (among other things) how to convert between different customary units as well as between customary and metric. My second job was as a temporary lecturer for an academic year at an ancient university<sup class="footnote-ref"><a href="#fn-4" id="fnref-4" data-footnote-ref>4</a></sup> in Scotland. In the U.K., my dream of a Celsius life came true, as weather reports were given in that scale. (On the other hand, speed limits, driving distances, and the volume of beer sold in pubs, are still given Imperial<sup class="footnote-ref"><a href="#fn-5" id="fnref-5" data-footnote-ref>5</a></sup> units.) Upon repatriation, I was getting most of my weather information from the Internet, and I realized I could set website an weather apps to Celsius, allowing me to continue my Celsius paradise in America.</p>
<p>However, my own private Celsius paradise couldn't last. Some cracks developed:</p>
<p>While I could set apps and websites to report temperatures in Celsius, the thermometer and thermostat in our car, the thermostat in our house, and the dial on our oven (as well as the American cookbooks we use) give temperatures in Fahrenheit. (I could configure my home thermostat to use Celsius, but when your spouse does not share your metric fanaticism, consideration requires your home thermostat to remain set for American units.)</p>
<p>Then there’s the fact that I now live in Minnesota, a place with serious weather and hence frequent weather-related conversations. Several times a week, I read <a href="https://www.mprnews.org/weather-and-climate/updraft">the Updraft blog</a>, which provides detailed discussions of weather forecasts, weather records, and comparisons of different weather computer models (and gives temperatures in Fahrenheit). I consult the weather report before getting dressed, to determine if I want to wear (depending on the season) long underwear, a sweater, short sleeves, pants, or shorts. I am often talking about the weather with other Minnesotans, and of course those conversations use Fahrenheit.</p>
<p>But the biggest problem with operating in Celsius was that I was not developing a Fahrenheit intuition for cold temperatures. I spent the first 28 years of my life living in temperate places: just outside of the Portland metro area, inside the Portland metro area, and in Eugene. Usually, the temperature stayed above 30°F, and so I developed a Fahrenheit intuition for temperatures above 30°F. Later, living in Scotland (also a relatively temperate place) allowed me to develop a Celsius intuition for the same range of temperatures. But Minnesota experiences much, much colder temperatures, <a href="https://chrisphan.com/posts/2019-06-03-palaces-for-the-people/">sometimes down to -31°F or -35°C</a>, and in my Celsius paradise I was only developing a Celsius intuition for winter temperatures. I was developing Celsius-based heuristics, such as not wearing long underwear or fleece-lined pants unless the temperature was below -15°C (5°F). When someone told me that the high temperature was going to be 10°F, I would have to make the conversion to Celsius in my head.</p>
<p>It turns out, for the same reasons that a nation should adopt the same units of measurement as the other nations in the global community, an individual should probably use the same units of measurements as the other individuals in their community. As most of my weather conversations are with other Americans, who think and use Fahrenheit, it makes sense for me to do so as well.</p>
<p>But I'm still not going to change the navigation app on my phone to miles.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>While I would still consider myself a metrication advocate, it's safe to say that metrication is very far from my highest priority, politically. Besides, <a href="https://www.npr.org/2020/03/05/812634551/the-u-s-doesnt-use-the-metric-system-or-does-it">it's happening slowly anyway</a>. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>Yes, technically, the SI unit for temperature is Kelvin, but that's just Celsius shifted by 273.15 degrees. <a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a></p>
</li>
<li id="fn-3">
<p>As an aside, I recently realized that the secret to remembering the U.S. customary liquid volume measures is to memorize the following list: 1 1/2 teaspoons, tablespoon, fluid ounce, 1/4 cup, 1/2 cup, cup, pint, quart, 1/2 gallon, gallon. In this list, each measurement is twice the size of the previous measurement. <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
<li id="fn-4">
<p>That is to say, one founded before 1600. <a href="#fnref-4" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="4" aria-label="Back to reference 4">↩</a></p>
</li>
<li id="fn-5">
<p>While they have much in common, U.K. Imperial system and U.S. customary system are different systems, with different volume units. For example, Imperial pints are 568 mL, while customary pints are 473 mL. <a href="#fnref-5" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="5" aria-label="Back to reference 5">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>Bugs in the iOS calendar app</title><link>https:://chrisphan.com/posts/2020-04-06_bug_in_ios_calendar/index.html</link><description><![CDATA[ Stand-up mathematician[^1] Matt Parker found some interesting bugs in the iOS calendar app: I encourage you to watch the video, but the short summary is]]></description><guid>https:://chrisphan.com/posts/2020-04-06_bug_in_ios_calendar/index.html</guid><pubDate>Mon, 6 Apr 2020 14:58:00 -0500</pubDate><content:encoded><![CDATA[
<p>Stand-up mathematician<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup> Matt Parker found some interesting bugs in the iOS calendar app:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/ER1a6jgW1Gs" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>I encourage you to watch the video, but the short summary is that if you scroll
back far enough (centuries) in the year view of the iOS Calendar app, the year
labels and some months disappear. I reproduced this bug on my iPhone:</p>
<figure>
<img src="/ios_cal_bug1.jpg" width="331" height="717" alt="Screenshot of iOS
calendar app, showing the year view for the year 1582. Several months are
missing." />
<figcaption>My iPhone's calendar app year view for 1582 is messed up.</figcaption>
</figure>
<p>I don't really believe Parker's suggested explanation for this bug, although to
be fair, I don't think he really does, either. It should be noted that 1582 (the
year where my iPhone first shows this problem) is the year that the Gregorian
calendar was introduced.<sup class="footnote-ref"><a href="#fn-2" id="fnref-2" data-footnote-ref>2</a></sup></p>
<p>Speaking of the Gregorian calendar, while trying to reproduce Parker's bug, I
found another bug. Check out the year view for 1900:</p>
<figure>
<img src="/ios_cal_bug2.jpg" width="331" height="717" alt="Screenshot of iOS
calendar app, showing the year view for the year 1900. February has 29 days, the
last of which is the same day of the week as the first of March." />
<figcaption>My iPhone's calendar app year view for 1900</figcaption>
</figure>
<p>Notice two things:</p>
<ul>
<li>February is shown as having 29 days.</li>
<li>March 1 and the nonexistent February 29 are both shown as being Thursdays.</li>
</ul>
<p>When you zoom in to February 1900, it shows that month correctly as having only 28 days.<sup class="footnote-ref"><a href="#fn-3" id="fnref-3" data-footnote-ref>3</a></sup></p>
<figure>
<img src="/ios_cal_bug3.jpg" width="331" height="717" alt="Screenshot of iOS
calendar app, showing the month view for the February 1900, with 28 days." />
<figcaption>My iPhone's calendar app month view for February 1900</figcaption>
</figure>
<p>However, the year view for 2100 shows the correct number of days for February 2100.</p>
<figure>
<img src="/ios_cal_bug4.jpg" width="331" height="717" alt="Screenshot of iOS
calendar app, showing the year view for the year 2100." />
<figcaption>My iPhone's calendar app year view for 2100</figcaption>
</figure>
<p>In terms of severity, these bugs are extremely minor. Very few people are using
their iPhones to view calendar events in the 16th century, or indeed probably
before the 1990s.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>Coolest job description <em>EVER</em>! <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
<li id="fn-2">
<p>Although different countries adopted the Gregorian calendar in different years.</p>
<p>For example, Great Britain and its colonies adopted the Gregorian calendar in September 1752, by skipping 11 days of that month. You can see this in many versions of the Unix <code>cal</code> command-line utility, including the one on my MacBook:</p>
<pre style="background-color:#002b36;"><code><span style="color:#839496;">Christophers-MacBook-Pro:~ chris$ cal 9 1752
</span><span style="color:#839496;">   September 1752
</span><span style="color:#839496;">Su Mo Tu We Th Fr Sa
</span><span style="color:#839496;">       1  2 14 15 16
</span><span style="color:#839496;">17 18 19 20 21 22 23
</span><span style="color:#839496;">24 25 26 27 28 29 30
</span></code></pre>
<a href="#fnref-2" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="2" aria-label="Back to reference 2">↩</a>
</li>
<li id="fn-3">
<p>If you are feeling confused, remember that in the Gregorian calendar years that are divisible by 100 are <em>not</em> leap years, unless they are also divisible by 400. For example, 1800 and 1900 were not leap years, 2100 will not be a leap year, but 2000 was a leap year. The means if you were born in the 20th century, every year divisible by 4 in your lifetime will probably be a leap year, just like it would have been under the previous Julian calendar. <a href="#fnref-3" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="3" aria-label="Back to reference 3">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>Repository of files related to the NYT COVID-19 dataset</title><link>https:://chrisphan.com/posts/2020-04-04-nyt-covid-data-repo/index.html</link><description><![CDATA[ I've created a GitHub repository based on the New York Times ' COVID-19 database. The New York Times has been compiling COVID-19 data from various]]></description><guid>https:://chrisphan.com/posts/2020-04-04-nyt-covid-data-repo/index.html</guid><pubDate>Sat, 4 Apr 2020 23:36:00 -0500</pubDate><content:encoded><![CDATA[
<p>I've created <a href="https://github.com/christopherphan/COVID-19-analysis">a GitHub repository</a> based on the <em>New York Times</em>' COVID-19 database.</p>
<p>The <em>New York Times</em> has been compiling COVID-19 data from various state health departments. They have published the data as <a href="https://github.com/nytimes/covid-19-data">a GitHub repository</a>. There are two files of interest in their repository: <a href="https://github.com/nytimes/covid-19-data/blob/master/us-states.csv"><code>us-states.csv</code></a> and <a href="https://github.com/nytimes/covid-19-data/blob/master/us-counties.csv"><code>us-counties.csv</code></a>.</p>
<p>In these CSV files, each row represents the number of (confirmed) cases and deaths in a particular geographical area as of a particular date. For example, the first ten rows of <code>us-states.csv</code> are:</p><div class="code_block"><div class="code-header"><span class="filename">us-states.csv</span> </div><pre class=""  id="block-e8cfcefc-9b9a-4eb2-bbee-6395a4d99855"><code><code class="checker lineno dig-1"><span style="color:#839496;">date,state,fips,cases,deaths</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-21,Washington,53,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-22,Washington,53,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-23,Washington,53,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-24,Illinois,17,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-24,Washington,53,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-25,California,06,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-25,Illinois,17,1,0</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">2020-01-25,Washington,53,1,0</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">2020-01-26,Arizona,04,1,0</span></code>
<code class="code-elipsis" id="block-e8cfcefc-9b9a-4eb2-bbee-6395a4d99855-elipsis-end"></code>
</code></pre></div>
<p>These are easy enough to analyze using a tool like <a href="https://pandas.pydata.org/">Pandas</a>. However, this kind of file might be hard to analyze if you want to use a spreadsheet program.</p>
<p>So, I wrote a Python script that uses Pandas to output a bunch of CSV files, so people can analyze the data using spreadsheet software. The script also creates a bunch of plots, including one for each state.</p>
<p>The script and all the output are available in <a href="https://github.com/christopherphan/COVID-19-analysis">my new repo</a>. I have licensed the script under an MIT-style license. Feel free to fork and improve! (The outputs of the script I haven't so licensed since they are subject to the license restrictions imposed by the <em>Times</em>.)</p>
<p>A big disclaimer: I'm not an epidemiologist (my expertise being in noncommutative algebra, not communicable disease). So, please don't make any policy decisions based on my plots or any other amateurs who don't know what they are doing.</p>
<p>Stay safe and healthy!</p>
<figure>
<img src="/nyt_cases_and_deaths.png" width="900" height="600" alt="Plot of U.S.
COVID cases and deaths on a log scale. Both are increasing at a steady rate,
with deaths following cases by about 1.5 months." />
<figcaption>U.S. COVID-19 cases and deaths, based on data from the New York Times</figcaption>
</figure>]]></content:encoded></item><item><title>What I believe</title><link>https:://chrisphan.com/posts/2019-10-11-what-i-believe/index.html</link><description><![CDATA[ I strongly believe: Diversity enriches a society. Immigrants enrich a society. Minnesota is a better state because of the refugees who have made it their]]></description><guid>https:://chrisphan.com/posts/2019-10-11-what-i-believe/index.html</guid><pubDate>Fri, 11 Oct 2019 12:31:28 -0500</pubDate><content:encoded><![CDATA[
<p>I strongly believe:</p>
<ul>
<li>Diversity enriches a society.</li>
<li>Immigrants enrich a society.</li>
<li>Minnesota is a better state because of the refugees who have made it their home.</li>
<li>The Somali community's presence in Minnesota is worth celebrating.</li>
<li>The ideologies that pose the greatest danger to America are white nationalism and toxic masculinity.</li>
<li>Anyone who seeks political power by demonizing immigrants and minorities is not fit to hold office.</li>
</ul>]]></content:encoded></item><item><title>Book recommendation: Palaces for the people</title><link>https:://chrisphan.com/posts/2019-06-03-palaces-for-the-people/index.html</link><description><![CDATA[ A small portion of a weather map reporting a temperature of -31 degrees in Winona In Palaces for the People: How Social Infrastructure Can Help]]></description><guid>https:://chrisphan.com/posts/2019-06-03-palaces-for-the-people/index.html</guid><pubDate>Mon, 3 Jun 2019 13:10:00 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://chrisphan.com/images/nws_temps.png" alt="A small portion of a weather map reporting a temperature of -31 degrees in Winona" /></p>
<p>In <a href="https://www.ericklinenberg.com/books#palaces-for-the-people-how-social-infrastructure-can-help-fight-inequality-polarization-and-the-decline-of-civic-life"><cite>Palaces for the People: How Social Infrastructure Can Help Fight Inequality, Polarization, and the Decline of Civic Life</cite></a>, sociologist Eric Klinenberg discusses the role of social infrastructure in maintaining the health of a community and its people. Klinenberg argues that well-designed social infrastructure can help reduce crime, improve people's lives, bring different people into contact with one-another, and even protect lives during natural disasters. He examines a variety of social infrastructures, including libraries, public housing courtyards, schools, barbershops, bookstores, and community gardens. For example, he explains that when abandoned inner-city lots are turned into community gardens, crime is reduced, which also decreases the stress felt by residents. He explains how having common meeting spaces also decrease political polarization.</p>
<p>I first learned about this book from <a href="https://99percentinvisible.org/episode/palaces-for-the-people/">an episode of the podcast <cite>99% Invisible</cite></a>. That episode serves as a good executive summary of the book, and I would recommend it also.</p>
<p>This book made me more grateful for the social infrastructure present in Winona, Minnesota, the charming college town on the Mississippi River where I make my home. Occasionally, while reading Klinenberg's examples of the benefits of robust social infrastructure in various communities, I would find comparable examples in my own community.</p>
<p>For example, Klinenberg became interested in the concept of social infrastructure when he was a graduate student studying a deadly 1995 heat wave in Chicago. He learned that robust social infrastructure in a neighborhood could prevent people from dying in the heat.</p>
<p>As I read this story, I thought about something that happened in my town during the <a href="https://www.weather.gov/arx/jan3019">brutal cold snap</a> we experienced in late January, when nighttime temperatures in Winona plunged as low as -31°F (-35°C), and even daytime temperatures were dangerous. To keep Winona's homeless population safe at night, there is <a href="https://www.ccsomn.org/programs/winona-community-warming-center/">a volunteer-run warming center</a> in a church basement during the winter months, open every evening between 9 p.m. and 7 a.m. During the cold snap, <a href="https://www.winonadailynews.com/opinion/editorial/our-view-william-h-laird-would-be-proud-as-are/article_c070520c-3286-5424-b886-383ea4d8e035.html">the director of our public library decided to keep the library open late</a>, until the warming center opened, so that homeless people wouldn't have to wait outside in the dangerous cold. Local businesses donated food, and the city's fire department gave rides from the library to the warming center at 9 p.m. The library and warming center are a vital part of my town's social infrastructure that kept people safe.</p>
<p>Klinenberg also explains how physical infrastructure can be designed in a such way to double as social infrastructure. For example, he talks about how the physical measures to control flooding (which will become increasingly important with climate change) can be designed to function as community spaces. In my town, <a href="/posts/2019-05-11-view-of-mississippi-from-levee-park/">the levee that protects us from the Mississippi's floods also functions as a park</a>. Indeed, Levee Park was recently redesigned to create an even more inviting space for gatherings, such as the farmer's market where my family buys fresh produce in the summer.</p>
<p>Finally, understanding the importance of social infrastructure reaffirms the importance of state and local government. Our political attention is often focused on national politics, especially presidential elections. Of course, presidential elections are very important, and people should pay attention to them, but state and local government are very important, too, and often do not get enough attention. (This is not helped by the recent business difficulties of many communities' local media, who traditionally took on the responsibility of informing citizens about their local government.) Decisions by your state legislature and local government have a large impact on the quality of social infrastructure in your community. They are the ones deciding how much funding should go to parks and libraries, and those decisions have a large impact on the health of communities.</p>
<p>(Image above: Low temperatures on the evening of January 31, 2019, <a href="https://www.weather.gov/arx/jan3019">as reported by the National Weather Service</a>)</p>]]></content:encoded></item><item><title>Consequences of YouTube&apos;s algorithm</title><link>https:://chrisphan.com/posts/2019-05-30-youtubes-algorithm/index.html</link><description><![CDATA[ As a follow-up to the previous post , consider this video by science educator Derek Muller, recently posted to his YouTube channel Veritasium : In]]></description><guid>https:://chrisphan.com/posts/2019-05-30-youtubes-algorithm/index.html</guid><pubDate>Thu, 30 May 2019 11:03:00 -0500</pubDate><content:encoded><![CDATA[
<p>As a follow-up to the <a href="/posts/2019-05-16-life-in-the-time-of-paperclip-maximizers/">previous post</a>, consider <a href="https://youtu.be/fHsa9DqmId8">this video</a> by science educator Derek Muller, recently posted to his YouTube channel <a href="https://www.youtube.com/veritasium"><cite>Veritasium</cite></a>:</p>
<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/fHsa9DqmId8" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>In the video, Muller explains why he thinks <a href="https://youtu.be/uxPdPpi5W4o">a previous video</a>, about the use of shade balls in a Los Angeles-area reservoir, went viral. Basically, he explains, when deciding which videos to promote, YouTube's algorithm seems to be attempting to maximize two outcomes:</p>
<ul>
<li><strong>Watch time</strong>: How long the user will spend watching the video</li>
<li><strong>Click-through rate</strong>: How likely the user will click that particular thumbnail when it's displayed</li>
</ul>
<p>As a result, Muller says that going forward, he will:</p>
<ol>
<li>&quot;Keep making high-quality videos&quot;</li>
<li>&quot;Choose topics that are more clickable&quot;</li>
<li>&quot;Use clickbaity titles and thumbnails&quot;</li>
</ol>
<blockquote>
<p>Because, frankly, if I'm going to work for days and weeks and months on a video, I would like that video to get, say, 10 million views instead of half-a-million.</p>
</blockquote>
<p>Now, my heart sunk a little when I first watched this video, because I have very much enjoyed Muller's previous videos, and I am not a big fan of clickbait. In the past, some of his topics haven't been as &quot;clickable&quot; but were very interesting (to me) nonetheless. But <em>I absolutely cannot fault him</em>, either, since part of his livelihood depends on people continuing to watch his videos.<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup></p>
<p>On a related note, recently on YouTube, I have noticed a trend to longer videos, a trend driven by the algorithm's favoring of videos with longer watch time. I find this a bit unfortunate, because short YouTube videos are great for taking a short break from work, and because longer videos require a larger investment of time. I'm reluctant to watch a video that's over 10 minutes, unless the video comes highly recommended or the creator has made content I've enjoyed before.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>For that matter, I absolutely don't fault news outlets for posting clickbait, either, given the changes to the media landscape wrought by the Internet in general and social media in particular. <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>Life in the time of paperclip maximizers</title><link>https:://chrisphan.com/posts/2019-05-16-life-in-the-time-of-paperclip-maximizers/index.html</link><description><![CDATA[ pile of paperclips In an influential 2003 essay , philosopher Nick Bostrom explored the ethical implications of developing a "superintelligence", that is, an "intellect that]]></description><guid>https:://chrisphan.com/posts/2019-05-16-life-in-the-time-of-paperclip-maximizers/index.html</guid><pubDate>Thu, 16 May 2019 10:08:00 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/flickr_photos/paperclips.jpg" alt="pile of paperclips" /></p>
<p>In <a href="https://nickbostrom.com/ethics/ai.html">an influential 2003 essay</a>, philosopher Nick Bostrom explored the ethical implications of developing a &quot;superintelligence&quot;, that is, an &quot;intellect that is vastly outperforms the best human brains in practically every field, including scientific creativity, general wisdom, and social skills.&quot; He argued that any such intelligence should be given &quot;philanthropic values&quot;, and designed to be ultimately motivated with improving human lives. Without such a &quot;supergoal of philanthropy&quot;, a superintelligence could be dangerous. For example, Bostrom imagines a powerful artificial intelligence that was tasked with making as many paperclips as possible, &quot;with the [unintended] consequence that it starts transforming first all of earth and then increasing portions of space into paperclip manufacturing facilities.&quot;</p>
<p>A similar example was given by Rob Miles in <a href="https://www.youtube.com/watch?v=tcdVC4e6EV4">a <cite>Computerphile</cite> video</a>. Instead of being asked to make paperclips, Miles imagines a superintelligent machine tasked with an ultimate goal of collecting stamps. The machine's designer imagines that the machine would buy stamps from eBay, but instead the machine starts finding unforeseen ways to accumulate stamps, ways that are creative yet extremely undesirable. The machine starts by fraudulently convincing stamp collectors to send it their collections, and the undesirability of the tactics escalate from there:</p>
<blockquote>
<p>There comes a point when the stamp-collecting device is thinking [. . .] &quot;Paper is made of carbon and hydrogen and oxygen. I'm gonna need all of that I can get to make stamps.&quot; And it's gonna notice that people are made of carbon, hydrogen, and oxygen, right?</p>
<p>There comes a point where the stamp collecting device becomes extremely dangerous and that point is as soon as you switch it on.</p>
</blockquote>
<p>We're probably a long way from being able to create the kind of superintelligence envisioned by Bostrom and Miles in their thought experiments. Compared to the hypothetical superintelligences envisioned by above, today's nascent artificial intelligences are rather rudimentary and are far from having the capacity to even understand &quot;philanthropic values&quot;. But it's becoming increasingly clear that even rudimentary AIs can pose risks to our well-being and society when tasked with maximizing some outcome.</p>
<p>I have been a social media user for a long time. In 2001, I joined LiveJournal, a blogging platform that was also one of the first social media sites. One of LiveJournal's great innovations, <a href="/2013/09/12/facebooks-news-feed-was-not-a-novel-idea/">sometimes mistakenly credited to Mark Zuckerberg and friends</a>, was the &quot;friends page&quot;, which displayed your &quot;friends'&quot; posts in reverse-chronological order.</p>
<p>LiveJournal is still around, but it never achieved the same market penetration as Facebook. Today's top services, such as Facebook and YouTube, now use computer programs to determine what shows up in your feed, and in what order, rather than just showing you posts in reverse-chronological order. These programs are designed to maximize &quot;engagement&quot;, that is, how much time you spend on their sites (and hence how many ad impressions they can sell). These computer programs are based on machine learning, meaning that rather than having a human programer using human judgment to determine how to choose what content is shown, the computer chooses based on what content has lead to the most engagement in the past. Unfortunately, the most engaging content (and hence shown by an algorithm trying to maximize engagement) is often content that is extremist, misleading, or polarizing.</p>
<p>One of the first to raise the alarm was sociologist Zeynep Tufekci. Her TED talk <a href="https://www.ted.com/talks/zeynep_tufekci_we_re_building_a_dystopia_just_to_make_people_click_on_ads/">&quot;We're building a dystopia just to make people click on ads&quot;</a> is required viewing for anyone who uses these services (or cares about the future of society).</p>
<blockquote>
<p>So in 2016, I attended rallies of then-candidate Donald Trump to study as a scholar the movement supporting him. I study social movements, so I was studying it, too. And then I wanted to write something about one of his rallies, so I watched it a few times on YouTube. YouTube started recommending to me and autoplaying to me white supremacist videos in increasing order of extremism. If I watched one, it served up one even more extreme and autoplayed that one, too. If you watch Hillary Clinton or Bernie Sanders content, YouTube recommends and autoplays conspiracy left, and it goes downhill from there.</p>
<p>Well, you might be thinking, this is politics, but it's not. This isn't about politics. This is just the algorithm figuring out human behavior. I once watched a video about vegetarianism on YouTube and YouTube recommended and autoplayed a video about being vegan. It's like you're never hardcore enough for YouTube.</p>
</blockquote>
<p>Since then, many others have joined in sounding this alarm. <a href="https://www.vox.com/policy-and-politics/2018/3/21/17144748/case-against-facebook">In April 2018, Matt Yglesias wrote</a>:</p>
<blockquote>
<p>The association between Facebook and fake news is by now well-known, but the stark facts are worth repeating — according to Craig Silverman’s path-breaking analysis for BuzzFeed, the <a href="https://www.buzzfeednews.com/article/craigsilverman/viral-fake-election-news-outperformed-real-news-on-facebook">20 highest-performing fake news stories of the closing days of the 2016 campaign did better on Facebook</a> than the 20 highest-performing real ones.</p>
<p>Rumors, misinformation, and bad reporting can and do exist in any medium. But Facebook created a medium that is optimized for fakeness, not as an algorithmic quirk but due to the core conception of the platform. By turning news consumption and news discovery into a performative social process, Facebook turns itself into a confirmation bias machine — a machine that can best be fed through deliberate engineering. [. . .] Facebook’s imperative to maximize engagement [. . .] lands it in an endless cycle of sensationalism and nonsense.</p>
</blockquote>
<p>To be clear, I'm not suggesting that these companies are deliberately promoting extremism or misinformation. It's probably an emergent property of the machine-learning algorithms that use trial and error to maximize users' engagement. It's an unintended side-effect, like the homicidal actions of Miles' hypothetical stamp-collecting machine.</p>
<p>But the probably inadvertent promotion of inaccurate information and extremism isn't the only problem with Facebook's engagement-maximizing algorithms. A bigger issue, to me, is that you have a nascent artificial intelligence trying to get you to waste more time on their web site, distracting you from other priorities. Just like Rob Miles' hypothetical stamp-collecting machine ends up trying to turn all available hydrocarbons into stamps, the computer programs used by social media companies try to convert as many of our waking hours at they can into time spent on their sites. Even the co-founder of Facebook <a href="https://www.nytimes.com/2019/05/09/opinion/sunday/chris-hughes-facebook-zuckerberg.html">has come to see the danger of this</a>:</p>
<blockquote>
<p>I was on the original News Feed team (my name is on the patent), and that product now gets billions of hours of attention and pulls in unknowable amounts of data each year. The average Facebook user spends an hour a day on the platform; Instagram users spend 53 minutes a day scrolling through pictures and videos. They create immense amounts of data — not just likes and dislikes, but how many seconds they watch a particular video — that Facebook uses to refine its targeted advertising. Facebook also collects data from partner companies and apps, without most users knowing about it, according to testing by The Wall Street Journal.</p>
<p>Some days, lying on the floor next to my 1-year-old son as he plays with his dinosaurs, I catch myself scrolling through Instagram, waiting to see if the next image will be more beautiful than the last. What am I doing? I know it’s not good for me, or for my son, and yet I do it anyway.</p>
<p>The choice is mine, but it doesn’t feel like a choice. Facebook seeps into every corner of our lives to capture as much of our attention and data as possible and, without any alternative, we make the trade.</p>
</blockquote>
<p>What can we do to counteract these effects? I'm not sure, to be honest. But one small step I've taken, in the wake of the 2016 election, is to take back control of what I read. Instead of waiting for people to post content on Facebook, I actively seek it out, visiting a variety of news sites and reading the physical newspaper. I've also started using an RSS reader again: I read things from my feed when I have a spare moment, and exhausting my feed is a good sign to quit surfing the Internet and re-engage with people who are physically proximate.</p>
<p>I also heartily recommend the book <a href="http://www.manoushz.com/book"><cite>Bored and Brilliant: How Spacing Out Can Unlock Your Most Productive and Creative Self</cite> by Manoush Zomorodi</a>.</p>]]></content:encoded></item><item><title>Plotting with TikZ, Part III: Plotting a function defined by a formula, and plotting functions that go through certain points</title><link>https:://chrisphan.com/posts/2019-05-13-plotting_with_tikz_3/index.html</link><description><![CDATA[ In the last post , I described how I use Ti k Z to create a graph that might otherwise be created freehand: A plot]]></description><guid>https:://chrisphan.com/posts/2019-05-13-plotting_with_tikz_3/index.html</guid><pubDate>Mon, 13 May 2019 15:41:00 -0500</pubDate><content:encoded><![CDATA[
<p><a href="posts/2019-05-07-plotting_with_tikz_2/">In the last post</a>, I described how I use Ti<i>k</i>Z to create a graph that might otherwise be created freehand:</p>
<p><img src="/tikz_2019-05_img/example2.png" alt="A plot of a real-valued function on the real numbers inclusively between -5 and 5, with the exception of -2. The function is continuous except that there is a removable discontinuity, a vertical asymptote, and a jump discontinuity" /></p>
<p>In this post, I will describe one method for using Ti<i>k</i>Z to to plot a function defined by a formula, such as
\[y = \left(2x^2 - x - 1\right)e^{-x}.\]
Then I will show two ways to make a function go through a certain point.</p>
<h1>Plotting from a formula</h1>
<h2>Simple example</h2>
<p>There are a number of ways to achieve this, and PGF actually includes the functionality to perform calculations in TeX. (For example, <a href="/2018/05/28/10-print-in-tikz/">I have used the PGF pseudorandom number generator in graphics</a>. Someone even made Ti<i>k</i>Z code to <a href="http://www.texample.net/tikz/examples/city/">generate a random city skyline</a>.) However, for efficiency sake, I prefer to have the calculations done outside TeX, in a more efficient computer language.</p>
<p>The trick is to use the <code>gnuplot</code> table import format. You simply have to generate a text file with a list of coordinates in the following form:</p><div class="code_block"><pre class=""  id="block-3907f292-e0b1-44dd-84db-8debfa788809"><code><code class="checker "><span style="color:#839496;">-1.250000 11.779907</span></code>
<code class="checker "><span style="color:#839496;">-1.240000 11.456050</span></code>
<code class="checker "><span style="color:#839496;">-1.230000 11.138839</span></code>
</code></pre></div>
<p>This file contains the coordinates \((-1.25, 11.779907)\), \((-1.24, 11.456050)\), \((-1.23, 11.138839)\).</p>
<p>There are a number of ways to generate such a file. Since I like Python, I used the following (simple) Python script:</p><div class="code_block"><div class="code-header"><span class="code-lang">Python</span></div><pre class=""  id="block-7a687d8c-d608-4c95-8604-5418cf3f0625"><code class="language-python"><code class="checker lineno dig-1"><span style="color:#586e75;">#! /usr/bin/env python3</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">numpy </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">np</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">f </span><span style="color:#657b83;">= </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: (</span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">*</span><span style="color:#839496;">x</span><span style="color:#657b83;">**</span><span style="color:#6c71c4;">2 </span><span style="color:#657b83;">- </span><span style="color:#839496;">x </span><span style="color:#657b83;">- </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">)*</span><span style="color:#839496;">np.</span><span style="color:#b58900;">exp</span><span style="color:#657b83;">(-</span><span style="color:#839496;">x</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">xvals </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(-</span><span style="color:#6c71c4;">1.25</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">10.25</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.01</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">with open</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">plot1.table</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">wt</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">as </span><span style="color:#839496;">outfile</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">for </span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">xvals</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#cb4b16;">{:f} {:f}</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">x, </span><span style="color:#b58900;">f</span><span style="color:#657b83;">(</span><span style="color:#839496;">x</span><span style="color:#657b83;">)))</span></code>
</code></pre></div>
<p>Now, this curve can be imported into your Ti<i>k</i>Z illustration using <code>\draw</code> [. . .] <code>plot</code>; in this case:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-8d1934a2-ec8b-427c-9673-928ced445a97"><code class="language-latex"><code class="code-elipsis" id="block-8d1934a2-ec8b-427c-9673-928ced445a97-elipsis-start"></code>
<code class="checker "><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] plot[smooth] file {plot1.table};</span></code>
<code class="code-elipsis" id="block-8d1934a2-ec8b-427c-9673-928ced445a97-elipsis-end"></code>
</code></pre></div>
<p>Here is a complete example (with coordinate axes and everything):</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-b8657a51-d23a-44b1-99a0-996c64a5acb9"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[</span><span style="color:#268bd2;">border</span><span style="color:#839496;">=0.25cm]{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}[</span><span style="color:#268bd2;">yscale</span><span style="color:#839496;">=0.5]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[gray] (-1.25, -1.25) grid (10.25, 12.25);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">% x-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (-1.25, 0) -- (10.25, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=south west] {$</span><span style="color:#268bd2;">x</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">% x-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {-1, 10}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, 0.2) -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, -0.2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          node[anchor=north] {\(</span><span style="color:#859900;">\x</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">% y-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (0, -1.25) -- (0, 12.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=south west] {$</span><span style="color:#268bd2;">y</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">% y-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {-1, 12}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (-0.1, </span><span style="color:#859900;">\y</span><span style="color:#839496;">) -- (0.1, </span><span style="color:#859900;">\y</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          node[anchor=west] {\(</span><span style="color:#859900;">\y</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#586e75;">% graph of function</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] plot[smooth] file {plot1.table};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>And here is the output:</p>
<p><img src="/tikz_2019-05_img/example3.png" alt="plot of y = (2 x^2 - x - 1) e^(-x) from -1 to 10" /></p>
<p>In my Python script above, I carefully chose the set of inputs \(x\) (<code>np.arange(-1.25, 10.25, 0.01)</code>, i.e., every real number of the form \(-1.25 + 0.01k, \; k \in \mathbb{Z}\) in the interval \([-1.25, 10.25)\)) to keep \(f(x) &lt; 12\). This can also be handled computationally.</p>
<h2>Example involving asymptotes</h2>
<p>For example, suppose I want to plot \(y = r(x)\), where
\[r(x) = \frac{6x^3 + 21x^2 - 21x - 36}{3x^3 + 3x^2 - 12x - 12},\]
with \(-15.5 \leq x \leq 15.5\). Let's additionally suppose I want to only see \(y\)-values with \(-15.5 \leq y \leq 15.5\). (In other words, the &quot;viewing rectangle&quot; will be \([-15.5, 15.5] \times [-15.5, 15.5]\).)</p>
<p>Factoring the numerator and denominator, we have:</p>
<p>\[r(x) = \frac{6x^3 + 21x^2 - 21x - 36}{3x^3 + 3x^2 - 12x - 12}\]
\[\phantom{r(x)}= \frac{\left(x + 1\right) \left(2 x - 3\right) \left(3 x + 12\right)}{\left(x + 1\right) \left(x + 2\right) \left(3 x - 6\right)}\]
\[\phantom{r(x)}= \frac{\left(2 x - 3\right) \left(3 x + 12\right)}{\left(x + 2\right) \left(3 x - 6\right)}, \; x \not = -1.\]</p>
<p>As you can see, we will have vertical asymptotes at \(x = -2\) and \(x = 2\), and a hole at \(x = -1\). There will also be a horizontal asymptote at \(y = 2\).</p>
<p>To handle the asymptotes, we plot the function
\[\hat r(x) = \frac{\left(2 x - 3\right) \left(3 x + 12\right)}{\left(x + 2\right) \left(3 x - 6\right)}\]
along three intervals:</p>
<ul>
<li>\([-15.5, -2)\),</li>
<li>\((-2, 2)\), and</li>
<li>\((2, 15.5]\)</li>
</ul>
<p>(Actually, for each of the above intervals \(I\), we plot something approximating \(\left\{(x, \hat r(x)): x \in I \text{ and } |\hat r(x)|\leq 16\right\}\).)</p>
<p>Here is the Python script:</p><div class="code_block"><div class="code-header"><span class="code-lang">Python</span></div><pre class=""  id="block-b7a20ec1-f607-4513-bbdb-afaad5cb1e02"><code class="language-python"><code class="checker lineno dig-1"><span style="color:#586e75;">#! /usr/bin/env python3</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">numpy </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">np</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">r </span><span style="color:#657b83;">= </span><span style="color:#268bd2;">lambda x</span><span style="color:#657b83;">: (</span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">*</span><span style="color:#839496;">x </span><span style="color:#657b83;">- </span><span style="color:#6c71c4;">3</span><span style="color:#657b83;">)*(</span><span style="color:#6c71c4;">3</span><span style="color:#657b83;">*</span><span style="color:#839496;">x </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">12</span><span style="color:#657b83;">)/((</span><span style="color:#839496;">x </span><span style="color:#657b83;">+ </span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">)*(</span><span style="color:#6c71c4;">3</span><span style="color:#657b83;">*</span><span style="color:#839496;">x </span><span style="color:#657b83;">- </span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">))</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">xvals </span><span style="color:#657b83;">= [</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(-</span><span style="color:#6c71c4;">15.5</span><span style="color:#839496;">, </span><span style="color:#657b83;">-</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.01</span><span style="color:#657b83;">)</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(-</span><span style="color:#6c71c4;">2.01</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">2</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.01</span><span style="color:#657b83;">)</span><span style="color:#839496;">,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">2.01</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">15.6</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.01</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#657b83;">]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">for </span><span style="color:#839496;">idx, interval </span><span style="color:#859900;">in enumerate</span><span style="color:#657b83;">(</span><span style="color:#839496;">xvals</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">with open</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">plot2_</span><span style="color:#cb4b16;">{}</span><span style="color:#2aa198;">.table</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">idx</span><span style="color:#657b83;">)</span><span style="color:#839496;">, &quot;</span><span style="color:#2aa198;">wt</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">as </span><span style="color:#839496;">outfile</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">for </span><span style="color:#839496;">x </span><span style="color:#859900;">in </span><span style="color:#839496;">interval</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">            </span><span style="color:#859900;">if abs</span><span style="color:#657b83;">(</span><span style="color:#b58900;">r</span><span style="color:#657b83;">(</span><span style="color:#839496;">x</span><span style="color:#657b83;">)) &lt;= </span><span style="color:#6c71c4;">16</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">                outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#cb4b16;">{:f} {:f}</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">x, </span><span style="color:#b58900;">r</span><span style="color:#657b83;">(</span><span style="color:#839496;">x</span><span style="color:#657b83;">)))</span></code>
</code></pre></div>
<p>Here is the corresponding LaTeX code:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-f285e2d9-9037-430b-9369-113d9224d4f5"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[</span><span style="color:#268bd2;">border</span><span style="color:#839496;">=0.25cm]{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}[</span><span style="color:#268bd2;">scale</span><span style="color:#839496;">=0.5] </span><span style="color:#586e75;">% Scale keeps the graphic small</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[gray] (-15.5, -15.5) grid (15.5, 15.5);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (-15.5, 0) -- (15.5, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">x</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {-15, -10, -5, 5, 10, 15}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, 0.5) -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, -0.5)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=north] {\(</span><span style="color:#859900;">\x</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (0, -15.5) -- (0, 15.5)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">y</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {-15, -10, -5, 5, 10, 15}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (-0.5, </span><span style="color:#859900;">\y</span><span style="color:#839496;">) -- (0.5, </span><span style="color:#859900;">\y</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=west] {\(</span><span style="color:#859900;">\y</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% graph of function</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] plot[smooth] file {plot2_0.table};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] plot[smooth] file {plot2_1.table};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] plot[smooth] file {plot2_2.table};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% hole at (-1, 5)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=white] (-1, 5) circle (2.5mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% vertical asymptotes</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, dashed, red] (-2, -15.5) -- (-2, 15.5);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, dashed, red] (2, -15.5) -- (2, 15.5);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% horizontal asymptote</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, dashed, red] (-15.5, 2) -- (15.5, 2);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>And here is the result:</p>
<p><img src="/tikz_2019-05_img/example4.png" alt="a plot of the function. There is a horizontal asymptote at both ends at y = 2, and vertical asymptotes at x = -2 and x = 2" /></p>
<h1>Plotting functions that go through certain points: two ways</h1>
<p>Suppose I want to plot a function that go through certain points, say:</p>
<ul>
<li>\((-4, 2)\),</li>
<li>\((-1, 6)\),</li>
<li>\((2, 3)\), and</li>
<li>\((4, 5)\).</li>
</ul>
<p>I want the function to be differentiable.</p>
<h2>Method one: Bézier curves</h2>
<p>Recall from the last post that a (cubic) Bézier curve is specified by four points:</p>
<ul>
<li>A start point (\((x_0, y_0)\) in the diagram below)</li>
<li>Two control points (\((x_1, y_1)\) and \((x_2, y_2)\) in the diagram below)</li>
<li>An end point (\((x_3, y_3)\) in the diagram below)</li>
</ul>
<p>The syntax is: <code>\draw (</code>\(x_0, y_0\)<code>) .. controls (</code>\(x_1, y_1\)<code>) and (</code>\(x_2, y_2\)<code>) .. (</code>\(x_3, y_3\)<code>);</code></p>
<p><img class="white_bk" src="/tikz_2019-05_img/bezier_curve.png" alt="bezier curve
with start, control, and end points as described"/></p>
<p>Now, we can combine multiple Bézier curves into a single <code>\draw</code>. For example, <code>\draw (</code>\(x_0, y_0\)<code>) .. controls (</code>\(x_1, y_1\)<code>) and (</code>\(x_2, y_2\)<code>) .. (</code>\(x_3, y_3\)<code>) .. controls (</code>\(x_4, y_4\)<code>) and (</code>\(x_5, y_5\)<code>) .. (</code>\(x_6, y_6\)<code>);</code> will produce:</p>
<p><img src="/tikz_2019-05_img/bezier_curve_hooked.png" class="white_bk"
alt="two bezier curves attached at a sharp corner" /></p>
<p>In general, this curve will <em>not</em> necessarily be differentiable. We can get differentiability by ensuring that \((x_2, y_2)\), \((x_3, y_3)\) and \((x_4, y_4)\) are colinear (i.e., the end of the first Bézier curve has the same derivative as the beginning of the second) with \(x_2 \not = x_3\):</p>
<p><img src="/tikz_2019-05_img/bezier_curve_hooked_diff.png" class="white_bk"
alt="two bezier curves attached so that the two curves have the same tangents at
their connecting ends" /></p>
<p>Keeping these principles in mind, we can plot a function going through the desired points with:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-106df658-2a2d-4391-b269-03561de6af22"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[</span><span style="color:#268bd2;">border</span><span style="color:#839496;">=0.25cm]{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}[</span><span style="color:#268bd2;">scale</span><span style="color:#839496;">=0.5] </span><span style="color:#586e75;">% Scale keeps the graphic small</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[gray] (-5.25, 0) grid (5.25, 8.25);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (-5.25, 0) -- (5.25, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">x</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {-5, 5}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, 0.25) -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, -0.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=north] {\(</span><span style="color:#859900;">\x</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (0, 0) -- (0, 8.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">y</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {4, 8}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (-0.25, </span><span style="color:#859900;">\y</span><span style="color:#839496;">) -- (0.25, </span><span style="color:#859900;">\y</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=west] {\(</span><span style="color:#859900;">\y</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% graph of function</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] (-5.25, -0.5)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      .. controls (-4, 0) and (-5, 0) .. (-4, 2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      .. controls (-3.5, 3) and (-3, 6) .. (-1, 6)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      .. controls (1, 6) and (1.75, 4) .. (2, 3)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      .. controls (2.25, 2) and (3, 2) .. (4, 5)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      .. controls (4.5, 6.5) and (4.5, 7) .. (5.25, 8);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>Here is the output:</p>
<p><img src="/tikz_2019-05_img/example5a.png" alt="a plot of a differentiable function passing through the desired " /></p>
<h2>Method two: Polynomial interpolation</h2>
<p>SciPy's interpolation functionality can find a smooth function that passes through an arbitrary list of points. Here is an example of a Python script to produce such a function and create a table in the necessary format:</p><div class="code_block"><div class="code-header"><span class="code-lang">Python</span></div><pre class=""  id="block-76b3137d-e0c4-4711-a365-ff624e54b4a3"><code class="language-python"><code class="checker lineno dig-1"><span style="color:#586e75;">#! /usr/bin/env python3</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">numpy </span><span style="color:#cb4b16;">as </span><span style="color:#839496;">np</span></code>
<code class="checker lineno dig-1"><span style="color:#cb4b16;">import </span><span style="color:#839496;">scipy.interpolate</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">coords </span><span style="color:#657b83;">= [(-</span><span style="color:#6c71c4;">10</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">8</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#657b83;">(-</span><span style="color:#6c71c4;">4</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">2</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#657b83;">(-</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">6</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">3</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">4</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">5</span><span style="color:#657b83;">)</span><span style="color:#839496;">, </span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">10</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">)]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;"># Since our goal is to plot from x = -5.25 to x = 5.25,</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># we need to specify some points beyond that interval on both sides.</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">xcoords, ycoords </span><span style="color:#657b83;">= </span><span style="color:#859900;">zip</span><span style="color:#657b83;">(*</span><span style="color:#839496;">coords</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># This produces a seperate list of x-coordinates and y-coordinates</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">f </span><span style="color:#657b83;">= </span><span style="color:#839496;">scipy.interpolate.</span><span style="color:#b58900;">interp1d</span><span style="color:#657b83;">(</span><span style="color:#839496;">xcoords, ycoords, </span><span style="color:#268bd2;">kind</span><span style="color:#657b83;">=</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">cubic</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">xvals </span><span style="color:#657b83;">= </span><span style="color:#839496;">np.</span><span style="color:#b58900;">arange</span><span style="color:#657b83;">(-</span><span style="color:#6c71c4;">5.25</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">5.25</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">0.01</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">yvals </span><span style="color:#657b83;">= </span><span style="color:#b58900;">f</span><span style="color:#657b83;">(</span><span style="color:#839496;">xvals</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">outcoords </span><span style="color:#657b83;">= </span><span style="color:#859900;">zip</span><span style="color:#657b83;">(</span><span style="color:#839496;">xvals, yvals</span><span style="color:#657b83;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;"># This produces a list of coordinate pairs</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">with open</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">plot3.table</span><span style="color:#839496;">&quot;, &quot;</span><span style="color:#2aa198;">wt</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">) </span><span style="color:#859900;">as </span><span style="color:#839496;">outfile</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">for </span><span style="color:#839496;">pair </span><span style="color:#859900;">in </span><span style="color:#839496;">outcoords</span><span style="color:#657b83;">:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        outfile.</span><span style="color:#b58900;">write</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;</span><span style="color:#cb4b16;">{:f} {:f}</span><span style="color:#dc322f;">\n</span><span style="color:#839496;">&quot;.</span><span style="color:#b58900;">format</span><span style="color:#657b83;">(</span><span style="color:#839496;">pair</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">0</span><span style="color:#268bd2;">]</span><span style="color:#839496;">, pair</span><span style="color:#268bd2;">[</span><span style="color:#6c71c4;">1</span><span style="color:#268bd2;">]</span><span style="color:#657b83;">))</span></code>
</code></pre></div>
<p>Note that if we had set <code>coords = [(-4, 2), (-1, 6), (2, 3), (4, 5)]</code>, then the resulting function would not have had a defined value outside of the interval \([-4, 4]\).</p>
<p>To plot, we use the following <code>tikzpicture</code>:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-b65def76-c2a1-4171-b3f0-b41d868a9635"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[</span><span style="color:#268bd2;">border</span><span style="color:#839496;">=0.25cm]{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}[</span><span style="color:#268bd2;">scale</span><span style="color:#839496;">=0.5] </span><span style="color:#586e75;">% Scale keeps the graphic small</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[gray] (-5.25, 0) grid (5.25, 8.25);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (-5.25, 0) -- (5.25, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">x</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {-5, 5}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, 0.25) -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, -0.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=north] {\(</span><span style="color:#859900;">\x</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (0, 0) -- (0, 8.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">y</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {4, 8}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (-0.25, </span><span style="color:#859900;">\y</span><span style="color:#839496;">) -- (0.25, </span><span style="color:#859900;">\y</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=west] {\(</span><span style="color:#859900;">\y</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% graph of function</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-&gt;] plot[smooth] file {plot3.table};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>Here is the result:</p>
<p><img src="/tikz_2019-05_img/example5b.png" alt="a plot of a polynomial function whose graph passes through the desired points" /></p>
<p>As we have seen, creating plots with Ti<i>k</i>Z allows you a deep amount of control over the final result, and can be especially powerful when combined with a programming language such as Python.</p>]]></content:encoded></item><item><title>View of the Mississippi from Levee Park</title><link>https:://chrisphan.com/posts/2019-05-11-view-of-mississippi-from-levee-park/index.html</link><description><![CDATA[ a view of the Mississippi from Levee Park, looking north, when the river has partially flooded the parkway in front of the levee (Levee Park,]]></description><guid>https:://chrisphan.com/posts/2019-05-11-view-of-mississippi-from-levee-park/index.html</guid><pubDate>Sat, 11 May 2019 22:23:52 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/2019-05-11_mississippi.jpg" alt="a view of the Mississippi from Levee Park, looking north, when the river has partially flooded the parkway in front of the levee" /></p>
<p>(Levee Park, Winona, Minnesota, this morning at 11:02 a.m. CDT.)</p>]]></content:encoded></item><item><title>Plotting with TikZ, Part II: Functions without formulæ</title><link>https:://chrisphan.com/posts/2019-05-07-plotting_with_tikz_2/index.html</link><description><![CDATA[ In the last post , I explained why Ti k Z is awesome for making plots. One good use case for handmade Ti k Z]]></description><guid>https:://chrisphan.com/posts/2019-05-07-plotting_with_tikz_2/index.html</guid><pubDate>Tue, 7 May 2019 10:10:00 -0500</pubDate><content:encoded><![CDATA[
<p>In the <a href="/posts/2019-05-01-plotting_with_tikz_1/">last post</a>, I explained why Ti<i>k</i>Z is awesome for making plots. One good use case for handmade Ti<i>k</i>Z plots is to typeset a question like this:</p>
<blockquote>
<ol start="5">
<li>(2 points each) A plot of the graph of the function \(f\) is below:</li>
</ol>
<p><img src="/tikz_2019-05_img/example2.png" alt="A plot of a real-valued function on the real numbers inclusively between -5 and 5, with the exception of -2. The function is continuous except that there is a removable discontinuity, a vertical asymptote, and a jump discontinuity" /></p>
<p>For each of the following expressions, either evaluate the expression or state that it is undefined:</p>
<p>a. \(\lim_{x \rightarrow 2^{-}} f(x)\)</p>
<p>b. \(\lim_{x \rightarrow 2^{+}} f(x)\)</p>
<p>c. \(\lim_{x \rightarrow 2} f(x)\)</p>
<p>d. \(f(2)\)</p>
<p>[. . .]</p>
</blockquote>
<p>It would be a pain to come up with a formula for a function with the features shown. Before I made these kinds of graphs in Ti<i>k</i>Z, I would either draw it by hand, or use the drawing features in word-processing software. Drawing by hand is suboptimal, since it requires you to be good at drawing (which I'm not) and the resulting files don't play well with version control. The output from a word-processing software won't play well with version control, either. And using Ti<i>k</i>Z will make the output automatically have the same font settings as the rest of your document.</p>
<h1>How to create such a plot</h1>
<p>Here is the source code for the plot above:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-5b1682a1-ae7c-4f03-b492-391f8dbcd992"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[</span><span style="color:#268bd2;">border</span><span style="color:#839496;">=0.25cm]{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}[</span><span style="color:#268bd2;">scale</span><span style="color:#839496;">=0.75]</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[gray] (-5.25, -5.25) grid (5.25, 5.25);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (-5.25, 0) -- (5.25, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">x</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% x-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {-5, 5}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, 0.2) -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, -0.2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=north] {\(</span><span style="color:#859900;">\x</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (0, -5.25) -- (0, 5.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      node[anchor=south west] {$</span><span style="color:#268bd2;">y</span><span style="color:#839496;">$};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% y-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {-5, 5}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (-0.2, </span><span style="color:#859900;">\y</span><span style="color:#839496;">) -- (0.2, </span><span style="color:#859900;">\y</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        node[anchor=west] {\(</span><span style="color:#859900;">\y</span><span style="color:#839496;">\)};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% graph of function</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, -&gt;] (-5, 4) .. controls (-5, 2) and (-4, 2) .. (-3, 2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      .. controls (-2.1, 2) and (-2.1, 3) ..</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      (-2.1, 5.25);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, dashed, red] (-2, -5.25) -- (-2, 5.25);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-] (-1.9, 5.25) ..</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    controls (-1.9, 0) and (0, -4) .. (2, -4);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue] (2, 4) -- (5, -2);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (-5, 4) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=white] (-3, 2) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (-3, -3) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=white] (2, -4) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (2, 4) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (5, -2) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>Let's go through the construction of this plot. This will also explain the basic syntax of Ti<i>k</i>Z.</p>
<h2>Grid</h2>
<p><img src="/tikz_2019-05_img/example2_grid.png" alt="the plot in the quiz
question above, except that everything is grayed out but the grid"
class="white_bk" /></p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-84ddce26-0de7-4bd5-aeed-a071475650f3"><code class="language-latex"><code class="code-elipsis" id="block-84ddce26-0de7-4bd5-aeed-a071475650f3-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[gray] (-5.25, -5.25) grid (5.25, 5.25);</span></code>
<code class="code-elipsis" id="block-84ddce26-0de7-4bd5-aeed-a071475650f3-elipsis-end"></code>
</code></pre></div>
<p>This creates a grid inside the rectangle with opposite corners at \((-5.25,
-5.25)\) and \((5.25, 5.25)\). By default, grids in Ti<i>k</i>Z have their
gridlines one unit apart, at integer coordinates. By having the edge of my grid
0.25 units off an integer, I give the subtle impression that the grid extends
beyond the graphic. Compare these two grids:</p>
<p><img src="/tikz_2019-05_img/grids.png" alt="two grids, but one has loose edges"
class="white_bk" /></p>
<p>The grid on the left was created with <code>\draw[gray] (-5.25, -5.25) grid (5.25, 5.25);</code> (off-integer edges), while the code on the right was created with <code>\draw[gray] (6, -5) grid (16, 5);</code> (integer edges).</p>
<p>Notice that the grid drawing code is placed <em>first</em> in the <code>tikzpicture</code>. This ensures the grid is drawn first, placing all other elements on top.</p>
<h2>Axes</h2>
<p><img src="/tikz_2019-05_img/example2_axes.png" alt="the plot in the quiz
question above, except that everything is grayed out but the coordinate axes"
class="white_bk" /></p>
<p>My preference is to have each axis be an arrow with the arrowhead in the positive direction. This is accomplished with:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-5db126f0-7618-4c7d-ad8b-6caecb3ce444"><code class="language-latex"><code class="code-elipsis" id="block-5db126f0-7618-4c7d-ad8b-6caecb3ce444-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">% x-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (-5.25, 0) -- (5.25, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  node[anchor=south west] {$</span><span style="color:#268bd2;">x</span><span style="color:#839496;">$};</span></code>
<code class="code-elipsis" id="block-5db126f0-7618-4c7d-ad8b-6caecb3ce444-elipsis-end"></code>
</code></pre></div><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-408172bd-90ec-4253-8648-0f5b87efe18b"><code class="language-latex"><code class="code-elipsis" id="block-408172bd-90ec-4253-8648-0f5b87efe18b-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">% y-axis</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, black, -&gt;] (0, -5.25) -- (0, 5.25)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  node[anchor=south west] {$</span><span style="color:#268bd2;">y</span><span style="color:#839496;">$};</span></code>
<code class="code-elipsis" id="block-408172bd-90ec-4253-8648-0f5b87efe18b-elipsis-end"></code>
</code></pre></div>
<p>The <code>\draw</code> command is used to draw, unsurprisingly. To produce a line segment
from \((-5.25, 0)\) to \((5.25, 0)\), one could just do:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-55538e54-2671-40f9-bc9c-c77fdb25783a"><code class="language-latex"><code class="code-elipsis" id="block-55538e54-2671-40f9-bc9c-c77fdb25783a-elipsis-start"></code>
<code class="checker "><span style="color:#859900;">\draw</span><span style="color:#839496;"> (-5.25, 0) -- (5.25, 0);</span></code>
<code class="code-elipsis" id="block-55538e54-2671-40f9-bc9c-c77fdb25783a-elipsis-end"></code>
</code></pre></div>
<p>You can actually chain line segments together by providing multiple coordinates. For example:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-d99829f8-a161-4958-937f-c1a02b7d9999"><code class="language-latex"><code class="code-elipsis" id="block-d99829f8-a161-4958-937f-c1a02b7d9999-elipsis-start"></code>
<code class="checker "><span style="color:#859900;">\draw</span><span style="color:#839496;"> (3, 0) -- (4, 2) -- (5, 0) -- (3, 4);</span></code>
<code class="code-elipsis" id="block-d99829f8-a161-4958-937f-c1a02b7d9999-elipsis-end"></code>
</code></pre></div>
<p>Back to the \(x\)-axis, the options <code>[thick, black, -&gt;]</code> produce a thick black line segment with an arrowhead at the end (the last coordinate). But after I draw the line segment, I add some text, using <code>node[anchor=south west] {$x$}</code>. This tells Ti<i>k</i>Z to place the LaTeX text \(x\) just to the right and above the arrowhead. (It's a bit confusing, but <code>anchor=south west</code> refers to the point of view of the <code>node</code> with the text \(x\), not the point of view of the arrowhead! That is, the arrowhead is southwest of the \(x\).)</p>
<h2>Tick marks</h2>
<p><img src="/tikz_2019-05_img/example2_ticks.png" alt="the plot in the quiz
question above, except that everything is grayed out but the tick marks"
class="white_bk" /></p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-d2a997c4-5f5b-4e28-9326-2cd0babef7a2"><code class="language-latex"><code class="code-elipsis" id="block-d2a997c4-5f5b-4e28-9326-2cd0babef7a2-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">% x-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {-5, 5}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, 0.2) -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, -0.2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    node[anchor=north] {\(</span><span style="color:#859900;">\x</span><span style="color:#839496;">\)};</span></code>
<code class="code-elipsis" id="block-d2a997c4-5f5b-4e28-9326-2cd0babef7a2-elipsis-end"></code>
</code></pre></div><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-5da4e3e9-ab20-46ca-a7f2-68d99f49e079"><code class="language-latex"><code class="code-elipsis" id="block-5da4e3e9-ab20-46ca-a7f2-68d99f49e079-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">% y-axis tick marks</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {-5, 5}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick] (-0.2, </span><span style="color:#859900;">\y</span><span style="color:#839496;">) -- (0.2, </span><span style="color:#859900;">\y</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    node[anchor=west] {\(</span><span style="color:#859900;">\y</span><span style="color:#839496;">\)};</span></code>
<code class="code-elipsis" id="block-5da4e3e9-ab20-46ca-a7f2-68d99f49e079-elipsis-end"></code>
</code></pre></div>
<p>On each axis are two tick marks. For example, on the \(x\)-axis, I want a tick
mark at \((-5, 0)\) and another at \((5, 0)\). Each tick mark is a tick line
segment from \((x, 0.2)\) to \((x, -0.2)\), where \(x\) is the horizontal
coordinate of the tick mark. I use a for (<code>\foreach</code>) loop to create the tick
marks. Below each tick mark is a node with the horizontal coordinate;
<code>anchor=north</code> tells Ti<i>k</i>Z to position the label so that the bottom end of
the tick mark (at \((x, -0.2)\)) is north of the label.</p>
<h2>Bézier curves</h2>
<p><img src="/tikz_2019-05_img/example2_bezier.png" alt="the plot in the quiz
question above, except that everything is grayed out but two bezier curves"
class="white_bk" /></p>
<p>We now start making the plot of the function itself. Two parts are made from Bézier curves, a go-to for making curvy parts.</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-2338c9db-d9f8-48a9-8629-c367f8309c51"><code class="language-latex"><code class="code-elipsis" id="block-2338c9db-d9f8-48a9-8629-c367f8309c51-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, -&gt;] (-5, 4) .. controls (-5, 2) and (-4, 2) .. (-3, 2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  .. controls (-2.1, 2) and (-2.1, 3) ..</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  (-2.1, 5.25);</span></code>
<code class="code-elipsis" id="block-2338c9db-d9f8-48a9-8629-c367f8309c51-elipsis-end"></code>
</code></pre></div><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-c5c35a6c-0355-4894-a2b5-470c7eea5042"><code class="language-latex"><code class="code-elipsis" id="block-c5c35a6c-0355-4894-a2b5-470c7eea5042-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, &lt;-] (-1.9, 5.25) ..</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  controls (-1.9, 0) and (0, -4) .. (2, -4);</span></code>
<code class="code-elipsis" id="block-c5c35a6c-0355-4894-a2b5-470c7eea5042-elipsis-end"></code>
</code></pre></div>
<p>The basic syntax for a Bézier curve in Ti<i>k</i>Z is
<code>\draw (</code>\(x_0, y_0\)<code>) .. controls (</code>\(x_1, y_1\)<code>) and (</code>\(x_2, y_2\)<code>) .. (</code>\(x_3, y_3\)<code>);</code>
A Bézier curve is specified by four points:</p>
<ul>
<li>A start point (\((x_0, y_0)\) in the diagram below)</li>
<li>Two control points (\((x_1, y_1)\) and \((x_2, y_2)\) in the diagram below)</li>
<li>An end point (\((x_3, y_3)\) in the diagram below)</li>
</ul>
<p>This diagram gives you a sense for how the control points &quot;pull&quot; the curve.</p>
<p><img class="white_bk" src="/tikz_2019-05_img/bezier_curve.png" alt="bezier curve
with start, control, and end points as described"/></p>
<p>(<strong>Side note</strong>: Technically, this is a <em>cubic</em> Bézier curve. The curve is
parametrized by \[B(t) = (1-t)^3(x_0, y_0) + 3 t(1-t)^2(x_1, y_1) +
3t^2(1-t)(x_2, y_2) + t^3(x_3, y_3), \; 0 \leq t \leq 1.\] For more details,
see <a href="http://www.ams.org/publicoutreach/feature-column/fcarc-bezier">this article by Bill
Casselman</a>, a
great expositor on the mathematics of computer graphics.)</p>
<p>You can even put your Bézier curve in the middle of a <code>draw</code> command, e.g. the following code:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-ef35a0a1-5adf-47a6-b939-a6aea224c6f8"><code class="language-latex"><code class="code-elipsis" id="block-ef35a0a1-5adf-47a6-b939-a6aea224c6f8-elipsis-start"></code>
<code class="checker "><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue] (0, 0) -- (2, 2) .. controls (-3, 1) and (4, 7) .. (5, 8) -- (5, 5);</span></code>
<code class="code-elipsis" id="block-ef35a0a1-5adf-47a6-b939-a6aea224c6f8-elipsis-end"></code>
</code></pre></div>
<p><img class="white_bk" src="/tikz_2019-05_img/silly_bezier.png" alt="A continuous
curve comprising a line segment, a bezier curve, and another line segment. The
curve is not differentiable, with sharp corners where the line segments have
been joined to the bezier curve." /></p>
<p>Back to our drawing, consider the left-most Bézier curve, given by:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-3ab580a2-2b2e-4af2-8941-8a878703f043"><code class="language-latex"><code class="code-elipsis" id="block-3ab580a2-2b2e-4af2-8941-8a878703f043-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, -&gt;] (-5, 4) .. controls (-5, 2) and (-4, 2) .. (-3, 2)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  .. controls (-2.1, 2) and (-2.1, 3) ..</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  (-2.1, 5.25);</span></code>
<code class="code-elipsis" id="block-3ab580a2-2b2e-4af2-8941-8a878703f043-elipsis-end"></code>
</code></pre></div>
<p><img src="/tikz_2019-05_img/example2_zoom_bezier.png" alt="a portion of the plot
in the quiz question above. We focus on a U-shaped part of the curve, with the
right part of the U having a vertical asymptote"
class="white_bk" /></p>
<p>I want a vertical asymptote at \(x=-2\). For readability sake, I actually make
the curve end at \((-2.1, 5.25)\). The control point at \((-2.1, 3)\) pulls
the curve back and gives the appearance of a vertical asymptote at \(x = -2\).
The option <code>-&gt;</code> puts an arrowhead on the end of the curve.</p>
<h3>Sidenote: Ensuring that a Bézier curve makes \(y\) a function of \(x\)</h3>
<p>It's possible to create a Bézier curve in which \(y\) is not a function of
\(x\) (i.e., fails the vertical line test).</p>
<p><img src="/tikz_2019-05_img/bezier_curve_fail_vertical_line_test.png"
alt="A bezier curve with end and control points given generic labels. The curve
bends on each end in such a way that there are multiple points with the same
horizontal position."
class="white_bk" /></p>
<p>With some calculus, one can show that \(x_0 \leq x_1 \leq x_2 \leq x_3\) will ensure this does not happen.<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup></p>
<h2>Vertical asymptote</h2>
<p><img src="/tikz_2019-05_img/example2_vasymp.png" alt="the plot in the quiz
question above, except that everything is grayed out but a dashed vertical line
that represents a vertical asymptote"
class="white_bk" /></p>
<p>I use a thick, dashed, red line segment from \((-2, -5.25)\) to \((-2,
5.25)\) to represent the vertical asymptote at \(x = -2\).</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-5c13ab5a-ab59-4cdf-8a83-d39a139a3006"><code class="language-latex"><code class="code-elipsis" id="block-5c13ab5a-ab59-4cdf-8a83-d39a139a3006-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, dashed, red] (-2, -5.25) -- (-2, 5.25);</span></code>
<code class="code-elipsis" id="block-5c13ab5a-ab59-4cdf-8a83-d39a139a3006-elipsis-end"></code>
</code></pre></div>
<h2>Line segment part of graph</h2>
<p><img src="/tikz_2019-05_img/example2_lineseg.png" alt="the plot in the quiz
question above, except that everything is grayed out but a line segment which is
part of the function's graph"
class="white_bk" /></p>
<p>Part of the graph is the line segment from \((2, 4)\) to \((5, -2)\).</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-6789c0b5-fc63-49ef-b0c4-2396b9c14da4"><code class="language-latex"><code class="code-elipsis" id="block-6789c0b5-fc63-49ef-b0c4-2396b9c14da4-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue] (2, 4) -- (5, -2);</span></code>
<code class="code-elipsis" id="block-6789c0b5-fc63-49ef-b0c4-2396b9c14da4-elipsis-end"></code>
</code></pre></div>
<h2>Explicit points</h2>
<p><img src="/tikz_2019-05_img/example2_expl_pts.png" alt="the plot in the quiz
question above, except that everything is grayed out circles (filled or
unfilled) that clarify which points are in the graph."
class="white_bk" /></p>
<p>A key advantage for making these graphs using Ti<i>k</i>Z is to incorporate my
visual vocabulary for graphs. I follow the common convention where a filled-in
circle indicates a point on the graph, while a hollow circle indicates a point
which is not on the graph, e.g. \((-3, 2)\) is not on the graph, while \((-3, -3)\)
is.</p>
<p>To accommodate this, we use circles, either filled with the same color as rest of the graph (for points on the graph) or filled with white (to make them hollow). These commands are last, so the white fill punches a hole in the graph.</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-6ab1b82e-c440-4cac-bdfa-e70b0e6dc465"><code class="language-latex"><code class="code-elipsis" id="block-6ab1b82e-c440-4cac-bdfa-e70b0e6dc465-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (-5, 4) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=white] (-3, 2) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (-3, -3) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=white] (2, -4) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (2, 4) circle (1mm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, blue, fill=blue] (5, -2) circle (1mm);</span></code>
<code class="code-elipsis" id="block-6ab1b82e-c440-4cac-bdfa-e70b0e6dc465-elipsis-end"></code>
</code></pre></div>
<p>And with that, our graph is complete!</p>
<p>In the next post, I will explain how to use Ti<i>k</i>Z to plot graphs of
functions defined by a mathematical formula.</p>
<section class="footnotes" data-footnotes>
<ol>
<li id="fn-1">
<p>This is because \[\frac{dx}{dt} = 3 \left((1 - t)^2 \left(x_1 - x_0\right) + 2t(1-t)\left(x_2 - x_1\right) + t^2 \left(x_3 - x_2\right) \right),\] and \(0 \leq t \leq 1\). <a href="#fnref-1" class="footnote-backref" data-footnote-backref data-footnote-backref-idx="1" aria-label="Back to reference 1">↩</a></p>
</li>
</ol>
</section>]]></content:encoded></item><item><title>Plotting with TikZ, Part I: Why?</title><link>https:://chrisphan.com/posts/2019-05-01-plotting_with_tikz_1/index.html</link><description><![CDATA[ This is the first part of a three-part series of posts on generating plots of graphs with Ti k Z. Last year, I left my]]></description><guid>https:://chrisphan.com/posts/2019-05-01-plotting_with_tikz_1/index.html</guid><pubDate>Wed, 1 May 2019 08:58:30 -0500</pubDate><content:encoded><![CDATA[
<p>This is the first part of a three-part series of posts on generating plots of graphs with Ti<i>k</i>Z. Last year, I left my position as a mathematics professor, after teaching mathematics at the college level for 15 years (nine years as a faculty member, and six years as a graduate teaching fellow). In that time, I picked up a lot of tricks using LaTeX to produce teaching materials (handouts and slides). I decided it might be good to record some of that knowledge somewhere, and my blog seems like a natural place.</p>
<h2>Outline</h2>
<p>I'm planning a three-part series:</p>
<ul>
<li>
<p><strong>Part I</strong> will explain what Ti<i>k</i>Z is and why you might want to use it to produce plots for classroom use.</p>
</li>
<li>
<p><strong>Part II</strong> will show how you can use Ti<i>k</i>Z to produce graphs for graph-reading and limit questions without having to make up functions.</p>
<p><img src="/tikz_2019-05_img/example2.png" alt="A plot of a real-valued function on the real numbers inclusively between -5 and 5, with the exception of -2. The function is continuous except that there is a removable discontinuity, a vertical asymptote, and a jump discontinuity" /></p>
</li>
<li>
<p><strong>Part III</strong> will show how I prefer to plot functions from a formula, using Python.</p>
</li>
</ul>
<h2>What is Ti<i>k</i>Z?</h2>
<p><a href="https://ctan.org/pkg/pgf?lang=en">Ti<i>k</i>Z</a> is a powerful LaTeX package for
producing illustrations. Ti<i>k</i>Z is short for &quot;TikZ ist <em>kein</em>
Zeichenprogramm&quot;, which I understand means &quot;Ti<i>k</i>Z is <em>not</em> a drawing
program&quot; in German. (Technically, Ti<i>k</i>Z comes bundled on top of another
package called PGF, and the actual package is PGF/Ti<i>k</i>Z. I will refer to
the package as just &quot;Ti<i>k</i>Z&quot; in this series of posts.) Unlike traditional
illustration software such as Illustrator, in which the user would use a
graphical interface create graphics, one creates graphics in Ti<i>k</i>Z with
drawing commands. Here is an example of a short LaTeX document in which
Ti<i>k</i>Z is used to produce a few shapes:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-9913ef7c-2d96-4e12-ad06-1558f80b9817"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[</span><span style="color:#268bd2;">border</span><span style="color:#839496;">=0.25cm]{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">% Square</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[dashed, blue] (0, 0) -- (0, 2)</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    -- (2, 2) -- (2, 0) -- cycle;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% Triangle</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, green, fill=green] (3, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      -- (4, 2) -- (5, 0) -- cycle;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% Circle</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[thick, red, fill=purple]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      (6, 0) circle (0.5 cm);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% Arrow</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[-&gt;, thick, brown] (0, -1) -- (6.5, -1);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>And here is the result:</p>
<p><img src="/tikz_2019-05_img/example1.png" 
alt="a square made out of dashed, blue lines; a green filled triangle; a red circle filled with purple; and a long brown arrow" class="white_bk" /></p>
<p>Here's an example of an illustration I created for a calculus exam, using Ti<i>k</i>Z:</p>
<p><img src="/tikz_2019-05_img/water_tank.png" 
alt="a isometric diagram of a trapezoidal prism water trough, partially filled with water, with dimensions labelled"
class="white_bk" /></p>
<p>You can find a number of beautiful Ti<i>k</i>Z examples on
<a href="http://www.texample.net/tikz/examples/">TeXample.net</a> and on the TeX
StackExchange under the <a href="https://tex.stackexchange.com/questions/tagged/tikz-pgf">&quot;Ti<i>k</i>Z-PGF&quot;
tag</a>.</p>
<h2>Why use Ti<i>k</i>Z to make plots?</h2>
<p>To be frank, creating illustrations in Ti<i>k</i>Z can sometimes be time-consuming. For example, to create the water trough illustration above, it would not be unreasonable to prefer using illustration software or drawing the diagram freehand. For plots, you can make great illustration using <a href="http://www.sagemath.org/">SageMath</a>, <a href="https://www.desmos.com/">Desmos</a>, or <a href="https://matplotlib.org/">Matplotlib</a>. But I still sometimes prefer Ti<i>k</i>Z to create plots.</p>
<ul>
<li>
<p><em>Complete control means plots fit the look and feel of your class:</em> When teaching, it's important that plots have a consistent look and feel, to avoid confusing students, and to communicate expectations for their hand-drawn plots. By creating plots from scratch with Ti<i>k</i>Z allows you to have complete control over elements such as axis placement and tick mark labeling.</p>
</li>
<li>
<p><em>Better integration with the document:</em> Plots created with Ti<i>k</i>Z will use the same fonts as your core document. For example, if you decide to replace <code>\usepackage{times}</code> with <code>\usepackage{fouriernc}</code>, the plots will change too.</p>
</li>
<li>
<p><em>It's compatible with version control:</em> I'm a bit of a version control fanatic, and unlike scans of hand-drawn sketches of plots or screen shots from other software, Ti<i>k</i>Z code plays very well with version control.</p>
</li>
<li>
<p><em>Incorporate your symbols for holes and asymptotes:</em> With Ti<i>k</i>Z, you can incorporate your graph notation for features, such as a dotted line to illustrate an asymptote, or an unfilled circle to indicate a hole.</p>
</li>
<li>
<p><em>Make graphs of functions without having to actually come up with an explicit formula for the rule of the function:</em> Sometimes it's nice to make up a function for illustration purposes without actually coming up with the formula for the rule of the function, for a problem such as:</p>
<blockquote>
<ol start="5">
<li>(2 points each) A plot of the graph of the function $f$ is below:</li>
</ol>
<p><img src="/tikz_2019-05_img/example2.png" alt="A plot of a real-valued function on the real numbers inclusively between -5 and 5, with the exception of -2. The function is continuous except that there is a removable discontinuity, a vertical asymptote, and a jump discontinuity" /></p>
<p>For each of the following expressions, either evaluate the expression or state that it is undefined:</p>
<p>a. \(\lim_{x \rightarrow 2^{-}} f(x)\)</p>
<p>b. \(\lim_{x \rightarrow 2^{+}} f(x)\)</p>
<p>c. \(\lim_{x \rightarrow 2} f(x)\)</p>
<p>d. \(f(2)\)</p>
<p>[. . .]</p>
</blockquote>
<p>With Ti<i>k</i>Z, you can make a plot like this using features such as Bezier curves.</p>
</li>
</ul>
<p>In the next post, I will explain how to create a plot like the one above.</p>]]></content:encoded></item><item><title>Migrated to Hugo</title><link>https:://chrisphan.com/posts/2019-04-25-migrated-to-hugo/index.html</link><description><![CDATA[ When I set up this blog in 2012, WordPress was a natural choice for content management system. However, I recently decided to investigate using Hugo]]></description><guid>https:://chrisphan.com/posts/2019-04-25-migrated-to-hugo/index.html</guid><pubDate>Thu, 25 Apr 2019 10:13:00 -0500</pubDate><content:encoded><![CDATA[
<p>When I set up this blog in 2012, WordPress was a natural choice for content management system. However, I recently decided to investigate using <a href="https://gohugo.io/">Hugo</a> to generate this blog, and after some playing around, I made the leap. The biggest reason: I wanted the <a href="https://gohugo.io/about/benefits/">benefits of a statically-generated site</a>. (Hugo is also more compatible with version control systems.)</p>
<p>For the actual migration, I used Cyrill Schumacher's <a href="https://github.com/SchumacherFM/wordpress-to-hugo-exporter">WordPress to Hugo Exporter</a> plug-in. I did have to do some manual futzing.</p>
<p>While I was at it, I merged my main site (<code>chrisphan.com</code>) with the blog (<code>blog.chrisphan.com</code>). I also made self-hosted copies of the photos that were on Flickr and posted here.</p>
<p>I also found <a href="https://www.euantorano.co.uk/posts/hugo-git-deployment-nearly-free-speech/">these instructions</a> by Euan T. to be very helpful!</p>]]></content:encoded></item><item><title>Disclaimer</title><link>https:://chrisphan.com/disclaimer/index.html</link><description><![CDATA[ is my personal web site, and content provided here is provided by me in my personal capacity. The opinions expressed on this site are my]]></description><guid>https:://chrisphan.com/disclaimer/index.html</guid><pubDate>Tue, 23 Apr 2019 12:00:00 +0000</pubDate><content:encoded><![CDATA[
<p><code>chrisphan.com</code> is my personal web site, and content provided here is provided
by me in my personal capacity.</p>
<p>The opinions expressed on this site are my own and do not necessarily represent
the opinion of any of my employers (former or current) or any organization with
which I am or was affiliated.</p>]]></content:encoded></item><item><title>Math page for Chistopher Phan</title><link>https:://chrisphan.com/math/index.html</link><description><![CDATA[ Academic Background Education Ph.D. 2009, mathematics , University of Oregon Advisor: Professor Brad Shelton Dissertation: Koszul and generalized Koszul properties for noncommutative graded algebras M.S.]]></description><guid>https:://chrisphan.com/math/index.html</guid><pubDate>Mon, 22 Apr 2019 21:46:53 -0500</pubDate><content:encoded><![CDATA[
<h1>Academic Background</h1>
<h2>Education</h2>
<ul>
<li>Ph.D. 2009, <a href="https://math.uoregon.edu">mathematics</a>, <a href="https://www.uoregon.edu/">University of
Oregon</a>
<ul>
<li>Advisor: <a href="https://math.uoregon.edu/profile/shelton">Professor Brad Shelton</a></li>
<li>Dissertation: <a href="http://hdl.handle.net/1794/10367"><em>Koszul and generalized Koszul properties for noncommutative
graded algebras</em></a></li>
</ul>
</li>
<li>M.S. 2005, mathematics, University of Oregon</li>
<li>B.A. 2003,
<a href="https://college.lclark.edu/departments/mathematical_sciences/">mathematics</a>
and
<a href="https://college.lclark.edu/departments/rhetoric_and_media/">communication</a>,
<a href="https://www.lclark.edu/">Lewis &amp; Clark College</a></li>
</ul>
<h2>Academic positions</h2>
<ul>
<li><strong>Fixed-term Assistant Professor</strong>, Department of Mathematics and Statistics,
Winona State University, Winona, Minnesota, August 2012-May 2018.</li>
<li><strong>Visiting Assistant Professor</strong>, Department of Mathematics, Bucknell
University, Lewisburg, Pennsylvania, August 2010-May 2012.</li>
<li><strong>Temporary Lecturer</strong>, Department of Mathematics, University of Glasgow,
Glasgow, Scotland, September 2009-August 2010.</li>
<li><strong>Adjunct Instructor</strong>, General Education Department, Cooking &amp;
Hospitality Institute of Chicago, Chicago, Illinois, August-September 2009.</li>
<li><strong>Graduate Teaching Fellow</strong>, Department of Mathematics, University of Oregon,
Eugene, Oregon, September 2003-June 2009.</li>
</ul>
<h2>Full CV</h2>
<ul>
<li><a href="https://chrisphan.com/cphan_cv.pdf">My full curriculum vitae</a> (last updated
August 2018)</li>
</ul>
<h1>Teaching demos</h1>
<p>These are some materials that I created for use in the classroom.</p>
<h2>Interactive demos</h2>
<ul>
<li><a href="https://chrisphan.com/math/deriv_as_function.html">The derivative as a
function</a></li>
<li><a href="https://chrisphan.com/math/derivative_of_exponential.html">Behavior of exponential
functions</a></li>
<li><a href="https://chrisphan.com/math/second_order_homog_linear_des.html">ODEs of the form \(y'' + by' + cy =
0\)</a></li>
<li><a href="https://chrisphan.com/math/second_order_nonhomog_linear_des.html">Forced
vibrations</a>
(ODEs of the form \(y'' + 0.125y' + y = 3 \cos(\omega t)\).)</li>
<li><a href="https://chrisphan.com/math/calcexamples/implicit_diff.html">Implicit
differentiation</a></li>
</ul>
<h2>Non-interactive materials</h2>
<ul>
<li><a href="https://chrisphan.com/math/calcexamples/inverse_functions_p.html">Derivatives of inverse
functions</a></li>
<li><a href="https://chrisphan.com/math/deexamples/oscillation_animate.html">Non-interactive version of forced
vibrations</a></li>
<li><a href="https://chrisphan.com/math/first_order_linear_des.html">First order linear differential
equations</a></li>
<li><a href="https://chrisphan.com/math/logistic.html">Logistic equation</a></li>
</ul>
<h1>Ring Theory Research</h1>
<p>I was a noncommutative ring theorist whose primary research interest was
homological results involving graded algebras. For example, I studied the Koszul
and \(\mathcal{K}_2\) properties.</p>
<ul>
<li>Here is my <a href="https://chrisphan.com/research_statement.pdf">statement of research
interests</a>, from back when I was
on the academic job market (circa 2012).</li>
</ul>
<h2>Research articles</h2>
<ul>
<li>
<p><a href="https://doi.org/10.1080/00927872.2013.793695">Quotients of Koszul algebras and 2-\(d\)-determined
algebras</a> (with T. Cassidy),
Communications in Algebra, 42 (2014), 3742–3752. Preprint available at
<a href="https://arxiv.org/abs/1210.3847">arXiv:1210.3847</a> [math.RA].
<a href="http://www.ams.org/mathscinet-getitem?mr=3200055">MR3200055</a></p>
<p>Vatne and Green &amp; Marcos have independently studied the Koszul-like
homological properties of graded algebras that have defining relations in
degree 2 and exactly one other degree. We contrast these two approaches,
answer two questions posed by Green &amp; Marcos, and find conditions that imply
the corresponding Yoneda algebras are generated in the lowest possible
degrees.</p>
</li>
<li>
<p><a href="http://dx.doi.org/10.1080/00927872.2010.539584">The Yoneda algebra of a graded Ore
extension</a>, Communications in
Algebra, 40 (2012) 834–844. Preprint available at
<a href="http://arxiv.org/abs/1002.2318">arXiv:1002.2318</a> [math.RA].
<a href="http://www.ams.org/mathscinet-getitem?mr=2899911">MR2899911</a></p>
<p>Let \(A\) be a connected-graded algebra with trivial module \(k\), and let
\(B\) be a graded Ore extension of \(A\). We relate the structure of the
Yoneda algebra \(\mathrm{E}(A):= \mathrm{Ext}_A(k,k)\) to
\(\mathrm{E}(B)\). Cassidy and Shelton have shown that when \(A\)
satisfies their \(\mathcal{K}_2\) property, \(B\) will also be
\(\mathcal{K}_2\). We prove the converse of this result.</p>
</li>
<li>
<p><a href="http://dx.doi.org/10.1007/s00029-011-0058-y">Localization algebras and deformations of Koszul
algebras</a> (with T. Braden, A.
Licata, N. Proudfoot, and B. Webster), Selecta Mathematica, 17 (2011) 533–572.
Preprint available at <a href="http://arxiv.org/abs/0905.1335">arXiv:0905.1335</a>
[math.RA]. <a href="http://www.ams.org/mathscinet-getitem?mr=2827176">MR2827176</a></p>
<p>We show that the center of a flat graded deformation of a standard Koszul
algebra \(A\) behaves in many ways like the torus-equivariant cohomology
ring of an algebraic variety with finite fixed point set. In particular, the
center of \(A\) acts by characters on the deformed standard modules,
providing a “localization map”. We construct a universal graded deformation of
\(A\) and show that the spectrum of its center is supported on a certain
arrangement of hyperplanes which is orthogonal to the arrangement coming from
the algebra Koszul dual to \(A\). This is an algebraic version of a duality
discovered by Goresky and MacPherson between the equivariant cohomology rings
of partial flag varieties and Springer fibers; we recover and generalize their
result by showing that the center of the universal deformation for the ring
governing a block of parabolic category \(\mathcal{O}\) for is isomorphic to the
equivariant cohomology of a Spaltenstein variety. We also identify the center
of the deformed version of the “category \(\mathcal{O}\)” of a hyperplane
arrangement (defined by the authors in a previous paper) with the equivariant
cohomology of a hypertoric variety.</p>
</li>
<li>
<p><a href="http://dx.doi.org/10.1515/CRELLE.2010.065">Noncommutative Koszul algebras from combinatorial
topology</a> (with T. Cassidy and B.
Shelton), Journal für die reine und angewandte Mathematik (Crelle’s Journal),
646 (2010) 45–63. Preprint available at
<a href="http://arxiv.org/abs/0811.3450">arXiv:0811:3450</a> [math.RA].
<a href="http://www.ams.org/mathscinet-getitem?mr=2719555">MR2719555</a></p>
<p>Associated to any uniform finite layered graph \(\Gamma\) there is a
noncommutative graded quadratic algebra \(A(\Gamma)\) given by a construction
due to Gelfand, Retakh, Serconek and Wilson. It is natural to ask when these
algebras are Koszul. Unfortunately, a mistake in the literature states that
all such algebras are Koszul. That is not the case and the theorem was
recently retracted. We analyze the Koszul property of these algebras for two
large classes of graphs associated to finite regular CW-complexes, \(X\).
Our methods are primarily topological. We solve the Koszul problem by
introducing new cohomology groups \(H_X(n,k)\), generalizing the usual
cohomology groups \(H_n(X)\). Along with several other results, our methods give
a new and primarily topological proof of the main result of [Serconek and
Wilson, J. Algebra 278: 473–493, 2004] and [Piontkovski, J. Alg. Comput. 15,
643–648, 2005].</p>
</li>
<li>
<p><a href="http://dx.doi.org/10.1080/00927870902829148">The Yoneda algebra of a \(\mathcal{K}_2\) algebra need not be another
\(\mathcal{K}_2\) algebra</a>
(with T. Cassidy and B. Shelton), Communications in Algebra, 38 (2010) 46–48.
Preprint available at <a href="http://arxiv.org/abs/0810.4656">arXiv:0810.4656</a>
[math.RA]. <a href="http://www.ams.org/mathscinet-getitem?mr=2597480">MR2597480</a></p>
<p>The Yoneda algebra of a Koszul algebra or a \(D\)-Koszul algebra is Koszul.
\(\mathcal{K}_2\) algebras are a natural generalization of Koszul
algebras, and one would hope that the Yoneda algebra of a
\(\mathcal{K}_2\) algebra would be another \(\mathcal{K}_2\) algebra.
We show that this is not necessarily the case by constructing a monomial
\(\mathcal{K}_2\) algebra for which the corresponding Yoneda algebra is
not \(\mathcal{K}_2\).</p>
</li>
<li>
<p><a href="http://dx.doi.org/10.1016/j.jalgebra.2008.12.011">Generalized Koszul properties for augmented
algebras</a>, Journal of
Algebra, 321 (2009) 1522–1537. Preprint available at
<a href="http://www.arxiv.org/abs/0711.3480">arXiv:0711.3480</a> [math.RA].
<a href="http://www.ams.org/mathscinet-getitem?mr=2494406">MR2494406</a></p>
<p>Under certain conditions, a filtration on an augmented algebra \(A\) admits
a related filtration on the Yoneda algebra \(\mathrm{E}(A) :=
\mathrm{Ext}_A(K,K)\). We show that there exists a bigraded algebra
monomorphism</p>
<p>\[\mathrm{gr}\;\mathrm{E}(A) \hookrightarrow \mathrm{E}_{\mathrm{Gr}}(\mathrm{gr}\;A),\]</p>
<p>where \(\mathrm{E}_{\mathrm{Gr}}(\mathrm{gr}\;A)\) is the graded Yoneda
algebra of \(\mathrm{gr}\;A\). This monomorphism can be applied in the
case where A is connected graded to determine that \(A\) has the
\(\mathcal{K}_2\) property recently introduced by Cassidy and Shelton.</p>
</li>
</ul>
<h2>Dissertation</h2>
<ul>
<li>
<p><a href="http://hdl.handle.net/1794/10367"><em>Koszul and generalized Koszul properties for noncommutative graded
algebras</em></a>, University of Oregon, Department
of Mathematics, 2009.</p>
<ul>
<li>Advisor: <a href="https://math.uoregon.edu/profile/shelton">Professor Brad Shelton</a></li>
</ul>
<p>We investigate some homological properties of graded algebras. If \(A\) is
an \(R\)-algebra, then \(\mathrm{E}(A):= \mathrm{Ext}_A(R,R)\) is an
\(R\)-algebra under the cup product and is called the Yoneda algebra. (In
most cases, we assume \(R\) is a field.) A well-known and widely-studied
condition on \(\mathrm{E}(A)\) is the Koszul property. We study a class of
deformations of Koszul algebras that arises from the study of equivariant
cohomology and algebraic groups and show that under certain circumstances
these deformations are Poincaré–Birkhoff–Witt deformations.</p>
<p>Some of our results involve the \(\mathcal{K}_2\) property, recently
introduced by Cassidy and Shelton, which is a generalization of the Koszul
property. While a Koszul algebra must be quadratic, a \(\mathcal{K}_2\)
algebra may have its ideal of relations generated in different degrees. We
study the structure of the Yoneda algebra corresponding to a monomial
\(\mathcal{K}_2\) algebra and provide an example of a monomial
\(\mathcal{K}_2\) algebra whose Yoneda algebra is not also
\(\mathcal{K}_2\). This example illustrates the difficulty of
finding a \(\mathcal{K}_2\) analogue of the classical theory of Koszul
duality.</p>
<p>It is well-known that Poincaré–Birkhoff–Witt algebras are Koszul. We find a
\(\mathcal{K}_2\) analogue of this theory. If \(V\) is a
finite-dimensional vector space with an ordered basis, and
\(A:=\mathbb{T}(V)/I\) is a connected-graded algebra, we can place a
filtration \(F\) on \(A\) as well as \(\mathrm{E}(A)\). We show there
is a bigraded algebra embedding</p>
<p>\[\Lambda: \mathrm{gr}\;\mathrm{E}(A) \hookrightarrow \mathrm{E}_{\mathrm{Gr}}(\mathrm{gr}\;A).\]</p>
<p>If \(I\) has a Gröbner basis meeting certain conditions and
\(\mathrm{gr}_F\;A\) is \(\mathcal{K}_2\), then \(\Lambda\) can be
used to show that \(A\) is also \(\mathcal{K}_2\).</p>
<p>This dissertation contains both previously published and co-authored materials.</p>
</li>
</ul>]]></content:encoded></item><item><title>“10 PRINT” in PostScript</title><link>https:://chrisphan.com/2019/02/18/10-print-in-postscript/index.html</link><description><![CDATA[ Back in May , I posted a LaTeX document using TikZ to implement the Commodore 64 BASIC program : The amusement factor (for me) is]]></description><guid>https:://chrisphan.com/2019/02/18/10-print-in-postscript/index.html</guid><pubDate>Mon, 18 Feb 2019 22:00:40 -0600</pubDate><content:encoded><![CDATA[
<p><a href="/2018/05/28/10-print-in-tikz/">Back in May</a>, I posted a LaTeX document using TikZ to implement the <a href="https://10print.org/">Commodore 64 BASIC program</a>:</p><div class="code_block"><div class="code-header"><span class="code-lang">BASIC</span></div><pre class=""  id="block-49dcf8a2-97f8-45a7-a570-69c13ed8ce4d"><code class="language-basic"><code class="checker "><span style="color:#839496;">10 PRINT CHR$(205.5+RND(1)); : GOTO 10</span></code>
</code></pre></div>
<p>The amusement factor (for me) is due to LaTeX's ability to generate pseudorandom
numbers, which may be surprising to some, especially those who think of LaTeX
documents as static (deterministic) documents and not computer programs.</p>
<p>PostScript can also generate pseudorandom numbers, and hence I present &quot;10
PRINT&quot; in PostScript:</p><div class="code_block"><div class="code-header"><span class="code-lang">PostScript</span></div><pre class=""  id="block-51f063af-187c-49e1-a659-7a3265a1e3c5"><code class="language-postscript"><code class="checker lineno dig-1"><span style="color:#839496;">%!</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">% Implementation of &quot;10 PRINT&quot; in PostScript</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">% Christopher Phan, cphan@chrisphan.com</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">% 2019-02-17</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">% Draw frame around page</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">newpath</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  36 36 moveto % 36 pt = 0.5 in</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  36 756 lineto % 756 pt = 10.5 in</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  576 756 lineto % 576 pt = 8 in</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  576 36 lineto</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  closepath</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">stroke</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">% each slash will occupy a 0.25 in x 0.25 in square</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">36 18 558 { % 18 pt = 0.25 in</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  /x exch def</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  36 18 738 {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    /y exch def</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    newpath</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      /u rand 2 mod 18 mul def</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      x y u add moveto</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      x 18 add y 18 u sub add lineto</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    closepath stroke</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  } for</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">} for</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">showpage</span></code>
</code></pre></div>
<p>Example output:</p>
<p><img src="/wp-content/uploads/10print.png" alt="A maze created by randomly placing walls. Each wall is in one of two perpendicular orientations." /></p>]]></content:encoded></item><item><title>“10 PRINT” in TikZ</title><link>https:://chrisphan.com/2018/05/28/10-print-in-tikz/index.html</link><description><![CDATA[ The book 10 PRINT CHR$(205.5+RND(1)); : GOTO 10 , by Nick Montfort, et. al. , uses a one-line Commodore 64 BASIC program “as a gateway]]></description><guid>https:://chrisphan.com/2018/05/28/10-print-in-tikz/index.html</guid><pubDate>Mon, 28 May 2018 16:42:51 -0500</pubDate><content:encoded><![CDATA[
<p>The book <a href="https://10print.org/"><cite>10 PRINT CHR$(205.5+RND(1)); : GOTO 10</cite>, by Nick Montfort, et. al.</a>, uses a one-line Commodore 64 BASIC program “as a gateway into a deeper understanding of how computing works in society and what the writing, reading, and execution of computer code mean” (p. 4). The focus is on the titular program, which the authors call <em>10 PRINT</em> for short:</p><div class="code_block"><div class="code-header"><span class="code-lang">BASIC</span></div><pre class=""  id="block-bb95e73d-6f08-482b-99e8-f1aaafef0fc6"><code class="language-basic"><code class="checker "><span style="color:#839496;">10 PRINT CHR$(205.5+RND(1)); : GOTO 10</span></code>
</code></pre></div>
<p>This program prints an infinite random sequence made up of the box-drawing characters ╱ and ╲ (that’s <a href="https://www.unicode.org/charts/PDF/U2500.pdf">U+2571 and U+2572</a>, respectively, encoded in the Commodore character set <a href="https://en.wikipedia.org/wiki/PETSCII">PETSCII</a> as 205 and 206.), in order to make a random maze. This produces an output similar to the following, except that the characters on a Commodore screen are more square:</p>
<p><img src="/wp-content/uploads/10_print.png" alt="A maze created by randomly placing walls. Each wall is in one of two not-quite perpendicular orientations." /></p>
<p>(<a href="https://10print.org/">The book’s web site</a> gives a better idea how the output on a Commodore would look.)</p>
<p>It’s not hard to reproduce <em>10 PRINT</em> in Python, albeit using more than one line:</p><div class="code_block"><div class="code-header"><span class="code-lang">Python</span></div><pre class=""  id="block-264d87a4-fb57-4398-b080-e8faac0fe911"><code class="language-python"><code class="checker lineno dig-0"><span style="color:#586e75;">#! /usr/bin/env python3</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#cb4b16;">import </span><span style="color:#839496;">random</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">for </span><span style="color:#839496;">j </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">24</span><span style="color:#657b83;">):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">print</span><span style="color:#657b83;">(</span><span style="color:#839496;">&quot;&quot;.</span><span style="color:#b58900;">join</span><span style="color:#657b83;">([</span><span style="color:#839496;">random.</span><span style="color:#b58900;">choice</span><span style="color:#657b83;">([</span><span style="color:#839496;">&quot;</span><span style="color:#dc322f;">\u2571</span><span style="color:#839496;">&quot;,&quot;</span><span style="color:#dc322f;">\u2572</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">])</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">for </span><span style="color:#839496;">k </span><span style="color:#859900;">in range</span><span style="color:#657b83;">(</span><span style="color:#6c71c4;">0</span><span style="color:#839496;">, </span><span style="color:#6c71c4;">40</span><span style="color:#657b83;">)]))</span></code>
</code></pre></div>
<p>(Instead of an infinite string, my program only outputs a 40 × 24 block of characters.) To get the output to look right, you might need to mess with the font settings in your Terminal. I found that that Melno Regular font on my Mac works.</p>
<p>But I really thought it would be more fun to obtain a <em>10 PRINT</em>-like output using TikZ, as TikZ is capable of generating random numbers! Instead of using the characters ╱ and ╲, I will draw the lines directly:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-e4c1734f-2327-4859-a288-db5b481ca18f"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">    </span><span style="color:#586e75;">% Draw background</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\fill</span><span style="color:#839496;">[blue!75!black] (0, 0) -- (0, 24) --</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    (40, 24) -- (40, 0) -- cycle;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#586e75;">% Draw maze</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\foreach \y</span><span style="color:#839496;"> in {0, ..., 23}{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\foreach \x</span><span style="color:#839496;"> in {0, ..., 39}{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">% Randomly choose a = 0 or a = 1</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">\pgfmathrandominteger</span><span style="color:#839496;">{</span><span style="color:#859900;">\a</span><span style="color:#839496;">}{0}{1};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">% If a = 0, then will draw SW-NE line</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#586e75;">% If a = 1, then will draw NW-SE line</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">\draw</span><span style="color:#839496;">[very thick, white] (</span><span style="color:#859900;">\x</span><span style="color:#839496;">, </span><span style="color:#859900;">\y</span><span style="color:#839496;"> + </span><span style="color:#859900;">\a</span><span style="color:#839496;">)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">          -- (</span><span style="color:#859900;">\x</span><span style="color:#839496;"> + 1, </span><span style="color:#859900;">\y</span><span style="color:#839496;"> + 1 - </span><span style="color:#859900;">\a</span><span style="color:#839496;">);</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      }</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    }</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>I really like the output:</p>
<p><img src="/wp-content/uploads/random_maze.png" alt="A maze created by randomly placing walls. Each wall is in one of two perpendicular orientations. The walls are white and the background is blue." /></p>]]></content:encoded></item><item><title>LaTeX mailmerge package</title><link>https:://chrisphan.com/2018/05/27/latex-mailmerge-package/index.html</link><description><![CDATA[ The LaTeX package is super useful, especially for creating multiple versions of tests. Before I discovered , my workflow for writing a test was basically:]]></description><guid>https:://chrisphan.com/2018/05/27/latex-mailmerge-package/index.html</guid><pubDate>Sun, 27 May 2018 21:40:57 -0500</pubDate><content:encoded><![CDATA[
<p>The LaTeX <a href="https://ctan.org/pkg/mailmerge?lang=en"><code>mailmerge</code> package</a> is super useful, especially for creating multiple versions of tests.</p>
<p>Before I discovered <code>mailmerge</code>, my workflow for writing a test was basically:</p>
<ul>
<li>Write one version of the test.</li>
<li>Make a duplicate of the file.</li>
<li>Edit the file to change all the constants.</li>
</ul>
<p>At least, that was my <em>intended</em> workflow. But typically I would also:</p>
<ul>
<li>Realize that there was some change I wanted to make to the test.</li>
<li>Painstakingly make the same change to both versions of the test, double-checking that the wording remained consistent between versions.</li>
</ul>
<p>Sometimes I would repeat the last two steps multiple times. This was obnoxiously inefficient.</p>
<p>Then I discovered the <code>mailmerge</code> package.</p>
<p>Here is a basic (silly) example illustrating how the package works:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-591b03ea-8c43-4407-8a59-cd8ffe243acb"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[letterpaper, 12pt]{</span><span style="color:#859900;">amsart</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">%% packages</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">mailmerge</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">url</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\title</span><span style="color:#839496;">{Some U.S.</span><span style="color:#cb4b16;">~</span><span style="color:#839496;">state capital facts}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\maketitle</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailrepeat</span><span style="color:#839496;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    The capital of </span><span style="color:#859900;">\field</span><span style="color:#839496;">{state} is </span><span style="color:#859900;">\field</span><span style="color:#839496;">{capital}.</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    The U.S. Census Bureau estimates that in mid-2017,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    there were </span><span style="color:#859900;">\field</span><span style="color:#839496;">{population} people living in</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\field</span><span style="color:#839496;">{capital}</span><span style="color:#859900;">\footnote</span><span style="color:#839496;">{</span><span style="color:#859900;">\field</span><span style="color:#839496;">{cite}}.</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  }</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailfields</span><span style="color:#839496;">{state,capital,population,cite}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Illinois,Springfield,</span><span style="color:#586e75;">%</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    {167,376},</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/YGDdE6}}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#586e75;">%% Draw a square:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\vskip</span><span style="color:#839496;"> 1 em</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\draw</span><span style="color:#839496;"> (0, 0) -- (1, 0)</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      -- (1, 1) -- (0, 1) -- cycle;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\vskip</span><span style="color:#839496;"> 1 em</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Minnesota,St.</span><span style="color:#cb4b16;">~</span><span style="color:#839496;">Paul,</span><span style="color:#586e75;">%</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    {306,621},</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/F6rXZ7}}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Oregon,Salem,</span><span style="color:#586e75;">%</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    {169,798},</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/Zc4tDC}}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Pennsylvania,Harrisburg,</span><span style="color:#586e75;">%</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    {49,192},</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/NQypQG}}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>This produces:</p>
<blockquote>
<div style="text-align:center">SOME U.S. STATE CAPITAL FACTS</div>
<p>The capital of Illinois is Springfield. The U.S. Census Bureau estimates that in mid-2017, there were 167,376 people living in Springfield<sup>1</sup>.</p>
<p><img src="/wp-content/uploads/tikzsquare.png" alt="A square" /></p>
<p>The capital of Minnesota is St. Paul. The U.S. Census Bureau estimates that in mid-2017, there were 306,621 people living in St. Paul<sup>2</sup>.</p>
<p>The capital of Oregon is Salem. The U.S. Census Bureau estimates that in mid-2017, there were 169,798 people living in Salem<sup>3</sup>.</p>
<p>The capital of Pennsylvania is Harrisburg. The U.S. Census Bureau estimates that in mid-2017, there were 49,192 people living in Harrisburg<sup>4</sup>.</p>
</blockquote>
<p>This is followed by the appropriate footnotes.</p>
<p><img src="/wp-content/uploads/example0-232x300.png" alt="Typeset output from first example." /></p>
<p>Notice:</p>
<ul>
<li>The text you want repeated is specified as the argument of the <code>\mailrepeat</code> macro.</li>
<li>Within the <code>\mailrepeat</code>, we specify the mail-merged info with <code>\field{</code>[field name]<code>}</code></li>
<li>The names of the mail merge fields are given as a comma-delimited list with the <code>\mailfields</code> macro.</li>
<li>The actual mail-merge is accomplished with the <code>\mailentry</code> macro. The argument to this macro is a comma-delimited list of the material to place into the fields.</li>
</ul>
<p>I put the silly TikZ square in this example to illustrate that the mail-merged text is placed where the <code>\mailentry</code> occurs in the code.</p>
<p>Spacing is significant in the <code>\mailentry</code> macro. If there is a space next to <code>\field{</code>[field name]<code>}</code> in the <code>\mailrepeat</code> <em>and</em> after the comma the corresponding field in the <code>\mailentry</code>, this will produce an awkward amount of space in the output. For example,</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-6fafa98a-4843-4510-ae7b-30ead6eb780c"><code class="language-latex"><code class="code-elipsis" id="block-6fafa98a-4843-4510-ae7b-30ead6eb780c-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Minnesota, St.</span><span style="color:#cb4b16;">~</span><span style="color:#839496;">Paul,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">{306,621},</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/F6rXZ7}}</span></code>
<code class="code-elipsis" id="block-6fafa98a-4843-4510-ae7b-30ead6eb780c-elipsis-end"></code>
</code></pre></div>
<p>will produce:</p>
<p><img src="/wp-content/uploads/misspaced.png" alt="Part of the output. &quot;The capital of Minnesota is  St. Paul. The U.S. Census Bureau estimates that in mid-2017, there were  306,621 people living in St. Paul&quot;. There is an awkward extra bit of space before the population and before each &quot;St. Paul&quot;" /></p>
<p>Notice the extra space before the two instances of “St. Paul” and before the population. Compare to what is produced when there is no space before the comma and there is a <code>%</code> before the line break (which prevents the line break from being treated as a space):</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-b2d5198b-2df3-4022-b05e-da0cf98eacd6"><code class="language-latex"><code class="code-elipsis" id="block-b2d5198b-2df3-4022-b05e-da0cf98eacd6-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Minnesota,St.</span><span style="color:#cb4b16;">~</span><span style="color:#839496;">Paul,</span><span style="color:#586e75;">%</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">{306,621},</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/F6rXZ7}}</span></code>
<code class="code-elipsis" id="block-b2d5198b-2df3-4022-b05e-da0cf98eacd6-elipsis-end"></code>
</code></pre></div>
<p><img src="/wp-content/uploads/wellspaced.png" alt="Part of the output. The same text as in the last graphic but no weird spaces" /></p>
<p>It’s <em>very subtle</em>, but I am a perfectionist.</p>
<p>If you have many fields, the comma-delimited list argument to the <code>\mailentry</code>
can get unwieldy. One trick I use is to end each entry with a comment containing
the field name:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-cabfa540-081f-405e-abb0-8a9facd27ffc"><code class="language-latex"><code class="code-elipsis" id="block-cabfa540-081f-405e-abb0-8a9facd27ffc-elipsis-start"></code>
<code class="checker "><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{Minnesota</span><span style="color:#586e75;">%state</span></code>
<code class="checker "><span style="color:#839496;">,St.</span><span style="color:#cb4b16;">~</span><span style="color:#839496;">Paul</span><span style="color:#586e75;">%capital</span></code>
<code class="checker "><span style="color:#839496;">,{306,621}</span><span style="color:#586e75;">%population</span></code>
<code class="checker "><span style="color:#839496;">,</span><span style="color:#859900;">\url</span><span style="color:#839496;">{https://goo.gl/F6rXZ7}</span><span style="color:#586e75;">%cite</span></code>
<code class="checker "><span style="color:#839496;">}</span></code>
<code class="code-elipsis" id="block-cabfa540-081f-405e-abb0-8a9facd27ffc-elipsis-end"></code>
</code></pre></div>
<p>Especially when the fields are difficult to tell apart based on content (e.g.,
when they are different constants for math problems), this makes it easier to
know which field you are changing. Also, the comments prevent any space or line
break before the comma from affecting the output.</p>
<p>For a test, each version would correspond to a single <code>\mailentry</code>. Consider
this made-up quiz, which has two versions (Form A and B):</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-ace45b1c-61f8-470d-be83-b46f6877ade9"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">[letterpaper, 11pt]{</span><span style="color:#859900;">article</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">%% packages</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">amsmath</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">mailmerge</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">enumitem</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fullpage</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailrepeat</span><span style="color:#839496;">{</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\setcounter</span><span style="color:#839496;">{page}{1}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\centerline</span><span style="color:#839496;">{</span><span style="color:#859900;">\textbf</span><span style="color:#839496;">{</span><span style="font-weight:bold;color:#839496;">Quiz </span><span style="font-weight:bold;color:#dc322f;">\#</span><span style="font-weight:bold;color:#839496;">1</span><span style="color:#839496;">}, Form </span><span style="color:#859900;">\field</span><span style="color:#839496;">{form}}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\vskip</span><span style="color:#839496;"> 1 em</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">enumerate</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\item</span><span style="color:#839496;"> (2 points) Expand</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      \(</span><span style="color:#859900;">\left</span><span style="color:#cb4b16;">(</span><span style="color:#268bd2;">x</span><span style="color:#859900;">^</span><span style="color:#839496;">{</span><span style="color:#859900;">\field</span><span style="color:#839496;">{</span><span style="color:#268bd2;">exponent</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">}} </span><span style="color:#859900;">+ </span><span style="color:#6c71c4;">2</span><span style="color:#268bd2;">x</span><span style="color:#859900;">\right</span><span style="color:#cb4b16;">)</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">\).</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\vfill</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\item</span><span style="color:#839496;"> (3 points) Suppose</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      \(</span><span style="color:#268bd2;">f</span><span style="color:#cb4b16;">(</span><span style="color:#268bd2;">x</span><span style="color:#cb4b16;">) </span><span style="color:#859900;">=</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">\field</span><span style="color:#839496;">{</span><span style="color:#268bd2;">coeff</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">}</span><span style="color:#268bd2;">x</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">2 </span><span style="color:#859900;">+ \field</span><span style="color:#839496;">{</span><span style="color:#268bd2;">coeff</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">}</span><span style="color:#268bd2;">x </span><span style="color:#859900;">+ </span><span style="color:#6c71c4;">1</span><span style="color:#839496;">\).</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      Find \(</span><span style="color:#268bd2;">f</span><span style="color:#cb4b16;">(</span><span style="color:#6c71c4;">5</span><span style="color:#cb4b16;">)</span><span style="color:#839496;">\).</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\vfill</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">enumerate</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\newpage</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">enumerate</span><span style="color:#839496;">}[resume]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\item</span><span style="color:#839496;"> (5 points) Solve for \(</span><span style="color:#268bd2;">x</span><span style="color:#839496;">\):</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      \[</span><span style="color:#859900;">\field</span><span style="color:#839496;">{</span><span style="color:#268bd2;">coeff</span><span style="color:#6c71c4;">3</span><span style="color:#839496;">}</span><span style="color:#268bd2;">x</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">4 </span><span style="color:#859900;">- \field</span><span style="color:#839496;">{</span><span style="color:#268bd2;">coeff</span><span style="color:#6c71c4;">4</span><span style="color:#839496;">}</span><span style="color:#268bd2;">x</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">3</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">        </span><span style="color:#859900;">= </span><span style="color:#6c71c4;">0</span><span style="color:#839496;">\]</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">      </span><span style="color:#859900;">\vfill</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">enumerate</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">    </span><span style="color:#859900;">\newpage</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  }</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#586e75;">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#586e75;">%%% Mail merge info:</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailfields</span><span style="color:#839496;">{form, coeff1, coeff2,</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  coeff3, coeff4, exponent1}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{A</span><span style="color:#586e75;">%form</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,6</span><span style="color:#586e75;">%coeff1</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,8</span><span style="color:#586e75;">%coeff2</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,2</span><span style="color:#586e75;">%coeff3</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,7</span><span style="color:#586e75;">%coeff4</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,3</span><span style="color:#586e75;">%exponent1</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  }</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  </span><span style="color:#859900;">\mailentry</span><span style="color:#839496;">{B</span><span style="color:#586e75;">%form</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,5</span><span style="color:#586e75;">%coeff1</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,9</span><span style="color:#586e75;">%coeff2</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,3</span><span style="color:#586e75;">%coeff3</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,5</span><span style="color:#586e75;">%coeff4</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  ,5</span><span style="color:#586e75;">%exponent1</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">  }</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>At the start of the <code>\mailrepeat</code>ed code is the macro <code>\setcounter{page}{1}</code>,
which resets the page number to 1; otherwise, Form B would start on Page 3.
Also, I ended the <code>\mailrepeat</code>ed code with a <code>\newpage</code>, ensuring that each
version is on a separate page.</p>
<p>If you print \(\lceil N/2\rceil\) copies of the resulting PDF (where \(N\)
is the number of students in your course), two-sided, then the pile of quizzes
will be alternated by version as they come out of the printer, ready to hand out
to your class.</p><div class="code_block"><pre class=""  id="block-1b02f067-e73e-4d09-a3c1-411ab1b06c1b"><code><code class="checker "><span style="color:#839496;"></span></code>
</code></pre></div>]]></content:encoded></item><item><title>LaTeX menukeys package</title><link>https:://chrisphan.com/2018/04/27/latex-menukeys-package/index.html</link><description><![CDATA[ I’d like to put in a quick word in favor the LaTeX package. This package makes really nice menu sequences, which is useful when you]]></description><guid>https:://chrisphan.com/2018/04/27/latex-menukeys-package/index.html</guid><pubDate>Fri, 27 Apr 2018 10:52:22 -0500</pubDate><content:encoded><![CDATA[
<p>I’d like to put in a quick word in favor the LaTeX <a href="https://www.ctan.org/tex-archive/macros/latex/contrib/menukeys"><code>menukeys</code></a>
package. This package makes really nice menu sequences, which is useful when you
have to explain how to use software.</p>
<p>For example, <code>\menu[&gt;]{Tools &gt; Web Developer &gt; Page Source}</code> produces:</p>
<img src="/wp-content/uploads/menukeys_demo-300x24.png" alt="Tools > Web Developer > Page Source" class="white_bk" />]]></content:encoded></item><item><title>Why I use version control</title><link>https:://chrisphan.com/2018/04/13/why-i-use-version-control/index.html</link><description><![CDATA[ Oh, crap! I wanted to copy that to , not overwrite ! Whew!!]]></description><guid>https:://chrisphan.com/2018/04/13/why-i-use-version-control/index.html</guid><pubDate>Fri, 13 Apr 2018 13:07:23 -0500</pubDate><content:encoded><![CDATA[<div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">cp</span><span style="color:#839496;"> t_test3.pg inclass_t_test2.pg</span></code>
</code></pre></div></div></div>
<p>Oh, crap! I wanted to copy that to <code>inclass_t_test3.pg</code>, <em>not</em> overwrite <code>inclass_t_test2.pg</code>!</p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">git</span><span style="color:#839496;"> status</span></code>
</code></pre></div><div class="repl_output">
<pre>
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git checkout -- ..." to discard changes in working directory)

        modified: inclass_t_test2.pg

no changes added to commit (use "git add" and/or "git commit -a")
</pre>
</div><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">git</span><span style="color:#839496;"> checkout</span><span style="color:#859900;"> --</span><span style="color:#839496;"> inclass_t_test2.pg</span></code>
<code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">git</span><span style="color:#839496;"> status</span></code>
</code></pre></div><div class="repl_output">
<pre>
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
</pre>
</div></div></div>
<p><em>Whew!!</em></p><div class="code_block"><div class="code-header"><span class="code-lang">Bash</span></div><div class="repl_session"><div class="repl_prompt_input"><pre><code class="language-bash"><code class="bash_repl_repl_prompt_0"><span style="color:#b58900;">cp</span><span style="color:#839496;"> t_test3.pg inclass_t_test3.pg</span></code>
</code></pre></div></div></div>]]></content:encoded></item><item><title>I’ve (mostly) stopped using Facebook</title><link>https:://chrisphan.com/2017/08/02/ive-mostly-stopped-using-facebook/index.html</link><description><![CDATA[ I have mostly stopped using Facebook. I’ve only made two posts to my own timeline since the beginning of the year, and one was to]]></description><guid>https:://chrisphan.com/2017/08/02/ive-mostly-stopped-using-facebook/index.html</guid><pubDate>Wed, 2 Aug 2017 20:32:34 -0500</pubDate><content:encoded><![CDATA[
<p><strong>I have mostly stopped using Facebook.</strong> I’ve only made two posts to my own timeline since the beginning of the year, and one was to update my bio with a message explaining that I’ve stopped using Facebook (which I will probably edit to include a link to this post). I’m not a <a href="https://twitter.com/doctorow/status/647448263860187136">“Facebook vegan”</a>: I still log in (occasionally) and comment or like others’ posts (even less occasionally). I also occasionally make posts for various organizations with which I’m involved (but I post them to those organizations’ pages). But I don’t log in daily (or even weekly), as I used to do.</p>
<p>At this moment, I’m not going to write a long essay about why I’ve (mostly) stopped using Facebook, and I’m not going to tell everyone else they should, either. It’s true that I have some serious concerns about Facebook and its impact on the world, many of which <a href="http://www.slate.com/articles/technology/future_tense/2017/05/sci_fi_doesn_t_predict_the_future_it_influences_it.html">have been explained by Cory Doctorow</a> better than I could. However, <strong>my main reason for (mostly) eschewing Facebook is personal</strong>: I became convinced late last year that my use of Facebook was harmful to my mental health, and drastically reducing my participation with Facebook has been a positive change for me.</p>
<p>So, please don’t take it personally if I don’t respond to your friend request, comment, or post in which you tagged me. (It’s likely I didn’t see it) And if you want to communicate with me, you’ll have much better luck if you use email or phone, rather than Facebook.</p>]]></content:encoded></item><item><title>Some politics observations, 2017-02-28</title><link>https:://chrisphan.com/2017/02/28/some-politics-observations-2017-02-28/index.html</link><description><![CDATA[ Some observations: Refugees are risking frostbite to flee the U.S. for Canada . This is a very sad commentary on the lack of compassion from]]></description><guid>https:://chrisphan.com/2017/02/28/some-politics-observations-2017-02-28/index.html</guid><pubDate>Tue, 28 Feb 2017 21:54:49 -0600</pubDate><content:encoded><![CDATA[
<p>Some observations:</p>
<ul>
<li>
<p><a href="http://www.mprnews.org/story/2017/02/21/refugees-minnesota-risk-death-to-cross-into-canada">Refugees are risking frostbite to flee the U.S. for Canada</a>. This is a very sad commentary on the lack of compassion from our current administration.</p>
</li>
<li>
<p>I signed the <a href="https://www.uua.org/pressroom/press-releases/calling-all-friends-faith-and-conscience-invitation-uua-president-and-uusc">Unitarian Universalist Association’s declaration of conscience</a>, and encourage you to consider signing it as well.</p>
</li>
<li>
<p>I agree with Congressman Ellison:</p>
<blockquote class="twitter-tweet" data-lang="en">
  <p lang="en" dir="ltr">
    To all my supporters: we may have come up short, but we need to be united. I look forward to continuing to work for the people in MN-05. <a href="https://t.co/sab2fUmDZu">pic.twitter.com/sab2fUmDZu</a>
  </p>
  <p>
    &mdash; Ellison for Congress (@EllisonCampaign) <a href="https://twitter.com/EllisonCampaign/status/835594185122131968">February 25, 2017</a>
  </p>
</blockquote>
<p>Democrats need to stay united! We need to work together to regain as many seats in Congress as we can in 2018.</li> </ul></p>
</li>
</ul>]]></content:encoded></item><item><title>Adventures in TikZ: tkz-graph</title><link>https:://chrisphan.com/2017/02/22/adventures-in-tikz-tkz-graph/index.html</link><description><![CDATA[ The other day, I was writing some lecture notes for my linear algebra class, and wanted to create the following diagram (to illustrate the concept]]></description><guid>https:://chrisphan.com/2017/02/22/adventures-in-tikz-tkz-graph/index.html</guid><pubDate>Wed, 22 Feb 2017 22:32:15 -0600</pubDate><content:encoded><![CDATA[
<p>The other day, I was writing some lecture notes for my linear algebra class, and
wanted to create the following diagram (to illustrate the concept of a Markov
chain):</p>
<p><img src="/wp-content/uploads/markov_chain_pic1-209x300.png"
alt="Weighted directed graph for a Markov chain"
class="white_bk" /></p>
<p>I had a very limited time in which to finish these notes. Fortunately, I found the <a href="https://www.ctan.org/pkg/tkz-graph?lang=en"><code>tkz-graph</code> package</a>, which made this a snap:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-5931f208-2863-49d9-8026-7c9e306e8e2d"><code class="language-latex"><code class="checker lineno dig-1"><span style="color:#859900;">\documentclass</span><span style="color:#839496;">{</span><span style="color:#859900;">standalone</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tikz</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">fouriernc</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\usepackage</span><span style="color:#839496;">{</span><span style="color:#859900;">tkz-graph</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-1"><span style="color:#859900;">\SetGraphUnit</span><span style="color:#839496;">{5}</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Vertex</span><span style="color:#839496;">[x=0, y=10]{0 points};</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Vertex</span><span style="color:#839496;">[x=0, y=5]{1 point};</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Vertex</span><span style="color:#839496;">[x=0, y=0]{Win};</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Vertex</span><span style="color:#839496;">[x=5, y=5]{Lose};</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Edge</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#859900;">/</span><span style="color:#6c71c4;">3</span><span style="color:#839496;">$}]({0 points})({1 point});</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Edge</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#859900;">/</span><span style="color:#6c71c4;">3</span><span style="color:#839496;">$}]({1 point})({Win});</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Edge</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#859900;">/</span><span style="color:#6c71c4;">6</span><span style="color:#839496;">$}]({0 points})({Lose});</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Edge</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#859900;">/</span><span style="color:#6c71c4;">6</span><span style="color:#839496;">$}]({1 point})({Lose});</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Loop</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#859900;">/</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">$}, labelstyle={fill=white}]({0 points});</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Loop</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#859900;">/</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">$}, labelstyle={fill=white}]({1 point});</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Loop</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">$}, dir=EA, labelstyle={fill=white}]({Lose});</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\Loop</span><span style="color:#839496;">[style ={-&gt;}, label={$</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">$}, labelstyle={fill=white}]({Win});</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">tikzpicture</span><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">document</span><span style="color:#839496;">}</span></code>
</code></pre></div>
<p>You don’t even have to specify the locations of the vertices; you can throw caution to the wind and have LaTeX decide where to place them! (I am a bit too much of a perfectionist for that.)</p>
<p>One slight issue I had was that the documentation for this package (at least on my computer, as retrieved by <a href="https://www.tug.org/texdoc/"><code>texdoc</code></a>) was in French. Fortunately, I seem to have retained enough knowledge since I took the French language exam as a grad student that I could read most of the documentation.</p>]]></content:encoded></item><item><title>It’s been a long time</title><link>https:://chrisphan.com/2017/02/12/its-been-a-long-time/index.html</link><description><![CDATA[ It’s been a long time (over a year) since I’ve posted on this blog, because I have (to put it mildly) been very busy with]]></description><guid>https:://chrisphan.com/2017/02/12/its-been-a-long-time/index.html</guid><pubDate>Sun, 12 Feb 2017 17:26:53 -0600</pubDate><content:encoded><![CDATA[
<p>It’s been a long time (over a year) since I’ve posted on this blog, because I have (to put it mildly) been very busy with other responsibilities and passions that have taken me away from blogging. Also, I serve as a (low-level, volunteer-basis) officer in a political party, and as a result, I am sometimes reluctant to post my opinions in public, for fear that they might be taken (or portrayed) as official statements, despite my <a href="https://blog.chrisphan.com/disclaimer/">disclaimer</a> (which, to be clear, says that everything written here is my personal opinion and does not reflect the position of my employer or any organization of which I am a member).</p>
<p>However, <strong>we are now facing a national emergency</strong>, and it is important for people to speak out. And I’ve decided that I distrust Twitter and Facebook as platforms for doing so (a topic on which I will elaborate later), leading to my desire to start writing again here. I certainly don’t have time for this, but I am going to try to make the time, hopefully posting here more frequently than once every two years.</p>
<p>I have also added https/SSL to this blog, using <a href="https://letsencrypt.org/">Let’s Encrypt</a>. I took this step a few months ago, right as the national emergency began, and promptly could not log into the interface for this blog. Because I was (and continue to be) so busy, I put off fixing the problem, only to discover that the problem seems to have fixed itself. Go figure.</p>
<p>While I do plan on talking about politics on this blog, I also have other interests (<a href="http://chrisphan.com/dissertation.pdf">mathematics</a>, for example), and so I will be posting on these as well.</p>
<p>By the way, I don’t have time for comment moderation, so I don’t plan to enable comments on my posts.</p>]]></content:encoded></item><item><title>Book recommendation: How Not to Be Wrong</title><link>https:://chrisphan.com/2015/09/26/book-recommendation-how-not-to-be-wrong/index.html</link><description><![CDATA[ Today, I finished reading How Not to Be Wrong: The Power of Mathematical Thinking by Jordan Ellenberg. This is a very enjoyable, very well-written, general-audience]]></description><guid>https:://chrisphan.com/2015/09/26/book-recommendation-how-not-to-be-wrong/index.html</guid><pubDate>Sat, 26 Sep 2015 22:14:39 -0500</pubDate><content:encoded><![CDATA[
<p>Today, I finished reading <a href="http://www.jordanellenberg.com/how-not-to-be-wrong/"><cite>How Not to Be Wrong: The Power of Mathematical Thinking</cite></a> by Jordan Ellenberg. This is a very enjoyable, very well-written, general-audience book about mathematics, which I recommend whole-heartedly.</p>
<p>Ellenberg, a math professor at the University of Wisconsin, does a great job weaving together a plethora of mathematical topics, including non-Euclidean geometry, probability, statistics, and mathematical analysis of voting systems. He writes in a way that someone who only vaguely remembers—or never really understood—high school algebra would be able to follow and enjoy. His exposition is made more lively by a cast of historical and contemporary characters, some famous and some primarily known only to mathematicians, including Abraham Wald, Bernhard Riemann, Teddy Roosevelt, Francis Galton, Voltaire, Nicolas de Condorcet, David Hilbert, Ronald Fisher, Antonin Scalia, and Nate Silver. (My favorite line in the book is the one in which Ellenberg describes Silver as a “Kurt Cobain of probability.”)</p>
<p>The best part of the book is about how the Massachusetts Lottery ran a game in which it was occasionally profitable to play (that is, there were some drawings in which the expected value of a ticket’s winnings was higher than the price of a ticket). Of course, some smart people (e.g. an MIT student) figured this out and recruited investors to buy absurd numbers of tickets for the profitable drawings. In the course of telling this story, Ellenberg weaves in discussions of finite geometries and error-correcting codes, both of which are relevant in describing how one buys thousands of lottery tickets without accidentally having to split winnings with yourself.</p>
<p>I think it would be awesome to use this book in a gen-ed math class.</p>]]></content:encoded></item><item><title>In defense of FERPA</title><link>https:://chrisphan.com/2015/09/12/in-defense-of-ferpa/index.html</link><description><![CDATA[ In an op-ed piece titled “ College kids have too much privacy “, Michele Willens criticizes the Family Educational Rights and Privacy Act (FERPA) for]]></description><guid>https:://chrisphan.com/2015/09/12/in-defense-of-ferpa/index.html</guid><pubDate>Sat, 12 Sep 2015 21:25:16 -0500</pubDate><content:encoded><![CDATA[
<p>In an op-ed piece titled “<a href="http://www.latimes.com/opinion/op-ed/la-oe-0906-willens-ferpa-20150908-story.html">College kids have too much privacy</a>“, Michele Willens criticizes the Family Educational Rights and Privacy Act (FERPA) for making it difficult for families to monitor their college student children’s academic performance.</p>
<p>I can understand why some families are frustrated by FERPA. Many families spend a great deal of money to send their young to college. Consider the parents in Willens’s opening anecdote, who learned their daughter had not actually graduated and skipped class for the last two years. I think anyone would be angry to be in their shoes.</p>
<p>However, it’s just not true that FERPA means, as Willens puts it, that “you have to take [your kid’s] word for it when they say ‘everything’s fine.'” FERPA allows a student to voluntarily release their records to another party. I recall having at least one scholarship in college whose sponsors required me to send an official transcript every year. I don’t see why a parent couldn’t insist on this as a condition for continued financial support.</p>
<p>In addition, a student can sign a FERPA waiver allowing a third party to get their records directly from the school. Although Willens describes this as a “laborious process”, it really amounts to having a student sign a form or check a box on a web site.</p>
<p>Part of being in college is learning how to become an independent adult. The transfer of FERPA rights from parents to student is part of that process. So is students learning to take responsibility for their learning. All FERPA requires is for parents to deal with their adult children directly, as adults, rather than being able to go behind their back.</p>]]></content:encoded></item><item><title>Some thoughts about online discourse</title><link>https:://chrisphan.com/2015/05/15/some-thoughts-about-online-discourse/index.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/2015/05/15/some-thoughts-about-online-discourse/index.html</guid><pubDate>Fri, 15 May 2015 09:41:32 -0500</pubDate><content:encoded><![CDATA[
<blockquote class="twitter-tweet" lang="en">
  <p lang="en" dir="ltr">
    I hate it when people reply or comment to something you posted, in a way that makes it clear they didn't read what you wrote or posted, (1/)
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321083747/https://twitter.com/functoruser/status/599202299949424641">May 15, 2015</a>
  </p>
</blockquote>
<blockquote class="twitter-tweet" lang="en">
  <p lang="en" dir="ltr">
    and that they were just looking for an argument. It's disrespectful and rude. Also, I'm not looking for arguments on the Internet. (2/)
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321234341/https://twitter.com/functoruser/status/599202517419855875">May 15, 2015</a>
  </p>
</blockquote>
<blockquote class="twitter-tweet" lang="en">
  <p lang="en" dir="ltr">
    I'm looking for dialogue, discussion, and reasonable disagreement. Debate is good. Glib, unnecessarily aggressive responses are not. (3/3)
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160322003059/https://twitter.com/functoruser/status/599202931880013824">May 15, 2015</a>
  </p>
</blockquote>]]></content:encoded></item><item><title>Busy recently…</title><link>https:://chrisphan.com/2014/10/19/busy-recently/index.html</link><description><![CDATA[ I’ve been very busy recently with work and various other things recently.]]></description><guid>https:://chrisphan.com/2014/10/19/busy-recently/index.html</guid><pubDate>Sun, 19 Oct 2014 17:40:24 -0500</pubDate><content:encoded><![CDATA[
<p>I’ve been very busy recently with work and various other things recently.</p>
<blockquote class="twitter-tweet" lang="en">
  <p>
    <a href="/note_about_tweets/">pic.twitter.com/o0PnRFbCq9</a>
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321133113/https://twitter.com/functoruser/status/523881486840528897">October 19, 2014</a>
  </p>
</blockquote>]]></content:encoded></item><item><title>Sum question!</title><link>https:://chrisphan.com/2014/09/24/sum-question/index.html</link><description><![CDATA[ The American Mathematical Society made the following amusing post to their Facebook page today: It's National Punctuation Day (at least in the U,S,)! To honor]]></description><guid>https:://chrisphan.com/2014/09/24/sum-question/index.html</guid><pubDate>Wed, 24 Sep 2014 19:51:21 -0500</pubDate><content:encoded><![CDATA[
<p>The <a href="http://www.ams.org">American Mathematical Society</a> made <a href="https://www.facebook.com/amermathsoc/posts/10154669168520217">the following amusing post</a> to their Facebook page today:</p>
<blockquote>
<p>It's National Punctuation Day (at least in the U,S,)! To honor the occasion, for positive integers n, let n? = 1 + 2 + ... + n. What is 3???? (Hint: &lt; 1000)</p>
</blockquote>
<p>You can calculate 3???? = 26796, which of course is greater than 1000.</p>
<p>The joke is that they aren’t asking you to calculate 3????. They are asking you to calculate 3???. (This is 231.) The last question mark in the sentence “What is 3????” is the punctuation that ends the sentence, not the postfix notation for adding the first <em>n</em> positive integers. You could rewrite the sentence as “Find 3???.” Of course, that wouldn’t be as funny.</p>]]></content:encoded></item><item><title>MVPB and me, yesterday morning</title><link>https:://chrisphan.com/2014/08/14/mvpb-and-me-yesterday-morning/index.html</link><description><![CDATA[ He’s really growing!]]></description><guid>https:://chrisphan.com/2014/08/14/mvpb-and-me-yesterday-morning/index.html</guid><pubDate>Thu, 14 Aug 2014 22:07:46 -0500</pubDate><content:encoded><![CDATA[
<blockquote class="twitter-tweet" lang="en">
  <p>
    Good morning! <a href="/note_about_tweets/">pic.twitter.com/qR3phXAszo</a>
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321083819/https://twitter.com/functoruser/statuses/499555484085411841">August 13, 2014</a>
  </p>
</blockquote>
<p>He’s really growing!</p>]]></content:encoded></item><item><title>Not all cars</title><link>https:://chrisphan.com/2014/06/23/not-all-cars/index.html</link><description><![CDATA[ Imagine there was a serious manufacturing defect present in about six percent of cars. This defect caused a malfunction that could seriously injure the car’s]]></description><guid>https:://chrisphan.com/2014/06/23/not-all-cars/index.html</guid><pubDate>Mon, 23 Jun 2014 09:55:44 -0500</pubDate><content:encoded><![CDATA[
<p>Imagine there was a serious manufacturing defect present in about six percent of cars. This defect caused a malfunction that could seriously injure the car’s passengers. Of course, consumers would demand action to eradicate this defect. Suppose auto industry representatives dismissed these concerns by protesting “<strong>Not all cars</strong> blow up because of this defect.”</p>]]></content:encoded></item><item><title>This joke is awesome and deserves more than just a retweet</title><link>https:://chrisphan.com/2014/06/11/this-is-awesome-and-deserves-more-than-just-a-retweet/index.html</link><description><![CDATA[ This joke is awesome and deserves more than just a retweet: I'd wager that right now, Eric Cantor’s sorrows are… (•_•) ( •_•)>⌐■-■ (⌐■_■) uncountable.]]></description><guid>https:://chrisphan.com/2014/06/11/this-is-awesome-and-deserves-more-than-just-a-retweet/index.html</guid><pubDate>Wed, 11 Jun 2014 16:20:00 -0500</pubDate><content:encoded><![CDATA[
<p>This joke is awesome and deserves more than just a retweet:</p>
<blockquote class="twitter-tweet" lang="en">
<p>I'd wager that right now, Eric Cantor’s sorrows are…</p>
<p>

<br />
(•_•) 
<br />
( •_•)&gt;⌐■-■<br />

(⌐■_■)

</p>
<p>uncountable.</p>
<p>— “patrick” (@importantshock) <a href="https://twitter.com/importantshock/statuses/476528066605621249">June 11, 2014</a></p>
</blockquote>
<p><small>(<a href="http://en.wikipedia.org/wiki/Cantor's_diagonal_argument">Georg Cantor’s diagonal argument</a> shows that the real numbers are uncountable.)</small></p>]]></content:encoded></item><item><title>Um, some conservatives DO dispute E=mc^2</title><link>https:://chrisphan.com/2014/06/08/um-some-conservatives-do-dispute-emc2/index.html</link><description><![CDATA[ A few times on my Facebook news feed, I’ve noticed a graphic with a photo of astrophysicist and (awesome) science popularizer Neil deGrasse Tyson and]]></description><guid>https:://chrisphan.com/2014/06/08/um-some-conservatives-do-dispute-emc2/index.html</guid><pubDate>Sun, 8 Jun 2014 15:20:03 -0500</pubDate><content:encoded><![CDATA[
<p>A few times on my Facebook news feed, I’ve noticed <a href="https://www.facebook.com/photo.php?fbid=780481785326015&amp;set=a.367249613315903.85664.354522044588660&amp;type=1&amp;permPage=1">a graphic</a> with a
photo of astrophysicist and (awesome) science popularizer Neil deGrasse Tyson
and this quotation of him (emphasis and ellipsis in original):</p>
<blockquote>
<p><strong>Climate change</strong> has taken on political dimensions… That’s odd
because I don’t see people choosing sides over \(E=mc^2\) or other
<strong>fundamental facts of science!</strong></p>
</blockquote>
<p>It appears that Dr. Tyson has not checked out Conservapedia, a right-wing
competitor to Wikiepdia. (I certainly don’t blame him for
this—he’s got to have much better things to do than read a web site
full of stupid garbage.) Conservapedia takes issue with relativity overall, <a
href="http://conservapedia.com/index.php?title=E%3Dmc%C2%B2&#038;oldid=1085203"
rel="nofollow">and says of \(E=mc^2\)</a> (emphasis in original):</p>
<blockquote>
<p>Political pressure, however, has since made it impossible for anyone pursuing
an academic career in science to even question the validity of this
nonsensical equation. <strong>Simply put, \(E=mc^2\) is liberal claptrap.</strong></p>
</blockquote>
<p>(The whole \(E=mc^2\) Conservapedia article is actually pretty funny. My wife,
who is a physicist, thought it was a joke.)</p>
<p>Conservapedia is a project of Andrew Schlafly, son of prominent conservative
activist Phyllis Schlafly. Indeed, you can see from my link above (adorned with
<code>rel=&quot;nofollow&quot;</code>, of course!) that the most recent edit to the \(E=mc^2\)
article was by Mr. Schlafly himself.</p>]]></content:encoded></item><item><title>Stop punching down at millennials</title><link>https:://chrisphan.com/2014/06/06/stop-punching-down-at-millennials/index.html</link><description><![CDATA[ I absolutely hate millennial-bashing. While I don’t consider myself a millennial—I’m just a tad bit too old—I have a great deal of sympathy and affinity]]></description><guid>https:://chrisphan.com/2014/06/06/stop-punching-down-at-millennials/index.html</guid><pubDate>Fri, 6 Jun 2014 11:49:56 -0500</pubDate><content:encoded><![CDATA[
<blockquote class="twitter-tweet" lang="en">
  <p>
    Um, complaining loudly in a coffee shop about how much you dislike millennials is pretty rude.
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321205139/https://twitter.com/functoruser/statuses/474944390184833024">June 6, 2014</a>
  </p>
</blockquote>
<blockquote class="twitter-tweet" lang="en">
  <p>
    Also, it's hilarious how your complaint boils down to "They were raised poorly." And whose fault would that be?
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160322003834/https://twitter.com/functoruser/statuses/474944905257951232">June 6, 2014</a>
  </p>
</blockquote>
<blockquote class="twitter-tweet" lang="en">
  <p>
    At least my parents raised me to know that complaining about people loudly in coffee shops (and making gross generalizations) is rude.
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321205127/https://twitter.com/functoruser/statuses/474945247357960192">June 6, 2014</a>
  </p>
</blockquote>
<blockquote class="twitter-tweet" lang="en">
  <p>
    (FWIW, I don't think millennials were raised poorly.)
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="https://web.archive.org/web/20160321194552/https://twitter.com/functoruser/statuses/474945827098873856">June 6, 2014</a>
  </p>
</blockquote>
<p><strong>I absolutely hate millennial-bashing.</strong> While I don’t consider myself a
millennial—I’m just a tad bit too old—I have a great deal of
sympathy and affinity for that generation. That generation has been dealt a bad
hand. Many of the manufacturing jobs that provide a path to prosperity for those
without college degrees have been moved overseas, and as a result millennials
desiring prosperity were told they had to go to college. Alas, millennials did
not enjoy the same level of government subsidy for their college education as
their parents, so many of them have been saddled with crippling amounts of
student debt. Furthermore, many millennials came out of college right as the
economy tanked due to the financial sins of their parents’ generation.
Yet, it’s common to hear people blame millennials for their inability to
launch.</p>
<p>Annoyingly, much of the millennial-bashing you hear boils down to complaints
about how they were raised. Millennials, many baby boomers will tell you, were
praised too much as children. There was too much emphasis on self-esteem. <a href="http://waitbutwhy.com/2013/09/why-generation-y-yuppies-are-unhappy.html">They
were given too high of expectations by their parents.</a> For whatever
it’s worth, I think these complaints are over-wrought. In my experience,
millennials don’t suffer from too much self-esteem and many have adjusted
expectations—I think more than they should have to—to today’s
economic realities. But even if these complaints were accurate, it takes quite a
bit of chutzpah for someone to say, essentially, “Ha ha, your generation
sucks because we did a poor job raising you!”</p>
<p>Millennial-bashing by older people is good example of “punching
down”, that is, it’s people using their power to attack someone with
less power—which I find very distasteful. And criticism of millennials is
used as a convenient excuse to avoid questioning the policy decisions (such as
financial deregulation, globalization, and defunding of post-secondary
education) that have put that generation at a disadvantage.</p>]]></content:encoded></item><item><title>Tech support scam</title><link>https:://chrisphan.com/2014/06/03/tech-support-scam/index.html</link><description><![CDATA[ Today, I was the target of a tech support scam. I received a phone call from someone purporting to work in tech support. The caller]]></description><guid>https:://chrisphan.com/2014/06/03/tech-support-scam/index.html</guid><pubDate>Tue, 3 Jun 2014 20:24:34 -0500</pubDate><content:encoded><![CDATA[
<p>Today, I was the target of a tech support scam.</p>
<p>I received a phone call from someone purporting to work in tech support. The caller said they were calling about my Windows computer. Thinking they might have the wrong number, I replied that I didn’t have a Windows computer. The caller then hung up, without even apologizing or saying goodbye.</p>
<p>The abrupt ending of the call made me suspicious, and so I did some research. It turns out that this is known scam. I found information from both the Federal Trade Commission and Microsoft about this scam:</p>
<ul>
<li><a href="http://www.consumer.ftc.gov/articles/0346-tech-support-scams">FTC: “Tech Support Scams”</a></li>
<li><a href="https://www.microsoft.com/en-us/safety/online-privacy/avoid-phone-scams.aspx">Microsoft: “Avoid tech support phone scams”</a></li>
</ul>
<p>According to these sites, the scammers sometimes try to convince you that your computer has a virus or malware, and then trick you into installing malware or divulging your password or credit card number. Sometimes the scammers claim to be working for Microsoft or tech support providers.</p>
<p>I ran the caller’s number through a search engine, and found reports from others that are consistent with Microsoft’s and the FTC’s descriptions of the scam.</p>
<p>I decided to post about my experience in order to spread the word about these scams. In closing, here’s <a href="http://www.consumer.ftc.gov/articles/0346-tech-support-scams">some of the FTC’s advice</a> for those cold-called about computer security issues:</p>
<blockquote>
<p>If you get a call from someone who claims to be a tech support person, hang up and call the company yourself on a phone number you know to be genuine. A caller who creates a sense of urgency or uses high-pressure tactics is probably a scam artist.</p>
</blockquote>]]></content:encoded></item><item><title>Brains over calculators, part 2.</title><link>https:://chrisphan.com/2014/05/22/brains-over-calculators-part-2/index.html</link><description><![CDATA[ I recently found another calculation that I would consider reasonable for my students to perform that their calculators cannot . On my Calc II students’]]></description><guid>https:://chrisphan.com/2014/05/22/brains-over-calculators-part-2/index.html</guid><pubDate>Thu, 22 May 2014 16:21:47 -0500</pubDate><content:encoded><![CDATA[
<p>I recently found another <a href="/2014/05/05/brains-over-calculators/">calculation that I would consider reasonable for my students to perform that their calculators cannot</a>. On my Calc II students’ final exam, I asked them to evaluate the infinite series \(\displaystyle \sum_{n = 1}^\infty \frac{4}{(n + 3)(n+5)}\). As a hint, I told them to rewrite in telescoping form using partial fractions. However, the TI-89 cannot evaluate this series. Since it’s hard to take a good photo of the calculator screen, I’ve instead included a screen shot of the TI-Nsipre CAS iPad app.</p>
<p><img src="/wp-content/uploads/photo-21.png" alt="Screen shot of app, which emulates a graphing calculator. The series has been input, but instead of evaluating, the calculator returns the same series with the constant 4 factored out." /></p>]]></content:encoded></item><item><title>Congrats, Oregon! Welcome to marriage equality!</title><link>https:://chrisphan.com/2014/05/21/congrats-oregon-welcome-to-marriage-equality/index.html</link><description><![CDATA[ On Monday, a federal judge in Eugene struck down Oregon’s state constitutional ban on same-sex marriage , which was enacted by citizen initiative nearly a]]></description><guid>https:://chrisphan.com/2014/05/21/congrats-oregon-welcome-to-marriage-equality/index.html</guid><pubDate>Wed, 21 May 2014 12:21:05 -0500</pubDate><content:encoded><![CDATA[
<blockquote class="twitter-tweet" lang="en">
  <p>
    Oregon Teacher of the Year Brett Bigham and his spouse Mike Turay just married by our own Jeana Frazzini <a href="http://t.co/GPSE7S0Dmv">pic.twitter.com/GPSE7S0Dmv</a>
  </p>
  <p>
    &mdash; Basic Rights Oregon (@basicrights) <a href="https://twitter.com/basicrights/statuses/468533941230501888">May 19, 2014</a>
  </p>
</blockquote>
<blockquote class="twitter-tweet" lang="en">
  <p>
    1st marriage in Eugene: Bruce and Matt together for 40 years! <a href="http://t.co/pIoBxHtwJ8">pic.twitter.com/pIoBxHtwJ8</a>
  </p>
  <p>
    &mdash; Basic Rights Oregon (@basicrights) <a href="https://twitter.com/basicrights/statuses/468534241181982721">May 19, 2014</a>
  </p>
</blockquote>
<p>On Monday, <a href="http://www.oregonlive.com/mapes/index.ssf/2014/05/oregon_gay_marriage_ban_struck.html">a federal judge in Eugene struck down Oregon’s state constitutional ban on same-sex marriage</a>, which was enacted by citizen initiative nearly a decade ago. This ruling was unsurprising, given that the defendants in the lawsuit, such as Oregon’s attorney general, agreed with the plaintiffs’ contention that the ban violated the federal constitution, leaving no one with standing willing to defend the ban’s constitutionality.</p>
<p>I cannot tell you how happy I was about this ruling. I grew up in Oregon, and lived there through the first decade of my adult life. I voted against Measure 36, the ballot measure that added discrimination to the Oregon Constitution, and was quite upset when it passed in 2004. Seeing pictures of Oregonian couples finally able to be married was really heartwarming to me.</p>
<p>Furthermore, my wife and I were married in Oregon; a framed copy of our marriage record from the Oregon Department of Health Services hangs on the wall near my desk in my home office. We chose our officiant, a senior judge, because she was on record as enthusiastic to marry same-sex couples during the brief window in 2004, before Measure 36 passed, when Multnomah County was issuing marriage licenses to same-sex couples. We encouraged our wedding guests to donate to Basic Rights Oregon, in the hope that same-sex couples could someday be married under the same laws we were. I am very happy to see that day finally come.</p>
<p>Yet, I must echo the sentiments expressed by a friend, who wrote on Twitter:</p>
<blockquote class="twitter-tweet" lang="en">
  <p>
    Oh, Oregon. It took a federal judge to tell you to play nice, but that bit of love for you that I was withholding is still gushing forth.
  </p>
  <p>
    &mdash; qousqous (@qousqous) <a href="https://twitter.com/qousqous/statuses/468508402058919936">May 19, 2014</a>
  </p>
</blockquote>
<p>I am sad that marriage equality didn’t come to Oregon by the voters or their elected representatives, but through the actions of a federal judge. Now, please don’t get me wrong, I think it’s completely appropriate that a judge strike down a law if it violates the constitution. I’m not saying it’s bad that a judge overturned the will of the people—judges absolutely <em>should</em> overturn the will of the people when the people want to violate the constitution. But I am much less happy when a state does the right thing because it’s forced to, rather than because it chose to.</p>
<p>Fate has decided that my wife and I make our home in the wonderful state of Minnesota. I have discovered a number of reasons to love and be proud of my new home state. One reason (out of many) I am proud is that, a months after we moved here, Minnesotans rejected at the ballot box a state constitutional ban on same-sex marriage. Furthermore, within a year after that, <a href="/2013/05/14/yay-for-minnesota/">Minnesota enacted marriage equality through a legislative process</a>. I am proud that Minnesotans did the right thing without needing a judge to force them to.</p>
<p><a href="http://www.oregonlive.com/mapes/index.ssf/2014/05/gay_marriage_now_appears_set_i.html">There is some talk</a> of a ballot measure in 2016 in Oregon to repeal Measure 36. I do hope Oregon voters have a chance to formally repudiate Measure 36 at the ballot box at some point.</p>
<p>By the way, I was inspired by the beautiful language in <a href="http://media.oregonlive.com/mapes/other/4758025-0--2002.pdf">Judge McShane’s ruling</a>. I think it’s worth quoting at length:</p>
<blockquote>
<p>Generations of Americans, my own included, were raised in a world in which homosexuality was believed to be a moral perversion, a mental disorder, or a mortal sin. I remember that one of the more popular playground games of my childhood was called “smear the queer” and it was played with great zeal and without a moment’s thought to today’s political correctness. On a darker level, that same worldview led to an environment of cruelty, violence, and self-loathing. It was but 1986 when the United States Supreme Court justified, on the basis of a “millennia of moral teaching,” the imprisonment of gay men and lesbian women who engaged in consensual sexual acts. [. . .] Even today I am reminded of the legacy that we have bequeathed today’ s generation when my son looks dismissively at the sweater I bought him for Christmas and, with a roll of his eyes, says “dad … that is so gay.”</p>
<p>It is not surprising then that many of us raised with such a world view would wish to protect our beliefs and our families by turning to the ballot box to enshrine in law those traditions we have come to value. But just as the Constitution protects the expression of these moral viewpoints, it equally protects the minority from being diminished by them.</p>
<p>[. . .]</p>
<p>My decision will not be the final word on this subject, but on this issue of marriage I am struck more by our similarities than our differences. I believe that if we can look for a moment past gender and sexuality, we can see in these plaintiffs nothing more or less than our own families. Families who we would expect our Constitution to protect, if not exalt, in equal measure. With discernment we see not shadows lurking in closets or the stereotypes of what was once believed; rather, we see families committed to the common purpose of love, devotion, and service to the greater community.</p>
<p>Where will this all lead? I know that many suggest we are going down a slippery slope that will have no moral boundaries. To those who truly harbor such fears, I can only say this: Let us look less to the sky to see what might fall; rather, let us look to each other … and rise.</p>
</blockquote>]]></content:encoded></item><item><title>Brains over calculators!</title><link>https:://chrisphan.com/2014/05/05/brains-over-calculators/index.html</link><description><![CDATA[ I enjoy finding calculations that I would consider reasonable for my students to perform that their calculators cannot. Using a double-angle identity and the pythagorean]]></description><guid>https:://chrisphan.com/2014/05/05/brains-over-calculators/index.html</guid><pubDate>Mon, 5 May 2014 18:36:45 -0500</pubDate><content:encoded><![CDATA[
<p>I enjoy finding calculations that I would consider reasonable for my students to perform that their calculators cannot.</p>
<p>Using a double-angle identity and the pythagorean identity, it’s pretty
straightforward to show that
\(\sin\left(2\sin^{-1}\left(-\frac{4}{5}\right)\right) = -\frac{24}{25}.\)
However, my TI-89 returns an unhelpful \(-\sin(2\sin^{-1}(4/5))\) instead.</p>
<p>Amusingly, the calculator does know that
\(2\sin\left(\sin^{-1}\left(-\frac{4}{5}\right)\right)\cos\left(\sin^{-1}\left(-\frac{4}{5}\right)\right)
= -\frac{24}{25}.\)</p>
<p><img src="/wp-content/uploads/photo-4-300x264.jpg" alt="Photo of the calculator screen showing what is described above." /></p>
<p>(My calculator is running the 2005 version of the software. It’s possible this has been fixed since then.)</p>]]></content:encoded></item><item><title>Rejoining the tweet-o-sphere</title><link>https:://chrisphan.com/2014/04/06/rejoining-the-tweet-o-sphere/index.html</link><description><![CDATA[ After a few years away, I am back on Twitter.]]></description><guid>https:://chrisphan.com/2014/04/06/rejoining-the-tweet-o-sphere/index.html</guid><pubDate>Sun, 6 Apr 2014 20:43:10 -0500</pubDate><content:encoded><![CDATA[
<p>After a few years away, I am back on Twitter.</p>
<blockquote class="twitter-tweet" lang="en">
  <p>
    I'm back on Twitter!
  </p>
  <p>
    &mdash; Chris Phan (@functoruser) <a href="/note_about_tweets/">April 7, 2014</a>
  </p>
</blockquote>]]></content:encoded></item><item><title>Re the Mozilla thing</title><link>https:://chrisphan.com/2014/04/03/re-the-mozilla-thing/index.html</link><description><![CDATA[ Re the Mozilla thing : Given that wealthy people now have a right to unlimited political donations , why shouldn’t people take CEO politics into]]></description><guid>https:://chrisphan.com/2014/04/03/re-the-mozilla-thing/index.html</guid><pubDate>Thu, 3 Apr 2014 21:27:42 -0500</pubDate><content:encoded><![CDATA[
<p>Re <a href="http://bits.blogs.nytimes.com/2014/04/03/eich-steps-down-as-mozilla-chief/">the Mozilla thing</a>: Given that wealthy people <a href="http://www.nytimes.com/2014/04/03/us/politics/supreme-court-ruling-on-campaign-contributions.html">now have a right to unlimited political donations</a>, why <em>shouldn’t</em> people take CEO politics into account in their consumer decisions?</p>
<p><small>(Yes, I am aware people don’t pay money to use Firefox. <a href="http://allthingsd.com/20111222/google-will-pay-mozilla-almost-300m-per-year-in-search-deal-besting-microsoft-and-yahoo/">But Google pays the Mozilla Corporation $300 million per year to be the default search engine in Firefox</a>, which presumably reflects Firefox’s market share.)</small></p>]]></content:encoded></item><item><title>hanging with MVPB</title><link>https:://chrisphan.com/2014/03/19/1034/index.html</link><description><![CDATA[ Picture of me with baby Max]]></description><guid>https:://chrisphan.com/2014/03/19/1034/index.html</guid><pubDate>Wed, 19 Mar 2014 19:45:22 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/wp-content/uploads/photo-11.jpg" alt="Picture of me with baby Max" /></p>]]></content:encoded></item><item><title>Arizona State Senator opposes Common Core, in part, because ALGEBRA!</title><link>https:://chrisphan.com/2014/02/22/arizona-state-senator-opposes-common-core-in-part-because-algebra/index.html</link><description><![CDATA[ According to the Arizona Daily Star , the Arizona Senate Education Committee passed a bill that would prohibit the state from implementing the Common Core]]></description><guid>https:://chrisphan.com/2014/02/22/arizona-state-senator-opposes-common-core-in-part-because-algebra/index.html</guid><pubDate>Sat, 22 Feb 2014 13:53:53 -0600</pubDate><content:encoded><![CDATA[
<p>According to <a href="http://azstarnet.com/news/local/education/arizona-senate-panel-votes-to-dump-common-core/article_512d157d-054f-5bc0-8a29-2076f69cc35a.html">the <cite>Arizona Daily Star</cite></a>, the Arizona Senate Education Committee passed a bill that would prohibit the state from implementing the Common Core standards. Quoth the <cite>Daily Star</cite> (emphasis mine):</p>
<blockquote>
<p>[Gubernatorial candidate and state Senator Al] Melvin said he understands “some of the reading material is borderline pornographic.” <strong>And he said the program uses “fuzzy math,” substituting letters for numbers in some examples.</strong></p>
</blockquote>
<p>Later on in the same article, Senator Melvin is quoted as expressing concern about the rigor of American academic standards, arguing that “We have cheated several generations of Americans out of a decent education.” I might argue that the person who has been cheated out of a decent education is Senator Melvin, who is apparently unfamiliar with <a href="http://www.nctm.org/standards/content.aspx?id=312#represent">fifth-grade mathematics</a>.</p>
<p>Of course, it’s entirely possible Senator Melvin is fully aware that this “fuzzy math” line is completely ignorant poppycock and is only saying it in a cynical attempt to appeal to ignorant people in his gubernatorial campaign. (This possibility, to be frank, would be even more distressing.)</p>
<p><a href="http://www.intel.com/content/www/us/en/corporate-responsibility/intel-in-arizona.html">Intel’s second largest U.S. site is in Arizona.</a> I wonder how Intel executives feel about their company’s investment in a state where members of the state senate education committee oppose the teaching of algebra.</p>
<p>(To be absolutely clear, I’m not saying that all Common Core skeptics and opponents are as ridiculous as Senator Melvin.)</p>
<p><small>HT: <a href="https://www.facebook.com/matthew.arbo/posts/10100864708838854?stream_ref=10">Matthew Arbo</a></small></p>]]></content:encoded></item><item><title>Yes, this.</title><link>https:://chrisphan.com/2014/02/15/yes-this/index.html</link><description><![CDATA[ Edited to add:]]></description><guid>https:://chrisphan.com/2014/02/15/yes-this/index.html</guid><pubDate>Sat, 15 Feb 2014 09:58:47 -0600</pubDate><content:encoded><![CDATA[
<blockquote class="twitter-tweet" lang="en">
  <p>
    Related note, arguments about whether "piracy" is "stealing" are irrelevant to debates about piracy's ethics, you can safely ignore them.
  </p>
  <p>
    &mdash; gia manry (@giapet) <a href="https://twitter.com/giapet/statuses/434685549845049344">February 15, 2014</a>
  </p>
</blockquote>
<p>Edited to add:</p>
<blockquote class="twitter-tweet" lang="en">
  <p>
    If you pirate media, you are choosing your *personal entertainment* over the rights of the owners of said media. Don't pretend otherwise.
  </p>
  <p>
    &mdash; gia manry (@giapet) <a href="https://twitter.com/giapet/statuses/434762346766929921">February 15, 2014</a>
  </p>
</blockquote>]]></content:encoded></item><item><title>MVPB and me</title><link>https:://chrisphan.com/2014/02/09/mvpb-and-me/index.html</link><description><![CDATA[ Picture of me with baby Max]]></description><guid>https:://chrisphan.com/2014/02/09/mvpb-and-me/index.html</guid><pubDate>Sun, 9 Feb 2014 11:33:12 -0600</pubDate><content:encoded><![CDATA[
<p><img src="https://chrisphan.com/wp-content/uploads/mvpb_and_me-e1391967142948.jpg" alt="Picture of me with baby Max" /></p>]]></content:encoded></item><item><title>One thing I love about the new NYT website redesign</title><link>https:://chrisphan.com/2014/01/20/one-thing-i-love-about-the-new-nyt-website-redesign/index.html</link><description><![CDATA[ Many people are complaining about the redesign of the New York Times website. Some of these complaints are from people having trouble finding things on]]></description><guid>https:://chrisphan.com/2014/01/20/one-thing-i-love-about-the-new-nyt-website-redesign/index.html</guid><pubDate>Mon, 20 Jan 2014 11:17:32 -0600</pubDate><content:encoded><![CDATA[
<p><a href="http://publiceditor.blogs.nytimes.com/2014/01/20/after-the-times-redesign-complaints-and-changes/">Many people are complaining</a> about the redesign of the <cite>New York Times</cite> website. Some of these complaints are from people having trouble finding things on the site, which is prone to happen anytime you change a user interface. Other complaints deal with the smaller font size, which I find annoying as well. (I am a frequent user of the ⌘+ key combo.)</p>
<p>But one thing I <em>love, love, love</em> about the redesign, which I hope is copied by other news sites, is that articles appear on a <em>single page</em>, and I don’t have to click “Next” repeatedly. It really bothers me to have to have to click “Next” to read the remainder of an article.</p>]]></content:encoded></item><item><title>Lake Winona on a frozen winter day</title><link>https:://chrisphan.com/2014/01/19/lake-winona-on-a-frozen-winter-day/index.html</link><description><![CDATA[ Panorama of frozen Lake Winona Full size Panorama of frozen Lake Winona Full size]]></description><guid>https:://chrisphan.com/2014/01/19/lake-winona-on-a-frozen-winter-day/index.html</guid><pubDate>Sun, 19 Jan 2014 20:07:40 -0600</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/panorama_2014-01-19/1_s.jpg" alt="Panorama of frozen Lake Winona" /></p>
<p><a href="https://blog.chrisphan.com/flickr_photos/panorama_2014-01-19/1_b.jpg">Full size</a></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/panorama_2014-01-19/2_s.jpg" alt="Panorama of frozen Lake Winona" /></p>
<p><a href="https://blog.chrisphan.com/flickr_photos/panorama_2014-01-19/2_b.jpg">Full size</a></p>]]></content:encoded></item><item><title>It’s fun!</title><link>https:://chrisphan.com/2014/01/18/its-fun/index.html</link><description><![CDATA[ I didn’t think this would be true, but I actually quite enjoy using the snowblower.]]></description><guid>https:://chrisphan.com/2014/01/18/its-fun/index.html</guid><pubDate>Sat, 18 Jan 2014 15:19:32 -0600</pubDate><content:encoded><![CDATA[
<img src="/wp-content/uploads/IMG_20140118_141448_837.jpg" alt="Me pushing a snowblower" height="816" width="460" />
<p>I didn’t think this would be true, but I actually quite enjoy using the snowblower.</p>]]></content:encoded></item><item><title>2013 Year in Review</title><link>https:://chrisphan.com/2013/12/27/2013-year-in-review/index.html</link><description><![CDATA[ It was another eventful year for the Phan-Budd family, and you can read all about it in our year-in-review letter !]]></description><guid>https:://chrisphan.com/2013/12/27/2013-year-in-review/index.html</guid><pubDate>Fri, 27 Dec 2013 18:58:51 -0600</pubDate><content:encoded><![CDATA[
<p>It was another eventful year for the Phan-Budd family, and you can read all about it in <a href="http://www.phanbudd.com/letters/2013/">our year-in-review letter</a>!</p>]]></content:encoded></item><item><title>Winter is here</title><link>https:://chrisphan.com/2013/12/22/winter-is-here/index.html</link><description><![CDATA[ Right after sunset on the solstice, I snapped this picture of Main Channel Bridge , which connects Winona with Wisconsin to the north. As its]]></description><guid>https:://chrisphan.com/2013/12/22/winter-is-here/index.html</guid><pubDate>Sun, 22 Dec 2013 18:46:39 -0600</pubDate><content:encoded><![CDATA[
<p>Right after sunset on the solstice, I snapped <a href="/wp-content/uploads/winona_winter_bridge.jpg">this picture</a> of <a href="http://en.wikipedia.org/wiki/Main_Channel_Bridge_(Winona)">Main Channel Bridge</a>, which connects Winona with Wisconsin to the north. As its name suggests, it crosses the main channel of the Mississippi River, which is currently frozen.</p>
<p><img src="/wp-content/uploads/winona_winter_bridge-500x207.jpg" alt="a bridge crosses the frozen Mississippi" /></p>
<p>Today, I captured this video of a BNSF train passing through Trempealeau, Wisconsin:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Z3tuEfi1v8s?si=yJ4Q_QNUQZ4DyKQv" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>]]></content:encoded></item><item><title>Ha ha nice try</title><link>https:://chrisphan.com/2013/10/26/ha-ha-nice-try-3/index.html</link><description><![CDATA[ From: Qatar Foundation To: Recipients You Have Been Awarded $1,000,000.00 USD October 24, 2013 at 16:36 Dear Beneficiary, This is to inform you that you]]></description><guid>https:://chrisphan.com/2013/10/26/ha-ha-nice-try-3/index.html</guid><pubDate>Sat, 26 Oct 2013 11:20:12 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/wp-content/uploads/photo-2.png" width="160"
height="284" alt="screenshot of phishing email"/></p>
<blockquote>
<p>From: Qatar Foundation</p>
<p>To: Recipients</p>
<p>You Have Been Awarded $1,000,000.00 USD</p>
<p>October 24, 2013 at 16:36</p>
<p>Dear Beneficiary,</p>
<p>This is to inform you that you were among the lucky
beneficiary selected to receive this donations award sum of $1,000,000.00 USD,
as charity donations/aid from the Qatar Foundation held in Doha, Qatar, 24th
of October 2013, to promote your business and personal Interest. Kindly get
back for more details on how to
claims your award via email:</p>
</blockquote>]]></content:encoded></item><item><title>Chromecast: Pretty neat</title><link>https:://chrisphan.com/2013/09/15/chromecast-pretty-neat/index.html</link><description><![CDATA[ A few weeks ago, I received my Chromecast in the mail. This is a small $35 device sold by Google that vaguely resembles a USB]]></description><guid>https:://chrisphan.com/2013/09/15/chromecast-pretty-neat/index.html</guid><pubDate>Mon, 16 Sep 2013 22:24:47 -0500</pubDate><content:encoded><![CDATA[
<p>A few weeks ago, I received my Chromecast in the mail. This is a small $35 device sold by Google that vaguely resembles a USB flash drive and fits into the HDMI port on your TV, and connects to your WiFi. For what it does, it is a very nice device.</p>
<p><img src="/wp-content/uploads/chromecast1.jpg" alt="Chromecast plugged into the back of a TV" /></p>
<p>My television comes with built-in software to watch Netflix and YouTube. Alas, that software is slow and is a pain to use. Entering a search term using the arrow keys on my remote control, one letter at a time, is absolutely frustrating. However, Chomecast has much nicer software for watching Netflix and YouTube, which you can control using your computer or mobile device. For example, I can launch the Netflix app on my iPad, pick a show off of my instant queue (or whatever they are calling it these days), and send the info on my selection to the Chromecast, which starts streaming the show to my TV. (Chormecast uses your home WiFi network to stream video and get commands from your devices.) The same is true of YouTube, and I guess Google Play movies, which I have never used. I love watching YouTube videos on my TV, selecting them from my subscriptions using my iPad. (I can also use my laptop or Droid 4 smartphone.)</p>
<p><img src="/wp-content/uploads/chromecast2.jpg" alt="Web page shown on TV screen" /></p>
<p>Chormecast also allows you to send any Chrome browser tab on your computer to your TV. This doesn’t work quite as well as the built-in apps. For one thing, there is a delay of a few seconds between something happening in the browser tab on your computer and the display of the tab on the TV. (Fortunately, the sound also gets delayed, so watching a video in a Chromecasted tab will mean the sound and video will be in sync on your TV.) Second, this is bandwidth-intensive when watching a video, since the computer has to stream the video from the Internet and then restream it to your TV over WiFi. So, it’s better to use the built-in apps to watch Netflix and YouTube.</p>
<p>Nevertheless, casting tabs still works good enough. The other night, I Chromecasted <a href="http://www.nytimes.com/2013/09/12/world/obama-syria.html?pagewanted=all">a NYT article on the president’s Syria speech</a>, and played the embedded video of his speech. It worked fine.</p>
<p>Now, this device is not really that necessary. My TV has built-in apps for Netflix and YouTube. Likewise, as you can see from the photo above, it’s perfectly possible for me to hook my computer up directly to the HDMI input on my TV, which would allow me to send the whole screen to the TV, not just what I can get in a Chrome tab. But Chromecast is much easier to use than my TV’s built-in apps, and less awkward than stringing HDMI cables back to the couch. For $35, this nice little device is a good help.</p>]]></content:encoded></item><item><title>Facebook’s news feed was not a novel idea</title><link>https:://chrisphan.com/2013/09/12/facebooks-news-feed-was-not-a-novel-idea/index.html</link><description><![CDATA[ Today in Slate , Farhad Manjoo celebrates the 7th birthday of Facebook’s news feed feature . Get this: Before news feed, which launched seven years]]></description><guid>https:://chrisphan.com/2013/09/12/facebooks-news-feed-was-not-a-novel-idea/index.html</guid><pubDate>Thu, 12 Sep 2013 12:24:57 +0000</pubDate><content:encoded><![CDATA[
<p>Today in <cite>Slate</cite>, <a href="http://www.slate.com/articles/technology/technology/2013/09/facebook_news_feed_turns_7_why_it_s_the_most_influential_feature_on_the.single.html">Farhad Manjoo celebrates the 7th birthday of Facebook’s news feed feature</a>.</p>
<blockquote>
<p>Get this: Before news feed, which launched seven years ago this month, you could post a picture or some other personal detail somewhere—your Facebook or MySpace or Friendster page, Flickr, Blogger, LiveJournal—and be reasonably sure that it would remain just there, unseen by pretty much everyone you knew. The only way someone might find it is by checking your page. Sure, some people would do that—but everyone had scores of connections online, so no one was checking each of their friends’ pages. The net effect was solitude.</p>
</blockquote>
<p>Sorry, but this is complete bunk. Every LiveJournal user has a <a href="http://www.livejournal.com/support/faq/219.html">friends page</a>, which shows all recent entries by their LJ friends. When I joined LiveJournal in July 2001, over 12 years ago and <em>before Facebook even existed</em>, LiveJournal had this feature already. Granted, as LiveJournal never attained the market penetration that Facebook has, posting something to your LiveJournal was never as effective at spreading your news as posting to Facebook today. But that’s due to Facebook benefiting from a <a href="http://en.wikipedia.org/wiki/Network_effect">network effect</a> on a scale that LiveJournal never did.</p>
<p>I wouldn’t dispute that Facebook’s news feed is an important feature that has allowed for those network effects. Without the news feed, the site would just be a glorified directory and messaging service. But it’s an absurd revision of Internet history to say that Mark Zuckerberg and his friends, as smart as they are, came up with the idea from scratch.</p>]]></content:encoded></item><item><title>What (not) to do if you don’t like sports</title><link>https:://chrisphan.com/2013/09/04/what-not-to-do-if-you-dont-like-sports/index.html</link><description><![CDATA[ Let’s say you don’t like watching sports. You have no interest in the World Series, the BCS, or the NBA Finals. I think that’s okay.]]></description><guid>https:://chrisphan.com/2013/09/04/what-not-to-do-if-you-dont-like-sports/index.html</guid><pubDate>Wed, 4 Sep 2013 21:58:23 -0500</pubDate><content:encoded><![CDATA[
<p>Let’s say you don’t like watching sports. You have no interest in the World Series, the BCS, or the NBA Finals. I think that’s okay. It’s okay to not pay attention to sports. It’s okay to flip past ESPN on your TV. But here’s what’s not okay to do:</p>
<ul>
<li>Make fun of people for liking to watch sports.</li>
<li>Derisively dismiss sports as “sportsball”.</li>
<li>Assume people are dumb because they like to watch sports.</li>
</ul>
<p>If you are a geek about my age, you may have not-so-fond memories of being ridiculed when you were a teenager for having geeky interests. You may remember people teasing you for socializing on the Internet (something just about every teenager does today), or for being interested in <cite>Star Trek</cite>. For someone with those memories, it’s very tempting, now that geek interests are more mainstream, to turn the tables and dish out ridicule for being into sports. But you should resist the temptation because it makes you as much as a jerk as the kids who teased you. Actually, it makes you worse, because you are some decade-and-a-half older and should know better.</p>]]></content:encoded></item><item><title>Next adventure: homeownership</title><link>https:://chrisphan.com/2013/08/07/next-adventure-homeownership/index.html</link><description><![CDATA[ Me pushing a lawnmower in a backyard Late last month, my wife and I went down to our local credit union, signed a very large]]></description><guid>https:://chrisphan.com/2013/08/07/next-adventure-homeownership/index.html</guid><pubDate>Wed, 7 Aug 2013 20:18:42 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/wp-content/uploads/1017583_10201801908752014_132053183_n.jpg" alt="Me pushing a lawnmower in a backyard" /></p>
<p>Late last month, my wife and I went down to our local credit union, signed a very large stack of legal documents, and joined the ranks of millions of Americans who own their own home.</p>
<p>And then, about a week or so later, I bought a cordless electric lawnmower and mowed the lawn.</p>]]></content:encoded></item><item><title>Ha ha nice try</title><link>https:://chrisphan.com/2013/08/07/ha-ha-nice-try-2/index.html</link><description><![CDATA[ Important Notification Patrick Nso [REDACTED]@gmail.com Important Notification, This is to inform you that we (International Financial Monitoring Agency) have been instructed to handle the completion]]></description><guid>https:://chrisphan.com/2013/08/07/ha-ha-nice-try-2/index.html</guid><pubDate>Wed, 7 Aug 2013 13:33:15 -0500</pubDate><content:encoded><![CDATA[
<p><img alt="Phishing email" src="/wp-content/uploads/nice_try.png" width="323"
height="219" /></p>
<blockquote>
<p>Important Notification</p>
<p>Patrick Nso [REDACTED]@gmail.com</p>
<p>Important Notification,</p>
<p>This is to inform you that we (International Financial Monitoring Agency) have
been instructed to handle the completion of your transaction worth the sum of
$950,000 (nine hundred and fifty thousand United States Dollars). We have also
been instructed to make sure that we take care of the paper works needed from
our end to transfer your fund while you take care of your end to receive your
fund once it is transfered out to you.</p>
<p>Your response is highly anticipated if you are willing to finalise this, for
us to proceed with the processing by letting you know the information needed
from you.</p>
<p>Thank you.<br />
Patrick Nso.<br />
Manager, <br />
International Financial Monitoring Agency.</p>
</blockquote>]]></content:encoded></item><item><title>PGP key</title><link>https:://chrisphan.com/2013/07/17/pgp-key/index.html</link><description><![CDATA[ In reaction to recent events, I have created a PGP key, and have posted the public key on my web site . The fingerprint to]]></description><guid>https:://chrisphan.com/2013/07/17/pgp-key/index.html</guid><pubDate>Wed, 17 Jul 2013 20:31:41 -0500</pubDate><content:encoded><![CDATA[
<p>In reaction to recent events, I have created a PGP key, and have <a href="/pgp-key/">posted the public key on my web site</a>. The fingerprint to this key is:</p>
<p><code>15A1 D221 79D1 2FEB 8BA4 4F47 33AB 9AD2 C4A9 A097</code></p>
<p>Personally, I have found <a href="https://gpgtools.org/">GPG tools</a>, a Mac implementation of GNU Privacy Guard, pretty easy to use.</p>]]></content:encoded></item><item><title>My hope in the wake of the Zimmerman verdict</title><link>https:://chrisphan.com/2013/07/15/my-hope-in-the-wake-of-the-zimmerman-verdict/index.html</link><description><![CDATA[ My hope, in the wake of the Zimmerman verdict, is that people don’t interpret the “not guilty” verdict as an exoneration of George Zimmerman’s actions]]></description><guid>https:://chrisphan.com/2013/07/15/my-hope-in-the-wake-of-the-zimmerman-verdict/index.html</guid><pubDate>Mon, 15 Jul 2013 14:19:55 -0500</pubDate><content:encoded><![CDATA[
<p>My hope, in the wake of the Zimmerman verdict, is that people don’t interpret the “not guilty” verdict as an exoneration of George Zimmerman’s actions leading up to Trayvon Martin’s death. The jury concluded, perhaps justifiably, that the state failed to prove that Zimmerman committed a crime. But that doesn’t mean that what Zimmerman did that night was honorable or ethical. It wasn’t.</p>
<p>It’s just not a good idea for people to act like police officers when they don’t have the training and authority. It’s dangerous for both you and the people you accost. The dispatcher was absolutely correct to attempt to dissuade Zimmerman from following Martin. I agree with Jay Smooth that <a href="https://twitter.com/jsmooth995/statuses/356108626139680771">“The fundamental danger of an acquittal is not more riots, it is more George Zimmermans.”</a></p>
<p>I’ve read a number of blog posts and opinion articles in the wake of the verdict, but here are two observations I found especially insightful:</p>
<!--more-->
<p>First, <a href="http://prospect.org/article/zimmerman-acquittal-isnt-about-stand-your-ground">Scott Lemieux argues that the Zimmerman case shows the deficiency of our self-defense laws</a>:</p>
<blockquote>
<p>Carrying a deadly weapon in public should carry unique responsibilities. In most cases someone with a gun should not be able to escape culpability if he initiates a conflict with someone unarmed and the other party ends up getting shot and killed. Under the current law in many states, people threatened by armed people have few good options, because fighting back might create a license to kill. As the New Yorker’s Amy Davidson puts it, “I still don’t understand what Trayvon was supposed to do.” Unless the law is changed to deal with the large number of people carrying concealed guns, there will be more tragic and unnecessary deaths of innocent people like Trayvon Martin for which nobody is legally culpable. And to make claims of self-defense easier to bring, as Florida and more than 20 other states have done, is moving in precisely the wrong direction. And, even more importantly, no matter how self-defense laws are structured the extremely unusual American practice of allowing large number of citizens to carry concealed weapons leads to many unecessary deaths.</p>
</blockquote>
<p>Second, Ta-Nehisi Coates (perhaps the best blogger writing today) <a href="http://www.theatlantic.com/national/archive/2013/07/trayvon-martin-and-the-irony-of-american-justice/277782/">argues</a> that the law—not the verdict, but the underlying statute— is the result of structural racism “forces we set in motion years ago and have done very little to arrest.”</p>
<blockquote>
<p>We have spent much of this year outlining the ways in which American policy has placed black people outside of the law. We are now being told that after having pursued such policies for 200 years, after codifying violence in slavery, after a people conceived in mass rape, after permitting the disenfranchisement of black people through violence, after Draft riots, after white-lines, white leagues, and red shirts, after terrorism, after standing aside for the better reduction of Rosewood and the improvement of Tulsa, after the coup d’etat in Wilmington, after Airport Homes and Cicero, after Ossian Sweet, after Arthur Lee McDuffie, after Anthony Baez, Amadou Diallo and Eleanor Bumpers, after Kathryn Johnston and the Danziger Bridge, that there are no ill effects, that we are pure, that we are just, that we are clean. Our sense of self is incredible. We believe ourselves to have inherited all of Jefferson’s love of freedom, but none of his affection for white supremacy.</p>
<p>You should not be troubled that George Zimmerman “got away” with the killing of Trayvon Martin, you should be troubled that you live in a country that ensures that Trayvon Martin will happen.</p>
</blockquote>
<p>Both these articles are worth reading in full.</p>
<p>Finally, this morning I read <a href="http://www.washingtonpost.com/blogs/erik-wemple/wp/2013/07/14/zimmerman-lawyer-to-move-asap-against-nbc-news/">a <cite>Washington Post</cite> story</a> about Zimmerman’s lawsuit against NBC News for their uncouth edits to the 911 tape. I do think NBC’s edits were unfair and don’t blame Zimmerman for suing. I’m not going to criticize Zimmerman’s lawyers for doing their job by engaging in full-throated advocacy on his behalf, even if that advocacy is sometimes full of B.S. However, dear reader, you should recognize some of their arguments as B.S., especially this:</p>
<blockquote>
<p>When asked how the not-guilty verdict affects the civil case against NBC News, Beasley responded, “This verdict of not guilty is just that, and shows that at least this jury didn’t believe that George was a racist, profiling, or anything that the press accused George of being. That probably doesn’t get you that much but it’s simply time for us to start the case and hold accountable anyone who was irresponsible in their journalism.”</p>
</blockquote>
<p>The jury <em>wasn’t</em> asked to determine if Zimmerman was a racist or profiling, just if there was enough evidence to convict him of homicide. The rest of us are quite entitled to form our own opinions on the matter.</p>]]></content:encoded></item><item><title>Making a “Places I have been” map</title><link>https:://chrisphan.com/2013/07/13/making-a-places-i-have-been-map/index.html</link><description><![CDATA[ A map of the USA with states colored based on my travel history For a while, I have maintained a list of places I’ve lived]]></description><guid>https:://chrisphan.com/2013/07/13/making-a-places-i-have-been-map/index.html</guid><pubDate>Sat, 13 Jul 2013 11:49:07 -0500</pubDate><content:encoded><![CDATA[
<p><img src="/wp-content/uploads/US_Map_chris_visit201307131.png" alt="A map of the USA with states colored based on my travel history" /></p>
<p>For a while, I have maintained a list of places I’ve lived or visited as a
note on Facebook. Recently, I decided to repatriate that content to this blog as
<a href="/places-i-have-been/">a page</a>. I also decided it would be nice to have a color-coded map of the
states with the same information.</p>
<p>Here’s how I made the map:</p>
<p>I started with <a href="https://commons.wikimedia.org/w/index.php?title=File:Blank_US_Map.svg">a blank SVG map of the states</a> from the Wikimedia Commons,
available under a Creative Commons license. (<a href="https://commons.wikimedia.org/w/index.php?title=File:Blank_US_Map.svg&amp;oldid=99464358">Here’s the actual version I
used.</a>) This map is very nice because you can edit it in a text editor. That
makes it easy to change the colors of the state.</p>
<p>I wanted four colors for the states, showing the states in which I have lived,
visited, had airport layovers, or never stepped foot in. In the original file,
there was only one “style” of state, as shown in the CSS style sheet
embedded in the file:</p><div class="code_block"><div class="code-header"><span class="filename">US_Map_chris_visit.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-3579721f-6ca1-422a-ba81-6d1988f6b493"><code class="language-svg"><code class="code-elipsis" id="block-3579721f-6ca1-422a-ba81-6d1988f6b493-elipsis-start"></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">style </span><span style="color:#b58900;">type</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">text/css</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">.state {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">	fill:#d3d3d3;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">	stroke:#fff;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">	stroke-width:0.75;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-opacity:1;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">style</span><span style="color:#586e75;">&gt;</span></code>
<code class="code-elipsis" id="block-3579721f-6ca1-422a-ba81-6d1988f6b493-elipsis-end"></code>
</code></pre></div>
<p>To this, I inserted three more styles. The resulting stylesheet is:</p><div class="code_block"><div class="code-header"><span class="filename">US_Map_chris_visit.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-e285dc20-99ef-43ff-a43f-2192fa89691a"><code class="language-svg"><code class="code-elipsis" id="block-e285dc20-99ef-43ff-a43f-2192fa89691a-elipsis-start"></code>
<code class="checker lineno dig-1"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">style </span><span style="color:#b58900;">type</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">text/css</span><span style="color:#839496;">&quot;</span><span style="color:#586e75;">&gt;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">.state {</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">	fill:#d3d3d3;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">	stroke:#fff;</span></code>
<code class="checker lineno dig-1"><span style="color:#839496;">	stroke-width:0.75;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-opacity:1;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">.statel {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	fill:#669966;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke:#fff;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-width:0.75;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-opacity:1;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">.statev {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	fill:#ff7f00;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke:#fff;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-width:0.75;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-opacity:1;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;"></span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">.statea {</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	fill:#ffcc33;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke:#fff;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-width:0.75;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">	stroke-opacity:1;</span></code>
<code class="checker lineno dig-0"><span style="color:#839496;">}</span></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;/</span><span style="color:#268bd2;">style</span><span style="color:#586e75;">&gt;</span></code>
<code class="code-elipsis" id="block-e285dc20-99ef-43ff-a43f-2192fa89691a-elipsis-end"></code>
</code></pre></div>
<p>The colors are given by the <code>fill</code> attributes, and are specified as <a href="https://en.wikipedia.org/w/index.php?title=Web_colors&amp;oldid=563971042#Hex_triplet">RGB hex
triplets</a> (e.g. <code>#669966</code> is the green color used in the image).</p>
<p>Once I established the styles, it was straightforward to modify the states to
assign the different styles. Each state is drawn in the SVG file with a <code>path</code>
element; you just need to change the <code>class</code> attribute in the corresponding
<code>path</code> element. For example, here is the original code to draw Colorado:</p><div class="code_block"><div class="code-header"><span class="filename">US_Map_chris_visit.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-04ba3c2e-e1b1-4825-a96f-8f64a2328cb7"><code class="language-svg"><code class="code-elipsis" id="block-04ba3c2e-e1b1-4825-a96f-8f64a2328cb7-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">path </span><span style="color:#b58900;">d</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">m 380.03242,320.96457 4.90324,-86.32496 -113.38856,-12.64396 -12.21382,87.93916 120.69914,11.02976 z</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">CO</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">class</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">state</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="code-elipsis" id="block-04ba3c2e-e1b1-4825-a96f-8f64a2328cb7-elipsis-end"></code>
</code></pre></div>
<p>And here is how I modified the code:</p><div class="code_block"><div class="code-header"><span class="filename">US_Map_chris_visit.svg</span> <span class="code-lang">SVG</span></div><pre class=""  id="block-a3961057-1a01-444f-80df-b46b548198dc"><code class="language-svg"><code class="code-elipsis" id="block-a3961057-1a01-444f-80df-b46b548198dc-elipsis-start"></code>
<code class="checker lineno dig-0"><span style="color:#586e75;">&lt;</span><span style="color:#268bd2;">path </span><span style="color:#b58900;">d</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">m 380.03242,320.96457 4.90324,-86.32496 -113.38856,-12.64396 -12.21382,87.93916 120.69914,11.02976 z</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">id</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">CO</span><span style="color:#839496;">&quot; </span><span style="color:#b58900;">class</span><span style="color:#839496;">=&quot;</span><span style="color:#2aa198;">statea</span><span style="color:#839496;">&quot; </span><span style="color:#586e75;">/&gt;</span></code>
<code class="code-elipsis" id="block-a3961057-1a01-444f-80df-b46b548198dc-elipsis-end"></code>
</code></pre></div>
<p>Note that the <code>id</code> attribute is used to identify the state.</p>
<p>Because browser support for SVG is imperfect at this point, I converted the SVG file to a PNG before uploading. Unfortunately, the version of the Imagemagick <code>convert</code> utility on my computer didn’t do the conversion correctly, so I used <a href="https://inkscape.org/">Inkscape</a> instead.</p>
<p><small><b>Credit:</b> Map of the US <a href="https://commons.wikimedia.org/w/index.php?title=File:Blank_US_Map.svg&#038;oldid=99464358">adapted from a file from the Wikimedia Commons</a> that was originally created by Wikimedia Commons user Theshibboleth and modified by users Fibonacci, NuclearVacuum, and Wylve. Used under the <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">Creative Commons Attribution-ShareAlike 3.0 Unported</a> (CC-BY-SA 3.0) license. <a href="https://chrisphan.com/wp-content/uploads/US_Map_chris_visit.svg">SVG source code of my modified version of the file.</a> Both my modified SVG and derived PNGs are offered under the <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">Creative Commons Attribution-ShareAlike 3.0 Unported</a> (CC-BY-SA 3.0) license.</small></p>]]></content:encoded></item><item><title>Places I have been</title><link>https:://chrisphan.com/places-i-have-been/index.html</link><description><![CDATA[ Last updated: 13 July 2013 For the purposes of this page, I have only been to a place if I have been on the ground;]]></description><guid>https:://chrisphan.com/places-i-have-been/index.html</guid><pubDate>Sat, 13 Jul 2013 11:12:27 -0500</pubDate><content:encoded><![CDATA[
<p>Last updated: 13 July 2013</p>
<p>For the purposes of this page, I have only been to a place if I have been on the
ground; being in a jurisdiction’s airspace does not count.</p>
<p><img src="/wp-content/uploads/US_Map_chris_visit.svg" alt="A map of the USA with states colored based on my travel history (described below)" /></p>
<h2>States I have lived in:</h2>
<ul>
<li>Illinois</li>
<li>Minnesota</li>
<li>Oregon</li>
<li>Pennsylvania</li>
</ul>
<h2>States I have not lived in, but have visited beyond just the airport:</h2>
<ul>
<li>Arkansas</li>
<li>California</li>
<li>Connecticut</li>
<li>District of Columbia*</li>
<li>Idaho</li>
<li>Indiana</li>
<li>Iowa</li>
<li>Kentucky</li>
<li>Louisiana</li>
<li>Maryland</li>
<li>Massachusetts</li>
<li>Michigan</li>
<li>Mississippi</li>
<li>Missouri</li>
<li>Montana</li>
<li>Nebraska</li>
<li>New Jersey</li>
<li>New York</li>
<li>North Carolina</li>
<li>North Dakota</li>
<li>Ohio</li>
<li>South Dakota</li>
<li>Tennessee</li>
<li>Utah</li>
<li>Virginia</li>
<li>Washington</li>
<li>West Virginia</li>
<li>Wisconsin</li>
<li>Wyoming</li>
</ul>
<p><code>*</code> For the purpose of this exercise, I am counting the District of Columbia as a state.</p>
<h2>States I have been to only for airport layovers:</h2>
<ul>
<li>Arizona</li>
<li>Colorado</li>
<li>Georgia</li>
<li>New Mexico</li>
</ul>
<h2>States I have never been to, not even for airport layovers:</h2>
<ul>
<li>Alabama</li>
<li>Alaska</li>
<li>Deleware</li>
<li>Florida</li>
<li>Hawaii</li>
<li>Kansas</li>
<li>Maine</li>
<li>Nevada</li>
<li>New Hampshire</li>
<li>Oklahoma</li>
<li>Rhode Island</li>
<li>South Carolina</li>
<li>Texas</li>
<li>Vermont</li>
</ul>
<h2>Canadian provinces I have visited beyond just the airport:</h2>
<ul>
<li>Alberta</li>
<li>British Columbia</li>
<li>Ontario</li>
</ul>
<p>(There is no Canadian province that I have only visited for an airport layover.)</p>
<h2>Countries I have lived in:</h2>
<ul>
<li>United Kingdom</li>
<li>United States</li>
</ul>
<h2>Countries I have not lived in, but have visited beyond just the airport:</h2>
<ul>
<li>Canada</li>
<li>South Korea</li>
<li>Vietnam</li>
</ul>
<h2>Countries I have been to only for airport layovers:</h2>
<ul>
<li>Ireland</li>
<li>The Netherlands</li>
</ul>
<p>(Technically, I visited South Korea during a long airport layover, but I left Incheon International Airport and went into Seoul.)</p>
<p><a href="2013/07/13/making-a-places-i-have-been-map/">How I made the map.</a></p>
<h2>Credit</h2>
<p>Map of the US <a href="https://commons.wikimedia.org/w/index.php?title=File:Blank_US_Map.svg&amp;oldid=99464358">adapted from a file from the Wikimedia
Commons</a>
that was originally created by Wikimedia Commons user Theshibboleth and modified
by users Fibonacci, NuclearVacuum, and Wylve. Used under the <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">Creative Commons
Attribution-ShareAlike 3.0
Unported</a> (CC-BY-SA 3.0)
license. <a href="http://blog.chrisphan.com/wp-content/uploads/US_Map_chris_visit.svg">SVG source code of my modified version of the
file.</a> Both
my modified SVG and derived PNGs are offered under the <a href="https://creativecommons.org/licenses/by-sa/3.0/deed.en">Creative Commons
Attribution-ShareAlike 3.0
Unported</a> (CC-BY-SA 3.0)
license.</p>]]></content:encoded></item><item><title>Deluge of comment spam</title><link>https:://chrisphan.com/2013/06/11/deluge-of-comment-spam/index.html</link><description><![CDATA[ This blog has received a deluge of attempted comment spam recently. Spammers attempted to post over 150 comments since the beginning of June. I say]]></description><guid>https:://chrisphan.com/2013/06/11/deluge-of-comment-spam/index.html</guid><pubDate>Tue, 11 Jun 2013 17:59:23 -0500</pubDate><content:encoded><![CDATA[
<p>This blog has received a deluge of attempted comment spam recently. Spammers attempted to post over 150 comments since the beginning of June. I say “attempted” because every comment made to this blog by a new user is sent to moderation; I have had to manually delete every spam comment made so far. I don’t know what the spammers are hoping to achieve, given I am not interested in illegally acquiring prescription pain medication, and nobody else has seen their missives on this topic they have tried to post here. But going forward, I guess I’m going to have to leave comments off.</p>]]></content:encoded></item><item><title>Facebook, “free speech”, and a monopoly on town squares</title><link>https:://chrisphan.com/2013/05/30/facebook-free-speech-and-a-monopoly-on-town-squares/index.html</link><description><![CDATA[ As you may know, there was a recent campaign by activists to pressure Facebook to remove misogynistic, in some cases graphic, posts glorifying rape and]]></description><guid>https:://chrisphan.com/2013/05/30/facebook-free-speech-and-a-monopoly-on-town-squares/index.html</guid><pubDate>Thu, 30 May 2013 19:42:59 -0500</pubDate><content:encoded><![CDATA[
<p>As you may know, there was a recent campaign by activists to pressure Facebook to remove misogynistic, in some cases graphic, posts glorifying rape and domestic violence. (If you can stomach it, Buzzfeed has <a href="http://www.buzzfeed.com/ryanhatesthis/facebook-still-doesnt-consider-rape-jokes-to-be-hate-speech">some screen shots</a> of the misogynistic posts.) Part of the motivation of this campaign was to highlight <a href="http://www.thedailybeast.com/witw/articles/2013/05/21/facebook-s-rapebook-page-shut-down-amid-graphic-threats-against-female-founders.html">Facebook’s ridiculous standards</a>: Facebook had been slow to remove the misogynistic posts, in some cases saying they weren’t hate speech, while <a href="http://bits.blogs.nytimes.com/2009/01/02/breastfeeding-facebook-photos/">removing some pictures that featured breastfeeding</a>, on the basis that the breastfeeding pictures violated Facebook’s prohibitions on nudity. As a result of the campaign, in which advertisers were pressured by activists, Facebook has <a href="https://www.facebook.com/notes/facebook-safety/controversial-harmful-and-hateful-speech-on-facebook/574430655911054">pledged to review and revise its policies, admitting that they failed to remove posts that constitute gender-based hate speech</a>:</p>
<blockquote>
<p>In some cases, content is not being removed as quickly as we want. In other cases, content that should be removed has not been or has been evaluated using outdated criteria. [. . .T]he guidelines used by these systems have failed to capture all the content that violates our standards. We need to do better – and we will.</p>
</blockquote>
<p>In considering this controversy, it’s important to remember, as Mary Gardiner <a href="http://geekfeminism.org/2012/10/13/discussion-starter-reddit-predditor-and-outing-bad-behaviour/">wrote last September (in the context of the Reddit/creepshots controversy)</a>, the phrase “freedom of speech”</p>
<blockquote>
<p>isn’t a very specific term on the Internet: it can mean anything from “I believe governments should not restrict expression” to “I believe that never deleting comments* from a forum improves the quality of discussion” to “I believe that never deleting comments from a forum is the only ethically correct way to run a forum.” (Or the disingenuous version: “I believe that I personally should be able to say what I want in any forum.”)</p>
</blockquote>
<p>(Gardiner goes on to point out that “No one seems to believe this about spam.”)</p>
<p>In response to Facebook’s announcement, Jillian C. York, Director for International Freedom of Expression for the <a href="https://www.eff.org/">Electronic Frontier Foundation</a>–a cyberspace civil liberties group whose work I generally respect and admire–wrote <a href="http://www.slate.com/blogs/xx_factor/2013/05/30/facebook_and_hate_speech_the_company_should_not_be_in_the_business_of_censorship.html">an article in <cite>Slate</cite> questioning whether Facebook should be in the business of policing “hate speech” at all</a>. Conceding that Facebook has a right as a private business to remove content it sees fit, York argues that the Facebook is ill-equipped to handle the hate speech complaints that go along with serving a billion users worldwide, citing examples where Facebook has erred. But then she goes on argue that Facebook shouldn’t engage in censorship at all, given its status as “the new town square”:</p>
<blockquote>
<p>Should private companies be determining what constitutes “hate speech”? In the United States (where Facebook is based), most of the speech flagged by Women, Action &amp; the Media as offensive is, while abhorrent, protected by law. And while Facebook may be private, many of its users treat it like the new town square, making it more of a quasi-public sphere. While the campaigners on this issue are to be commended for raising awareness of such awful speech on Facebook’s platform, their proposed solution is ultimately futile and sets a dangerous precedent for special interest groups looking to bring their pet issue to the attention of Facebook’s censors.</p>
</blockquote>
<p>Although I am very sympathetic to York’s argument, ultimately I must respectfully disagree. First of all, it’s just not feasible to expect Facebook to operate the way York suggests. Facebook’s business model involves posting advertisements on nearly every page served by the site, but a company will understandably be reluctant to advertise on Facebook if the ad might give the impression that the company supports misogyny (an impression that would not be wholly incorrect when the company’s ad is paying for the server and bandwidth costs for a misogynistic post). Facebook has to remove gender-based hate speech for the same reason <a href="http://www.weezerpedia.com/wiki/index.php?title=Hash_Pipe&amp;oldid=35135#Censorship">MTV bleeps out the word “hash” in the Weezer song “Hash Pipe”</a>. Expecting an advertisement-supported site to allow all constitutionally-protected content is a pipe dream.</p>
<p>More importantly, I think the greater issue is one company’s extent of control over Internet discourse. York’s article is accompanied by a photo of Mark Zuckerberg, with the caption “Should we give this guy the power to decide what is and isn’t hate speech?” My answer, if we’re talking about the majority of public discourse on the Internet, is a resounding “no”. Indeed, if we’re talking about the majority of public discourse on the Internet, I don’t want Mark Zuckerberg–or anyone else–to have power to decide anything. And that’s why the problem isn’t that Facebook bans hate speech; the problem is that Facebook has become the de facto default “town square”. It’s dangerous to allow any one company or entity to have this much power.</p>
<p>If you are worried about Facebook having the power to determine what is “hate speech”, then the proper solution is to encourage people to stop viewing Facebook as the de facto method of interaction on the Internet. Encourage people to use other social networks in addition to Facebook. Encourage people to use forums outside of Facebook. Share things on your own site instead of just Facebook. (My web host, <a href="https://www.nearlyfreespeech.net/">NearlyFreeSpeech.net</a>, has relatively few restrictions on content and is pretty affordable.) I’m not suggesting that people stop using Facebook, but merely that dissuade people from <em>only</em> using Facebook. If we work to ensure that there is a variety of “town squares”, then we won’t have to worry as much about the restrictions at any particular one.</p>]]></content:encoded></item><item><title>Yay for Minnesota!</title><link>https:://chrisphan.com/2013/05/14/yay-for-minnesota/index.html</link><description><![CDATA[ Earlier today, Gov. Mark Dayton signed into law a bill to recognize same-sex marriages! The law will take effect in August. Minnesota will become the]]></description><guid>https:://chrisphan.com/2013/05/14/yay-for-minnesota/index.html</guid><pubDate>Tue, 14 May 2013 21:53:03 -0500</pubDate><content:encoded><![CDATA[
<p><a href="http://www.startribune.com/politics/blogs/207434441.html">Earlier today, Gov. Mark Dayton signed into law a bill to recognize same-sex marriages!</a> The law will take effect in August. Minnesota will become the 12th state to recognize same-sex marriage.</p>
<p><strong>Yay for Minnesota!</strong> I am very proud of my new state!</p>]]></content:encoded></item><item><title>A moving speech on marriage equality</title><link>https:://chrisphan.com/2013/05/10/a-moving-speech-on-marriage-equality/index.html</link><description><![CDATA[ I’m a newcomer to Minnesota, having lived here only 9 months. But one thing that has made me proud to be a new Minnesotan is]]></description><guid>https:://chrisphan.com/2013/05/10/a-moving-speech-on-marriage-equality/index.html</guid><pubDate>Fri, 10 May 2013 22:41:02 -0500</pubDate><content:encoded><![CDATA[
<p>I’m a newcomer to Minnesota, having lived here only 9 months. But one thing that has made me proud to be a new Minnesotan is how this state has handled the issue of marriage equality. In the November 2012 election, Minnesotans defeated at the polls <a href="http://ballotpedia.org/wiki/index.php/Minnesota_Same-Sex_Marriage_Amendment,_Amendment_1_(2012)">a proposed state constitutional amendment banning on same-sex marriage</a>. And yesterday, <a href="http://minnesota.publicradio.org/display/web/2013/05/09/politics/same-sex-marriage-passes-in-minn-house">the Minnesota House of Representatives passed a bill</a> to legalize same-sex marriage.</p>
<p>Today, on Minnesota Public Radio, they were replaying speeches made in debate the Minnesota house yesterday during the floor debate before the historic vote. One speech, made Rep. Tim Faust, who is a Lutheran pastor, was particularly moving:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/IW_pMe-7hvQ?si=EWQ4nCcIKxuNfE4d" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
<p>The Minnesota Senate will vote on the bill Monday, and should it pass (which is expected), our governor has promised to sign it. While I’m not going to celebrate too much until the bill passes the Senate, it’s appearing more and more likely that next week Minnesota will become the 12th state in the union to have marriage equality.</p>]]></content:encoded></item><item><title>Record snow!</title><link>https:://chrisphan.com/2013/05/03/record-snow/index.html</link><description><![CDATA[ We had some nice spring weather this week in Southeastern Minnesota. On Tuesday, the temperature got up to 27°C (80°F) and we had our apartment]]></description><guid>https:://chrisphan.com/2013/05/03/record-snow/index.html</guid><pubDate>Fri, 3 May 2013 07:15:51 -0500</pubDate><content:encoded><![CDATA[
<p>We had some nice spring weather this week in Southeastern Minnesota. On Tuesday, the temperature got up to 27°C (80°F) and we had our apartment windows open in the evening.</p>
<p>Then on Wednesday, the temperature dropped precipitously, and we awoke on Thursday to this:</p>
<p><img src="/flickr_photos/snowy_may.jpg" alt="street with thin layer of snow" /></p>
<p>That picture was taken in the morning. The snow came down most of the day, piling up to 3.5 inches (89 mm).</p>
<p>But we didn’t get it as bad as Rochester, which is about an hour west of here. As the National Weather Service points out, Rochester didn’t break the snow record for May 2nd yesterday, they got more snow yesterday than all other days in May <strong>combined</strong> since record-keeping began in 1886. Here is the public information statement released by the La Crosse office of the NWS last night:</p>
<!-- prettier-ignore-start -->
<blockquote>
<p>000</p>
<p>NOUS43 KARX 030107</p>
<p>PNSARX</p>
<p>PUBLIC INFORMATION STATEMENT</p>
<p>NATIONAL WEATHER SERVICE LA CROSSE WI</p>
<p>807 PM CDT THU MAY 2 2013</p>
<p>…UNPRECEDENTED SNOWFALL FOR ROCHESTER MINNESOTA…</p>
<p>WHAT A STORM FOR THE RECORD BOOKS. THE INFORMATION BELOW SHOWCASES HOW THIS SNOWSTORM RANKS FROM A MAY PERSPECTIVE…AND ALSO THE ENTIRE CALENDAR YEAR.</p>
<p>THE 13.9 INCHES…THROUGH 730 PM…BREAKS THE FOLLOWING RECORDS…</p>
<p>…DAILY RECORD SNOWFALL FOR MAY 2ND / 0.7 INCHES IN 1954 /</p>
<p>…DAILY RECORD SNOWFALL FOR MONTH OF MAY / 1.2 INCHES MAY 5 1944/</p>
<p>…MAY MONTHLY SNOWFALL TOTAL / 2.0 INCHES MAY 1944 /</p>
<p>IT CURRENTLY RANKS AS SIXTH GREATEST ALL-TIME DAILY SNOWFALL. THIS WILL LIKELY RISE ONCE THE OFFICIAL SNOW TOTAL IS REPORTED.</p>
<pre style="background-color:#002b36;"><code><span style="color:#839496;">ALL-TIME 1-DAY SNOWFALL RECORDS
</span><span style="color:#839496;">             ROCHESTER MINNESOTA
</span><span style="color:#839496;">                 1886-2013
</span><span style="color:#839496;">
</span><span style="color:#839496;">   RANK          SNOWFALL         YEAR
</span><span style="color:#839496;">   ----       -------------      -------
</span><span style="color:#839496;">     1         19.8 INCHES      3/18/2005
</span><span style="color:#839496;">     2         15.4 INCHES      1/22/1982
</span><span style="color:#839496;">     3         15.0 INCHES     12/11/2010
</span><span style="color:#839496;">     4         14.0 INCHES      3/30/1934
</span><span style="color:#839496;">                                4/20/1893
</span><span style="color:#839496;">     6         13.9 INCHES      5/02/2013
</span><span style="color:#839496;">     7         13.5 INCHES      2/27/1893
</span><span style="color:#839496;">     8         13.0 INCHES      4/26/1988
</span><span style="color:#839496;">     9         12.0 INCHES     11/30/1934
</span></code></pre>
<p>OTHER RECORDS BROKEN TODAY INCLUDE…</p>
<p>THE LOWEST MAXIMUM TEMPERATURE FOR MAY 2ND…33 DEGREES. THIS ALSO MAKES
IT THE LOWEST MAXIMUM TEMPERATURE FOR ANY DAY IN THE MONTH OF MAY. THE
PREVIOUS LOWEST MAXIMUM TEMPERATURE IN MAY WAS 36 DEGREES…ON MAY 1ST 1940.</p>
<p>TO PUT THIS SNOWSTORM IN ANOTHER PERSPECTIVE…TODAYS SNOWFALL IN
ROCHESTER SHATTERS THE COMBINED TOTAL FOR ALL PREVIOUS MAY MEASURABLE SNOW
EVENTS. SINCE 1886…THERE WERE 10 MEASURABLE MAY EVENTS…FOR A TOTAL
OF 4.3 INCHES. TODAYS SNOWFALL IS OVER 3 TIMES THAT.</p>
<p>FURTHER CLIMATE AND RECORD INFORMATION WILL BE ADDED ONCE TOTALS ARE CONFIRMED
AND THE SNOW ENDS.</p>
<p>$$</p>
<p>ZT</p>
</blockquote>
<!-- prettier-ignore-end -->]]></content:encoded></item><item><title>Still some ice in the river</title><link>https:://chrisphan.com/2013/04/13/still-some-ice-in-the-river/index.html</link><description><![CDATA[ Taken at the Verchota Landing, just outside Winona in the Upper Mississippi River National Wildlife & Fish Refuge : icy but melting river icy but]]></description><guid>https:://chrisphan.com/2013/04/13/still-some-ice-in-the-river/index.html</guid><pubDate>Sun, 14 Apr 2013 00:23:41 +0000</pubDate><content:encoded><![CDATA[
<p>Taken at the Verchota Landing, just outside Winona in the <a href="http://www.fws.gov/refuge/Upper_Mississippi_River/about.html">Upper Mississippi River National Wildlife &amp; Fish Refuge</a>:</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/verchota_1.jpg" alt="icy but melting river" /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/verchota_2.jpg" alt="icy but melting river" /></p>
<p>Yikes! <a href="http://en.wikipedia.org/wiki/Zebra_mussel">Zebra mussels</a> are pretty terrible:</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/exotic_species.jpg" alt="Sign: Exotic species alert" /></p>]]></content:encoded></item><item><title>Duke of Wellington statue on Google treasure map</title><link>https:://chrisphan.com/2013/04/01/duke-of-wellington-statue-on-google-treasure-map/index.html</link><description><![CDATA[ For April Fool’s Day, Google has added a fun “treasure map” mode on Google Maps. If you zoom into various cities, you can see hand-drawn]]></description><guid>https:://chrisphan.com/2013/04/01/duke-of-wellington-statue-on-google-treasure-map/index.html</guid><pubDate>Mon, 1 Apr 2013 21:16:09 -0500</pubDate><content:encoded><![CDATA[
<p>For April Fool’s Day, Google has added a fun <a href="http://www.youtube.com/watch?v=_qFFHC0eIUc">“treasure map”</a> mode on Google Maps. If you zoom into various cities, you can see hand-drawn landmarks, such as the Sears Tower or Washington Monument. Or, if you zoom into Glasgow, you see this:</p>
<p><img src="/wp-content/uploads/Google_treasure_Glasgow.png" alt="Google map, but in a old pirate map style. Glasgow has a person on a horse with a traffic cone on his head" /></p>
<p>This is the <a href="http://en.wikipedia.org/wiki/Wellington_Statue,_Glasgow">Duke of Wellington</a> statue in front Glasgow’s Gallery of Modern Art. Here’s a real-life picture (albeit from the other side):</p>
<p><img src="/flickr_photos/wellington.jpg" alt="statue of Duke of Wellington on horse, wearing traffic cone" /></p>]]></content:encoded></item><item><title>late March in Winona</title><link>https:://chrisphan.com/2013/03/30/late-march-in-winona/index.html</link><description><![CDATA[ It’s starting to melt! A set of stationary train cars, on melting show A bird's-eye view of Lake Winona from the viewpoint at Garvin Heights.]]></description><guid>https:://chrisphan.com/2013/03/30/late-march-in-winona/index.html</guid><pubDate>Sat, 30 Mar 2013 11:07:47 -0500</pubDate><content:encoded><![CDATA[
<p>It’s starting to melt!</p>
<p><img src="/flickr_photos/winona_march/1.jpg" alt="A set of stationary train cars, on melting show" /></p>
<p><img src="/flickr_photos/winona_march/2.jpg" alt="A bird's-eye view of Lake Winona from the viewpoint at Garvin Heights. The lake is frozen but starting to melt." /></p>
<p><img src="/flickr_photos/winona_march/3.jpg" alt="A bird's-eye view of Lake Winona, showing the valley to the south. The lake is frozen but starting to melt." /></p>
<p><img src="/flickr_photos/winona_march/4.jpg" alt="A bird's-eye view of Lake Winona, showing the east end of town. The lake is frozen but starting to melt." /></p>]]></content:encoded></item><item><title>SageTeX is awesome!</title><link>https:://chrisphan.com/2013/03/07/sagetex-is-awesome/index.html</link><description><![CDATA[ For a long time, I have been a user of the math software system Sage , and for a longer time, I have been a]]></description><guid>https:://chrisphan.com/2013/03/07/sagetex-is-awesome/index.html</guid><pubDate>Fri, 8 Mar 2013 21:39:36 -0600</pubDate><content:encoded><![CDATA[
<p>For a long time, I have been a user of the math software system <a href="http://sagemath.org/">Sage</a>, and
for a longer time, I have been a user of <a href="http://www.latex-project.org/">LaTeX</a>. So, it’s with some
embarrassment that I report that I only recently discovered the awesomeness that
is <a href="http://www.ctan.org/tex-archive/macros/latex/contrib/sagetex/">SageTeX</a>, a LaTeX package that allows your LaTeX document to run Sage
code and include the results.</p>
<p>I often use Sage to create plots for use in my lectures or printed class
materials. Previously, my workflow was as follows:</p>
<ol>
<li>Create the graphic by running commands in the Sage notebook.</li>
<li>Use the <code>save</code> command to save the graphic as a PDF, usually with a
filename based on my LaTeX source file’s name (e.g.
<code>m160-sp13-mid2-practice-1.pdf</code>, for use in the LaTeX document with source
file <code>m160-sp13-mid2-practice.tex</code>).</li>
<li>Save the file in the directory where my LaTeX source file lives.</li>
<li><code>\includegraphics</code>, FTW!</li>
</ol>
<p>Like most teachers, every time I teach a course I’ve taught before, I like
to reuse old materials, often after improving them or adjusting them to suit the
new class. Therefore, it’s good to record the exact Sage commands
somewhere, as opposed to just keeping the graphic file, in case I want to modify
the graphic. One way you can do this is to paste the Sage commands as a comment
in the LaTeX file. This has the advantage of allowing future tweaks to be
recorded in your version control system. (<a href="https://web.archive.org/web/20120419063624/http://imprompt.us/2010/why-version-control/">And you <em>really should</em> be using a
version control system, so that way you won’t be afraid to make changes to
your document.</a>) Unfortunately, modifications then mean a lot of
copy-and-pasting: you have to modify the code in the Sage notebook, and then
copy-and-paste the modifications to the comments in the LaTeX document, or
vice-versa. And then you have to save another version of your graphic from the
browser. What a headache!</p>
<p>SageTeX makes this a lot easier. When I want to put a Sage plot in my document,
I can put the Sage commands right in the document:</p><div class="code_block"><div class="code-header"><span class="code-lang">LaTeX</span></div><pre class=""  id="block-631e3023-9e10-44db-813d-bd2db5801b81"><code class="language-latex"><code class="code-elipsis" id="block-631e3023-9e10-44db-813d-bd2db5801b81-elipsis-start"></code>
<code class="checker "><span style="color:#859900;">\begin</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">sagesilent</span><span style="color:#839496;">}</span></code>
<code class="checker "><span style="color:#839496;">var(&#39;x,y&#39;)</span></code>
<code class="checker "><span style="color:#839496;">gfx = implicit_plot((x + 1)*(x^2 + y^2) == 3*x^2, (x, -2, 2),(y, -2, 2), axes=true, frame=false)</span></code>
<code class="checker "><span style="color:#839496;">gfx = gfx + list_plot([(1/2, -1/2)], size=50)</span></code>
<code class="checker "><span style="color:#839496;">save(gfx, &quot;m160-sp13-mid2-practice-1.pdf&quot;, figsize=[3, 3])</span></code>
<code class="checker "><span style="color:#859900;">\end</span><span style="color:#839496;">{</span><span style="color:#cb4b16;">sagesilent</span><span style="color:#839496;">}</span></code>
<code class="checker "><span style="color:#839496;"></span></code>
<code class="checker "><span style="color:#859900;">\item</span><span style="color:#839496;"> (15 points)</span></code>
<code class="checker "><span style="color:#839496;">Consider the curve with the equation</span></code>
<code class="checker "><span style="color:#839496;">$</span><span style="color:#cb4b16;">(</span><span style="color:#268bd2;">x </span><span style="color:#859900;">+ </span><span style="color:#6c71c4;">1</span><span style="color:#cb4b16;">)(</span><span style="color:#268bd2;">x</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">2 </span><span style="color:#859900;">+ </span><span style="color:#268bd2;">y</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">2</span><span style="color:#cb4b16;">) </span><span style="color:#859900;">= </span><span style="color:#6c71c4;">3</span><span style="color:#268bd2;">x</span><span style="color:#859900;">^</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">$ (shown below).</span></code>
<code class="checker "><span style="color:#839496;">Use implicit differentation to find $</span><span style="color:#859900;">\tfrac</span><span style="color:#839496;">{</span><span style="color:#268bd2;">dy</span><span style="color:#839496;">}{</span><span style="color:#268bd2;">dx</span><span style="color:#839496;">}$,</span></code>
<code class="checker "><span style="color:#839496;">and then find an equation for the tangent line</span></code>
<code class="checker "><span style="color:#839496;">of the curve at the point</span></code>
<code class="checker "><span style="color:#839496;">$</span><span style="color:#859900;">\left</span><span style="color:#cb4b16;">(</span><span style="color:#859900;">\tfrac</span><span style="color:#839496;">{</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">}{</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">},</span><span style="color:#859900;">-\tfrac</span><span style="color:#839496;">{</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">}{</span><span style="color:#6c71c4;">2</span><span style="color:#839496;">}</span><span style="color:#859900;">\right</span><span style="color:#cb4b16;">)</span><span style="color:#839496;">$.</span><span style="color:#cb4b16;">\\</span></code>
<code class="checker "><span style="color:#859900;">\includegraphics</span><span style="color:#839496;">[</span><span style="color:#268bd2;">width</span><span style="color:#839496;">=3 in]{m160-sp13-mid2-practice-1.pdf}</span></code>
<code class="code-elipsis" id="block-631e3023-9e10-44db-813d-bd2db5801b81-elipsis-end"></code>
</code></pre></div>
<p>When you compile your document with <code>pdflatex</code>, it creates a Sage script file
titled (in this case) <code>m160-sp13-mid2-practice.sagetex.py</code>. Compiling this with
Sage will create (or update) the file <code>m160-sp13-mid2-practice-1.pdf</code>, which you
can include (or update) by running <code>pdflatex</code> again!</p>
<p>That’s pretty awesome.</p>]]></content:encoded></item><item><title>Ha ha nice try</title><link>https:://chrisphan.com/2013/03/01/ha-ha-nice-try/index.html</link><description><![CDATA[ Transaction is completed Payment notification system [Redacted]@gmail.com To: phan03 Cc: [Redacted] ACH transaction is completed. $8047 has been successfully transferred. If the transaction was made]]></description><guid>https:://chrisphan.com/2013/03/01/ha-ha-nice-try/index.html</guid><pubDate>Fri, 1 Mar 2013 21:51:58 -0600</pubDate><content:encoded><![CDATA[
<p><img src="/wp-content/uploads/Screenshot_2013-03-01-21-44-081.png" 
alt="scam email" width="320" height="180" /></p>
<blockquote>
<p>Transaction is completed</p>
<p>Payment notification system [Redacted]@gmail.com</p>
<p>To: phan03</p>
<p>Cc: [Redacted]</p>
<p>ACH transaction is completed. $8047 has been successfully transferred. If the
transaction was made by mistake please contact our customer service. Payment
receipt is attached.</p>
<p>*** This is an automatically generated email, please do not reply ***</p>
<p>Executable Attachment Removed</p>
</blockquote>]]></content:encoded></item><item><title>Winona in late February</title><link>https:://chrisphan.com/2013/02/24/winona-in-late-february/index.html</link><description><![CDATA[ Sarah and I took a break from grading to enjoy the lake today. snow-covered, frozen lake Winona birds in a spot of open water Sign:]]></description><guid>https:://chrisphan.com/2013/02/24/winona-in-late-february/index.html</guid><pubDate>Sun, 24 Feb 2013 22:53:33 -0600</pubDate><content:encoded><![CDATA[
<p>Sarah and I took a break from grading to enjoy the lake today.</p>
<p><img src="/flickr_photos/winona_february/3.jpg" alt="snow-covered, frozen lake Winona" /></p>
<p><img src="/flickr_photos/winona_february/4.jpg" alt="birds in a spot of open water" /></p>
<p><img src="/flickr_photos/winona_february/5.jpg" alt="Sign: Warning: An aeration system creating open water and thin ice is in use on this lake. USE EXTREME CAUTION." /></p>
<p>Here’s a device they use to keep part of the lake from freezing over:</p>
<p><img src="/flickr_photos/winona_february/6.jpg" alt="aeration system" /></p>
<p><img src="/flickr_photos/winona_february/7.jpg" alt="open water in lake" /></p>
<p><img src="/flickr_photos/winona_february/8.jpg" alt="Thin ice signs" /></p>
<p><a href="http://www.youtube.com/watch?v=tBb4cjjj1gI&amp;t=1m42s">“On very thin ice, very thin ice, very thin ice, very thin ice…”</a></p>]]></content:encoded></item><item><title>Winona in February</title><link>https:://chrisphan.com/2013/02/06/winona-in-february/index.html</link><description><![CDATA[ snow-covered, frozen lake Winona snow-covered, frozen lake Winona (That’s a lake, BTW.)]]></description><guid>https:://chrisphan.com/2013/02/06/winona-in-february/index.html</guid><pubDate>Wed, 6 Feb 2013 20:11:04 -0600</pubDate><content:encoded><![CDATA[
<p><img src="/flickr_photos/winona_february/1.jpg" alt="snow-covered, frozen lake Winona" /></p>
<p><img src="/flickr_photos/winona_february/2.jpg" alt="snow-covered, frozen lake Winona" /></p>
<p>(That’s a lake, BTW.)</p>]]></content:encoded></item><item><title>Thanks</title><link>https:://chrisphan.com/2013/01/21/thanks/index.html</link><description><![CDATA[]]></description><guid>https:://chrisphan.com/2013/01/21/thanks/index.html</guid><pubDate>Mon, 21 Jan 2013 16:49:51 -0600</pubDate><content:encoded><![CDATA[
<p><a href="http://arcweb.archives.gov/arc/action/ExternalIdSearch?id=542069"><img src="/wp-content/uploads/mlk.jpg" alt="Martin Luther King, Jr" /></a></p>]]></content:encoded></item><item><title>Winona in January</title><link>https:://chrisphan.com/2013/01/19/winona-in-january/index.html</link><description><![CDATA[ frozen Mississippi from Winona's waterfront, looking north frozen Mississippi from Winona's waterfront, looking south frozen lake Winona frozen lake Winona]]></description><guid>https:://chrisphan.com/2013/01/19/winona-in-january/index.html</guid><pubDate>Sat, 19 Jan 2013 18:40:36 -0600</pubDate><content:encoded><![CDATA[
<p><img src="/flickr_photos/winona_january/1.jpg" alt="frozen Mississippi from Winona's waterfront, looking north" /></p>
<p><img src="/flickr_photos/winona_january/2.jpg" alt="frozen Mississippi from Winona's waterfront, looking south" /></p>
<p><img src="/flickr_photos/winona_january/3.jpg" alt="frozen lake Winona" /></p>
<p><img src="/flickr_photos/winona_january/4.jpg" alt="frozen lake Winona" /></p>]]></content:encoded></item><item><title>Up goer five dissertation summary</title><link>https:://chrisphan.com/2013/01/19/up-goer-five-dissertation-summary/index.html</link><description><![CDATA[ I learned about this Tumblr blog where people try to summarize their PhD dissertations in the style of xkcd’s “Up Goer Five” comic—that is, “using]]></description><guid>https:://chrisphan.com/2013/01/19/up-goer-five-dissertation-summary/index.html</guid><pubDate>Sat, 19 Jan 2013 14:34:05 -0600</pubDate><content:encoded><![CDATA[
<p>I learned about <a href="http://upgoeryourphd.tumblr.com/">this Tumblr blog</a> where people try to summarize their PhD dissertations in the style of xkcd’s <a href="http://xkcd.com/1133/">“Up Goer Five”</a> comic—that is, “using only the ten hundred words people use most often”. There’s <a href="http://splasho.com/upgoer5/">an online text editor</a> that checks whether you’ve strayed from these thousand most-common words.</p>
<p>Inspired by this blog, here’s my attempt to summarize my dissertation (<a href="http://www.chrisphan.com/dissertation.pdf"><em>Koszul and generalized Koszul properties for noncommutative graded algebras</em></a>) in “Up Goer Five” style:</p>
<blockquote>
<p>You can add and times numbers. There are ways make up a set other things you can add and times like you can with numbers. We call these sets “rings”. Sometimes, with these new things, the order in which you times things changes what you get.</p>
<p>Some of these rings have floors, like a building. When you times two things in the ring, you have to add the floor numbers to figure out which floor the thing you get is on.</p>
<p>There is a way to study these rings with floors with strange add and times that comes from the study of forms in space. Given a ring with floors, you can make a new ring with floors that is sort of like it, but with some things about it inside out.</p>
<p>I studied stuff about these new rings with floors coming from the old, especially in cases where the order in which you times things changes what you get from times.</p>
</blockquote>
<p>And here’s Sarah’s “Up Goer Five” summary of her dissertation (<a href="http://www.hep.uiuc.edu/hepg/Theses/Budd_2008.pdf"><em>Search for single top quark production with the CDF Run II detector using a multivariate likelihood method</em></a>):</p>
<blockquote>
<p>We made very very very small but very heavy things (called top things) in a new way. These top things are very small and are like a point, but are very heavy. They also live for a very short time. Usually you see two top things made at the same time. We found one top thing made with another thing. This one top thing looks a lot like other small heavy things that are made more easily. So, we had to tell our one top thing from all the other small heavy things that we made as well. It was hard. We used computers to help with the numbers. I worked with many people. But, I found the one top thing turning into three other things, while other people found the one top thing turning into two other things. We added my finding with my friends to make a strong finding.</p>
<p>Our finding was so strong we thought for sure it was true. But, we like to know for sure for sure for sure, not just for sure. So, the next year another friend made another finding of the same thing. With our finding and the new finding and we thought for sure for sure for sure it was true. So, now every person thinks our finding is true as well. Now our finding is in the way of seeing other new very small very heavy things, but that is life.</p>
</blockquote>]]></content:encoded></item><item><title>Lake Winona, frozen over</title><link>https:://chrisphan.com/2013/01/16/lake-winona-frozen-over/index.html</link><description><![CDATA[ Lake Winona, frozen over]]></description><guid>https:://chrisphan.com/2013/01/16/lake-winona-frozen-over/index.html</guid><pubDate>Wed, 16 Jan 2013 20:59:36 -0600</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/frozen_lake_winona.jpg" alt="Lake Winona, frozen over" /></p>]]></content:encoded></item><item><title>2012 Year in Review</title><link>https:://chrisphan.com/2012/12/26/2012-year-in-review/index.html</link><description><![CDATA[ It’s the end of the year, and hence time for another year in review letter .]]></description><guid>https:://chrisphan.com/2012/12/26/2012-year-in-review/index.html</guid><pubDate>Tue, 25 Dec 2012 23:27:33 -0800</pubDate><content:encoded><![CDATA[
<p>It’s the end of the year, and hence time for <a href="http://phanbudd.com/letters/2012/">another year in review letter</a>.</p>]]></content:encoded></item><item><title>Policies aren’t the only thing that matter in elections</title><link>https:://chrisphan.com/2012/10/23/policies-arent-the-only-thing-that-matter-in-elections/index.html</link><description><![CDATA[ Much of the talk about “values” and “character” that surrounds elections is phony, not uncommon for campaign rhetoric, but it’s a mistake for voters to]]></description><guid>https:://chrisphan.com/2012/10/23/policies-arent-the-only-thing-that-matter-in-elections/index.html</guid><pubDate>Wed, 24 Oct 2012 23:03:44 -0500</pubDate><content:encoded><![CDATA[
<p>Much of the talk about “values” and “character” that surrounds elections is phony, not uncommon for campaign rhetoric, but it’s a mistake for voters to disregard these issues.</p>
<p>Every once in a while, I’ll run across some online quiz where you answer some questions about your policy preferences—e.g. should we spend more or less on war—and it identifies the presidential candidate you should support. I regard these results with some skepticism. It’s not just because I’m worried the issues might be cherry-picked, and it’s not just because such questionnaires usually fail to ask about the strengths of my beliefs. It’s because such metrics disregard the candidates’ competence and trustworthiness.</p>
<p>I moved away from Portland in 2003, haven’t lived there since, and doubt I’ll live there again. So, let me disclose up front that I don’t have much of a stake in the upcoming mayoral election there. But I have been following it, because I find it interesting.</p>
<p>Portland uses a nonpartisan two-round system for municipal elections. Advancing to the second round are Charlie Hales, a former city commissioner, and Jefferson Smith, a state legislator and founder of the Bus Project, a group that gets young people involved in progressive politics in Oregon. (<a href="http://www.flickr.com/photos/functoruser/2997694521/lightbox/">Here’s a picture</a> of me wearing a button reading “I’m on the Bus”. I’m posing with the guy who ran <a href="http://www.youtube.com/watch?v=N2UesvrH-cs">this awesome ad</a>.) Both are Democrats, which is unsurprising given that <a href="http://community.statesmanjournal.com/blogs/data/2012/03/30/oregon-voter-registration-totals-by-county/?appSession=001329967327232">Democrats outnumber Republicans</a> by over a 3-to-1 ratio in Multnomah County.</p>
<p>Smith seemed like a rising star in Oregon politics, but some unpleasant background surfaced in the mayoral race. First, there was his <a href="http://www.oregonlive.com/portland/index.ssf/2012/08/jefferson_smith_i_have_a_bad_d.html">“embarrassing” driving record</a> (to use his word), which included a citation for driving with a suspended license.</p>
<p>More troubling were two incidents of violence. <a href="http://www.wweek.com/portland/blog-29290-police_report_and_vi.html">He punched a woman while in college</a>, back in 1993, hard enough that she needed stitches. The victim told police that he had spent the evening leading up to the punch harassing her. In a stunningly idiotic move, Smith turned up uninvited at the home of the victim on the day the story would break, ostensibly to assure her that he wouldn’t identify her publicly. This and his failure to disclose the incident earlier are distressing.</p>
<p>More recently, <em>last year</em>, <a href="http://www.wweek.com/portland/article-19396-red_card.html">Smith was kicked out of a pick-up basketball game for fighting</a>. Other witnesses say Smith punched a man in the groin; Smith denies he hit the groin specifically. Before that, in January 2011, he was banned from a co-ed soccer league for a season after pushing another player.</p>
<p>(In the interest of fairness, I will also point out that there are allegations that Hales, Smith’s opponent, <a href="http://www.oregonlive.com/portland/index.ssf/2011/06/portland_mayoral_candidate_cha.html">claimed Washington residency for tax purposes while continuing to vote in Oregon</a>.)</p>
<p>Unsurprisingly, Smith’s candidacy has been hurt by this. <a href="http://www.oregonlive.com/portland/index.ssf/2012/10/another_union_pulls_its_jeffer.html">Some organizations have withdrawn their endorsement.</a> In response, Smith’s campaign blamed the media for “character assassination”. <a href="http://www.oregonlive.com/portland/index.ssf/2012/10/jefferson_smith_supporters_dec.html">Quoth the <cite>Oregonian</cite></a>,</p>
<blockquote>
<p>Jefferson Smith supporters are trying to raise money to buy ads that would blame the candidate’s recent troubles on “gotcha” journalism.</p>
<p>An email circulating this week says coverage of the Portland mayoral candidate in The Oregonian and Willamette Week newspapers amounts to “character assassination.” The email lists other supporters and asks for money to buy ads in the two newpapers.</p>
<p>“Their coverage has bypassed the issues and the positions of the candidates in favor of ‘gotcha’ journalism,” the email reads. “Portland deserves better.” The group is also planning a news conference this week, the email says.</p>
</blockquote>
<p>This is absurd. Portland does deserve a debate on policy issues, but a candidate’s character and competency is also important. It’s impossible to predict exactly what issues an elected official will face—<a href="http://www.nytimes.com/2012/09/13/us/portland-approves-adding-fluoride-to-water-by-14.html">I don’t think most Portland voters predicted that water fluoridation would later become an issue when they voted in the last election</a>—and so Smith is asking voters to trust his judgement to make decisions on unforeseen issues. His past decisions, the good and the bad, is all voters have to go on. And so it’s absolutely appropriate for the media to shed light on a candidate’s past, and what the candidate has done to learn from their past, especially in the wake of the candidate’s failure to disclose major incidents.</p>
<p>Likewise, competency is an important issue. Even if a candidate is on the right side of all the issues, they might still be terrible at doing the job. Temperament comes into play as well; I believe the current dysfunction in Congress has less to do with policy positions and more to do with the poor temperament: the unwillingness to compromise, the preference starting fights over finding solutions. Likewise, electing a mayor that has a problem with punching people probably doesn’t encourage a functioning city government.</p>
<p>Smith blames the media for his political problems, instead of his own poor handling of his past misbehavior. Smith seems to think that character issues are unimportant. That, alone, is probably a good reason for Portland voters to be reject him.</p>]]></content:encoded></item><item><title>The only explanation that makes sense to me is misogyny</title><link>https:://chrisphan.com/2012/10/15/the-only-explanation-that-makes-sense-to-me-is-misogyny/index.html</link><description><![CDATA[ Let’s consider two morally problematic actions: Surreptitiously taking photographs of women, or stealing them from the women’s Facebook pages, and posting them on a forum]]></description><guid>https:://chrisphan.com/2012/10/15/the-only-explanation-that-makes-sense-to-me-is-misogyny/index.html</guid><pubDate>Mon, 15 Oct 2012 22:15:09 -0500</pubDate><content:encoded><![CDATA[
<p>Let’s consider two morally problematic actions:</p>
<ol>
<li>
<p>Surreptitiously taking photographs of women, or stealing them from the women’s Facebook pages, and posting them on a forum with the explicit intent of having you and your buddies leer at said women.</p>
</li>
<li>
<p>Unmasking the identity of a person who participates in a forum pseudonymously, against that person’s wishes.</p>
</li>
</ol>
<p>The last few days, <a href="http://gawker.com/5950981/unmasking-reddits-violentacrez-the-biggest-troll-on-the-web">since a reporter at Gawker did action (2) to the moderator of a forum dedicated to (1)</a>, I have been trying to imagine a reasonable system of ethics under which (1) is acceptable but (2) is not. Indeed, I can’t even come up with a reasonable argument why (2) is worse than (1). Or an explanation, other than misogyny, why a person would think (2) is worse than (1).</p>
<p>Nevertheless, the reaction of much of the Reddit user community has been <a href="http://www.guardian.co.uk/media/2012/oct/12/reddit-blocks-gawker-creepshot-photos">anger at <em>Gawker</em> for the unmasking</a>, and solidarity with the moderator of a forum titled “Creepshots”.</p>
<p>Personally, I’m inclined to agree with <a href="http://www.lawyersgunsmoneyblog.com/2012/10/why-norms-have-exceptions">Scott Lemieux</a>: while outing pseudonymous people online is generally a bad thing, this case is probably a reasonable exception.</p>
<p>Also, one of the most stunning revelations in the <cite>Gawker</cite> story</a>, in my mind, is the relationship between Reddit’s administrators and the guy who was running the “Creepshots” forum.</p>
<blockquote>
<p>But Violentacrez has historically had a close relationship with Reddit’s staff, a fact far less well-known than his controversial behavior. [. . .] A few years ago, while Jailbait [a forum dedicated to leering a photos of teenage girls] was still going strong, Reddit’s administrators gave him a special one-of-a-kind “pimp hat” badge to honor his contributions to the site, which he proudly displayed on his profile. Brutsch said he was even in the final running for a job as a customer support representative at Reddit last year.</p>
</blockquote>
<p>This is beyond the laissez-faire “we let people post whatever legal content they want” attitude. Seriously, if someone you know runs a forum dedicated to leering at teenage girls, or leering over photos of women taken surreptitiously, you don’t give that person an award. You shun them.</p>]]></content:encoded></item><item><title>How can this be for real?</title><link>https:://chrisphan.com/2012/10/10/how-can-this-be-for-real/index.html</link><description><![CDATA[ Someone tried to leave this comment on my blog: Aug 21st 2012 – Interior decoration is a matter of pleasure or stress, depending on how]]></description><guid>https:://chrisphan.com/2012/10/10/how-can-this-be-for-real/index.html</guid><pubDate>Thu, 11 Oct 2012 22:34:45 -0500</pubDate><content:encoded><![CDATA[
<p>Someone tried to leave this comment on my blog:</p>
<blockquote>
<p>Aug 21st 2012 – Interior decoration is a matter of pleasure or stress, depending on how you look at it. This technology is brand new and has only been around for the past 6 months. The flight is scheduled according to the needs of the passenger at his or her own pace complete with any stops or side-trips that may be requested. How can this be for real? Something is going wrong. It is 2012, and this is the United States of America</p>
</blockquote>
<p>Does that make any sense? Not really. I posted it because I found it particularly amusing. This was, indeed, the 167th spam comment I’ve received. (In the URL field was the address for some site selling cheap handbags.) Something <em>is</em> going wrong, at least for this commenter. It is 2012, this is the United States of America, and I moderate my comments, bozo!</p>]]></content:encoded></item><item><title>socialized pot</title><link>https:://chrisphan.com/2012/10/05/socialized-pot/index.html</link><description><![CDATA[ A few months ago, I made a half-joking post about the government monopoly on the retail sale of liquor in many states, including my native]]></description><guid>https:://chrisphan.com/2012/10/05/socialized-pot/index.html</guid><pubDate>Fri, 5 Oct 2012 23:17:13 -0500</pubDate><content:encoded><![CDATA[
<p>A few months ago, I made a half-joking post about the government monopoly on the retail sale of liquor in many states, including my native Oregon, calling it <a href="https://chrisphan.com/2012/05/28/socialized-booze/">“socialized booze”</a>. Part of the point of that post is that I am tired of people calling things (like certain recent laws to improve health care) “socialism” that don’t involve public or government ownership of capital. When people misuse the word “socialism” to mean “government subsidy or social welfare program”, I have an urge to hit them over the head with a political science textbook.</p>
<p>Anyway, if you think socialized booze is weird, wait until you learn about socialized pot. This fall, Oregonians will vote on <a href="http://ballotpedia.org/wiki/index.php/Oregon_Cannabis_Tax_Act_Initiative,_Measure_80_(2012)">a ballot measure to legalize marijuana</a>. But this measure wouldn’t just legalize marijuana, but set up a system where the state government would buy pot from growers and sell it to consumers at state stores.</p>
<p>Mind you, I don’t have a strong opinion on this measure, and as I don’t live in Oregon anymore I don’t need to decide how vote on it. I am sympathetic to legalizing marijuana and to changing our drug laws generally. But I’m not quite sure of the wisdom of having the government in the pot-selling business. (Or the booze-selling business, for that matter.)</p>]]></content:encoded></item><item><title>a beautiful fall day along the Upper Misssissippi</title><link>https:://chrisphan.com/2012/09/30/a-beautiful-fall-day-along-the-upper-misssissippi/index.html</link><description><![CDATA[ An orchard. Behind the orchard is a hill with trees with colorful leaves. Two trees in front of the orchard have colorful leaves as well.]]></description><guid>https:://chrisphan.com/2012/09/30/a-beautiful-fall-day-along-the-upper-misssissippi/index.html</guid><pubDate>Sun, 30 Sep 2012 21:40:03 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/beaut_day_2012-09-30/1.jpg" alt="An orchard. Behind the orchard is a hill with trees with colorful leaves. Two trees in front of the orchard have colorful leaves as well." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/beaut_day_2012-09-30/2.jpg" alt="A pair of tracks tracks along the Mississippi." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/beaut_day_2012-09-30/3.jpg" alt="A pair of train tracks along the Mississippi river. Next to the tracks in a railroad sign reading &quot;Trempealaeu&quot;." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/beaut_day_2012-09-30/4.jpg" alt="A pair of barges inside a lock. One has an open lid." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/beaut_day_2012-09-30/5.jpg" alt="A pair of barges inside a lock. You can see the dam in the background." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/beaut_day_2012-09-30/6.jpg" alt="A red brick church, and a steep street that runs alongside the church." /></p>]]></content:encoded></item><item><title>One neat thing about Apple’s new maps</title><link>https:://chrisphan.com/2012/09/29/one-neat-thing-about-apples-new-maps/index.html</link><description><![CDATA[ I don’t have any iThings, so I haven’t tried the new Apple Maps in iOS 6, which appear to have been met with almost uniform]]></description><guid>https:://chrisphan.com/2012/09/29/one-neat-thing-about-apples-new-maps/index.html</guid><pubDate>Sat, 29 Sep 2012 22:54:00 -0500</pubDate><content:encoded><![CDATA[
<p>I don’t have any iThings, so I haven’t tried the new Apple Maps in iOS 6, which appear to have been met with almost uniform disappointment from those who have tried them. But while browsing <a href="http://theamazingios6maps.tumblr.com/">this incredibly amusing blog</a> dedicated to documenting errors in the new Apple Maps, I noticed one really neat feature: specific state route shields! Most maps (paper or online) use a generic oval shield for state routes, but Apple Maps appears to use the proper route shield, as seen here for <a href="http://theamazingios6maps.tumblr.com/post/32038269902/i-didnt-realize-that-wilkes-barre-pa-was-located">Pennsylvania</a>, <a href="http://theamazingios6maps.tumblr.com/post/32055905836/yup-lexington-avenue-is-now-in-brooklyn-and-no">New York</a>, <a href="http://theamazingios6maps.tumblr.com/post/32188754909/new-orleans-famously-misplaced-crescent-city">Louisiana</a>, and <a href="http://theamazingios6maps.tumblr.com/post/32188774487/apple-thinks-that-much-of-the-east-side-of">Oregon</a>.</p>
<p>This is a nice touch that Google should copy immediately.</p>]]></content:encoded></item><item><title>Some state route shields, reviewed</title><link>https:://chrisphan.com/2012/09/27/some-state-route-shields-reviewed/index.html</link><description><![CDATA[ I have lived in four states: Of these four states, I believe Pennsylvania has the best route shield. Pennsylvania is the keystone state (if you]]></description><guid>https:://chrisphan.com/2012/09/27/some-state-route-shields-reviewed/index.html</guid><pubDate>Thu, 27 Sep 2012 08:01:12 -0500</pubDate><content:encoded><![CDATA[
<p>I have lived in four states:</p>
<p><a href="http://commons.wikimedia.org/wiki/File:PA-45.svg"><img title="75px-PA-45" src="https://chrisphan.com/wp-content/uploads/75px-PA-45.png" alt="A white shape made by taking a trapezoid and appending a shorter trapezoid on top, with 45 in black letters inside." width="75" height="75" /></a></p>
<p>Of these four states, I believe <strong>Pennsylvania</strong> has the best route shield. Pennsylvania is the keystone state (if you don’t understand why, look at <a href="http://en.wikipedia.org/wiki/File:Map_of_territorial_growth_1775.svg">a map of the original 13 states</a>), and so it’s fitting that the route shield looks like a keystone. Distinctive and legible—good qualities in a route shield.</p>
<p><a href="http://commons.wikimedia.org/wiki/File:MN-43.svg"><img src="https://chrisphan.com/wp-content/uploads/75px-MN-43.png" alt="A blue rectangle with a gold border. Inside the rectangle reads the label 43. The top gold border is thick, with an outline of Minnesota followed by the word Minnesota inside." title="75px-MN-43" width="75" height="75" /></a></p>
<p>I like the <strong>Minnesota</strong> route shield. The colors are nice. I also like the small outline of the state in the corner. One issue is that it’s kind of hard to read the “Minnesota” from far away, but you don’t really need to, given that this shield is so distinctive.</p>
<p><a href="http://commons.wikimedia.org/wiki/File:OR_212.svg"><img src="https://chrisphan.com/wp-content/uploads/75px-OR_212.png" alt="A white shape that looks sort of like a guitar pick with 212 inside." title="75px-OR_212" width="75" height="60" /></a></p>
<p>The route shield of my home state of <strong>Oregon</strong> leaves something to be desired. It’s not very distinctive: it looks very much like all the other states that use a circular or vaguely oval-like pattern. When I was a child, I thought this route shield was some sort of deformed oval, like the default oval used for state highways on maps, until I realized it’s supposed to be <a href="http://bluebook.state.or.us/images/facts/almanac/sealbig.jpg">the state seal</a>. Except, with three-digit highways, they have to distort the seal to make it wide enough. I’m not saying Oregon should change its route shield—that would be a waste of money—but it’s really sad that such a beautiful state has such a drab route shield.</p>
<p><a href="http://en.wikipedia.org/wiki/File:Illinois_59.svg"><img src="https://chrisphan.com/wp-content/uploads/75px-Illinois_59.png" alt="A white square with a simple black border, and the text Illinois and a bigger 59 inside." title="75px-Illinois_59" width="75" height="75" /></a></p>
<p>Sorry, but I don’t like <strong>Illinios</strong>’s route shield. It’s extremely boring and undistinctive. Worse, it looks too much like a speed limit sign!</p>
<p>(Route shields by Wikipedia users <a href="http://commons.wikimedia.org/wiki/File:PA-45.svg">TwinMetsFan</a>, <a href="http://commons.wikimedia.org/wiki/File:MN-43.svg">Master_son</a>, <a href="http://commons.wikimedia.org/wiki/File:OR_212.svg">Fredddie</a>, and <a href="http://en.wikipedia.org/wiki/File:Illinois_59.svg">SPUI</a>, respectively. The Oregon Route shield image is used under a <a href="http://creativecommons.org/licenses/by-sa/3.0/deed.en">CC-BY-SA</a> license.)</p>]]></content:encoded></item><item><title>61/14 or 14/61?</title><link>https:://chrisphan.com/2012/09/25/6114-or-1461/index.html</link><description><![CDATA[ The major highway through this town is a concurrency of U.S. Route 14 and U.S. Route 61. Some of the signage looks like this: U.S.]]></description><guid>https:://chrisphan.com/2012/09/25/6114-or-1461/index.html</guid><pubDate>Wed, 26 Sep 2012 21:10:47 -0500</pubDate><content:encoded><![CDATA[
<p>The major highway through this town is a concurrency of U.S. Route 14 and U.S. Route 61. Some of the signage looks like this:</p>
<p><img src="https://blog.chrisphan.com/wp-content/uploads/75px-US_61.png" alt="U.S. 61 route shield" /><img src="https://blog.chrisphan.com/wp-content/uploads/75px-US_14.png" alt="U.S. 14 route shield" /></p>
<p>And some of the signage looks like this:</p>
<p><img src="https://blog.chrisphan.com/wp-content/uploads/75px-US_14.png" alt="U.S. 14 route shield" /><img src="https://blog.chrisphan.com/wp-content/uploads/75px-US_61.png" alt="U.S. 61 route shield" /></p>
<p>I still haven’t figured out what determines the order of the route shields.</p>
<p>(Route shields by Wikipedia user SPUI: <a href="http://commons.wikimedia.org/wiki/File:US_14.svg">14 source</a>, <a href="http://commons.wikimedia.org/wiki/File:US_61.svg">61 source</a>.)</p>]]></content:encoded></item><item><title>Alternate side</title><link>https:://chrisphan.com/2012/09/21/alternate-side/index.html</link><description><![CDATA[ A sign reads: "City wide alternate side parking Nov 15-Mar 15, 12:01 am-6:30 am". Below is another sign prohibiting parking (at this location) at any]]></description><guid>https:://chrisphan.com/2012/09/21/alternate-side/index.html</guid><pubDate>Fri, 21 Sep 2012 19:27:47 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/alternate_side.jpg" alt="A sign reads: &quot;City wide alternate side parking Nov 15-Mar 15, 12:01 am-6:30 am&quot;. Below is another sign prohibiting parking (at this location) at any time." /></p>]]></content:encoded></item><item><title>sharrow</title><link>https:://chrisphan.com/2012/09/21/sharrow/index.html</link><description><![CDATA[ A sharrow painted on the street: A bicycle symbol accompanied by a pair of chevrons.]]></description><guid>https:://chrisphan.com/2012/09/21/sharrow/index.html</guid><pubDate>Fri, 21 Sep 2012 19:27:18 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/sharrow.jpg" alt="A sharrow painted on the street: A bicycle symbol accompanied by a pair of chevrons." /></p>]]></content:encoded></item><item><title>Eleven years…</title><link>https:://chrisphan.com/2012/09/11/eleven-years/index.html</link><description><![CDATA[ It’s been eleven years since that horrible day the world changed, and I don’t know that I have anything substantial to say about it. Maybe]]></description><guid>https:://chrisphan.com/2012/09/11/eleven-years/index.html</guid><pubDate>Wed, 12 Sep 2012 20:20:44 -0500</pubDate><content:encoded><![CDATA[
<p>It’s been eleven years since that horrible day the world changed, and I don’t know that I have anything substantial to say about it. Maybe instead I’ll post a photo of this memorial I found in the Glasgow Botanic Gardens. When I came across this memorial in 2010, it moved me, and made me hopeful that we might make a world with more global understanding.</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/scotland_911.jpg" alt="A small stone memorial reading &quot;In Memory Of Our Fallen Comrades Who Died in America In The Atrocities Of 11th Sept. 2001. Our Heartfelt Condolences Go To Their Families And Loved Ones. From All Fire Brigades Union Members, Scottish Region.&quot; The memorial is surrounded by brown leaves." /></p>]]></content:encoded></item><item><title>train cars</title><link>https:://chrisphan.com/2012/09/10/train-cars/index.html</link><description><![CDATA[ A connected trio of rail cars sits on a track on the far side of a parking lot. One sports the "Canada" wordmark while another]]></description><guid>https:://chrisphan.com/2012/09/10/train-cars/index.html</guid><pubDate>Mon, 10 Sep 2012 20:52:37 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train_cars.jpg" alt="A connected trio of rail cars sits on a track on the far side of a parking lot. One sports the &quot;Canada&quot; wordmark while another is labeled &quot;CP Rail&quot;. Behind the cars are some tall trees." /></p>]]></content:encoded></item><item><title>The demise of LiveJournal</title><link>https:://chrisphan.com/2012/09/08/the-demise-of-livejournal/index.html</link><description><![CDATA[ Aja Romano chronicles the demise of LiveJournal. (It’s still around, but far less busy than during its glory days.) I joined LiveJournal in 2001 and]]></description><guid>https:://chrisphan.com/2012/09/08/the-demise-of-livejournal/index.html</guid><pubDate>Sat, 8 Sep 2012 14:10:35 -0500</pubDate><content:encoded><![CDATA[
<p><a href="http://www.dailydot.com/culture/livejournal-decline-timeline/">Aja Romano chronicles the demise of LiveJournal.</a> (It’s still around, but far less busy than during its glory days.)</p>
<p>I joined LiveJournal in 2001 and used it pretty heavily until the mid- to late-noughties. It makes you wonder if Facebook will still be as popular as today in, say, 2020. (Of course, the Eff Bee has a lot higher market penetration than LJ ever did.)</p>
<p>About a year or so ago, I took my journal down from LJ’s servers. This is where my LiveJournal lives today:</p>
<p><img src="https://blog.chrisphan.com/wp-content/uploads/Screen-Shot-2012-09-08-at-14.17.32-.png" alt="A screen shot of terminal window showing output of ls command. The folder, &quot;LJ backup chris&quot;, is filled with dozens of CSV files with filenames like &quot;clipdude-2001-10.csv&quot;." /></p>
<p>(HT <a href="http://nielsenhayden.com/lighter/archives/2012_09.html#014331">TNH</a>.)</p>]]></content:encoded></item><item><title>barge on the Mississippi</title><link>https:://chrisphan.com/2012/09/05/barge-on-the-mississippi/index.html</link><description><![CDATA[ A barge moves up a river at sunset. The sunset is reflected in the river. On the other side of the channel are a silhouette]]></description><guid>https:://chrisphan.com/2012/09/05/barge-on-the-mississippi/index.html</guid><pubDate>Wed, 5 Sep 2012 21:52:28 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/barge/1.jpg" alt="A barge moves up a river at sunset. The sunset is reflected in the river. On the other side of the channel are a silhouette of trees. On the left of the photo, a silhouette of part of a cantilever bridge is seen." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/barge/2.jpg" alt="A barge moves up a river at sunset. The sunset is reflected in the river. On the other side of the channel are a silhouette of trees. We also see the silhouette of about two-thirds of a cantilever bridge." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/barge/3.jpg" alt="A barge moves up a river at sunset. The sunset is reflected in the river. On the other side of the channel are a silhouette of trees. We also see the silhouette of most of a cantilever bridge, and the walkway on which the photograph was taken. The barge is almost under the bridge." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/barge/4.jpg" alt="A cantilever bridge crosses a river. Behind it is a barge upstream and some hills. The sky is a gradient from yellow to deep orange, some of which is reflected in the river." /></p>]]></content:encoded></item><item><title>“Good general theory does not search for the maximum generality, but for the right generality.”</title><link>https:://chrisphan.com/2012/09/04/good-general-theory-does-not-search-for-the-maximum-generality-but-for-the-right-generality/index.html</link><description><![CDATA[ This comes from Saunders Mac Lane in his textbook Categories for the Working Mathematician (p. 108, emphasis mine), but I contend it applies to more]]></description><guid>https:://chrisphan.com/2012/09/04/good-general-theory-does-not-search-for-the-maximum-generality-but-for-the-right-generality/index.html</guid><pubDate>Wed, 5 Sep 2012 20:08:55 -0500</pubDate><content:encoded><![CDATA[
<p>This comes from Saunders Mac Lane in his textbook <a href="http://en.wikipedia.org/wiki/Categories_for_the_Working_Mathematician"><cite>Categories for the Working Mathematician</cite></a> (p. 108, emphasis mine), but I contend it applies to more than just mathematics:</p>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    displayMath: [['$$','$$'], ['\\[','\\]']],
    processEscapes: true,
    processEnvironments: true,
    skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
    TeX: { equationNumbers: { autoNumber: "AMS" },
         extensions: ["AMSmath.js", "AMSsymbols.js"] }
  }
});
</script>
<blockquote>
<p>One may also speculate as to why the discovery of adjoint functors was so delayed. Ideas about Hilbert space or universal constructions in general topology might have suggested adjoints, but they did not; perhaps the 1939–1945 war interrupted this development. During the next decade 1945–55 there were very few studies of categories, category theory was just a language, and possible workers may have been discouraged by the widespread pragmatic distrust of “general abstract nonsense” (category theory). Bourbaki just missed [. . .] Bourbaki’s idea of universal construction was devised to be so general as to include more–and in partcular, to include the ideas of multilinear algebra which were important to French Mathematical traditions. In retrospect, this added generality seems mistaken; Bourbaki’s construction problem emphasized representable functors, and asked “Find $F,x$ so that $W(x, a) \cong A(F,x, a)$”. This formulation lacks the symmetry of the adjunction problem, “Find $F,x$ so that $X(x, G,a) \cong A(F,x, a)$”—and so missed a basic discovery; this discovery was left to a younger man, perhaps one less beholden to tradition or to fashion. <strong>Put differently, good general theory does not search for the maximum generality, but for the right generality.</strong></p>
</blockquote>]]></content:encoded></item><item><title>NOT BAD</title><link>https:://chrisphan.com/2012/08/29/not-bad/index.html</link><description><![CDATA[ By the way, if you want to know what I think about this whole reddit experience – NOT BAD! I’d like to point out, not]]></description><guid>https:://chrisphan.com/2012/08/29/not-bad/index.html</guid><pubDate>Wed, 29 Aug 2012 21:42:00 -0500</pubDate><content:encoded><![CDATA[
<blockquote>
<p>By the way, if you want to know what I think about this whole reddit experience – NOT BAD!</p>
</blockquote>
<p>I’d like to point out, not only did the president of the United States do <a href="http://www.reddit.com/r/IAmA/comments/z1c9z/i_am_barack_obama_president_of_the_united_states/">an AMA on Reddit today</a>, he threw in an allusion to <a href="http://knowyourmeme.com/memes/obama-rage-face-not-bad">a rage face</a> he inspired.</p>]]></content:encoded></item><item><title>Lake Winona at dusk (#2)</title><link>https:://chrisphan.com/2012/08/27/lake-winona-at-dusk-2/index.html</link><description><![CDATA[ Lake Winona at dusk: an orange sunset sky is reflected in the waters of a lake. The trees around the lake are in silhouette.]]></description><guid>https:://chrisphan.com/2012/08/27/lake-winona-at-dusk-2/index.html</guid><pubDate>Mon, 27 Aug 2012 20:57:01 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/lake_winona_dusk.jpg" alt="Lake Winona at dusk: an orange sunset sky is reflected in the waters of a lake. The trees around the lake are in silhouette." /></p>]]></content:encoded></item><item><title>“The real satisfaction from mathematics is in learning from others and sharing with others.”</title><link>https:://chrisphan.com/2012/08/26/the-real-satisfaction-from-mathematics-is-in-learning-from-others-and-sharing-with-others/index.html</link><description><![CDATA[ [M]athematics only exists in a living community of mathematicians that spreads understanding and breaths life into ideas both old and new. The real satisfaction from]]></description><guid>https:://chrisphan.com/2012/08/26/the-real-satisfaction-from-mathematics-is-in-learning-from-others-and-sharing-with-others/index.html</guid><pubDate>Sun, 26 Aug 2012 11:16:33 -0500</pubDate><content:encoded><![CDATA[
<blockquote>
<p><a href="http://mathoverflow.net/questions/43690/whats-a-mathematician-to-do/44213#44213">[M]athematics only exists in a living community of mathematicians that spreads understanding and breaths life into ideas both old and new.</a> The real satisfaction from mathematics is in learning from others and sharing with others. All of us have clear understanding of a few things and murky concepts of many more. There is no way to run out of ideas in need of clarification. The question of who is the first person to ever set foot on some square meter of land is really secondary. Revolutionary change does matter, but revolutions are few, and they are not self-sustaining — they depend very heavily on the community of mathematicians.</p>
</blockquote>
<p>—Bill Thurston, mathematics professor at Cornell and a Fields medalist, who passed away on Tuesday.</p>
<p>I also recommend Thurston’s 1994 essay <a href="http://arxiv.org/abs/math.HO/9404236">“On proof and progress in mathematics”</a>.</p>]]></content:encoded></item><item><title>Peace, love, and neutrinos</title><link>https:://chrisphan.com/2012/08/14/peace-love-and-neutrinos/index.html</link><description><![CDATA[ Buttons with peace symbol, heart, and Greek letter nu Edited to add : I had meant to add this caption: My wife is a physicist]]></description><guid>https:://chrisphan.com/2012/08/14/peace-love-and-neutrinos/index.html</guid><pubDate>Tue, 14 Aug 2012 17:49:53 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/peace_love_nu.jpg" alt="Buttons with peace symbol, heart, and Greek letter nu" /></p>
<p><strong>Edited to add</strong>: I had meant to add this caption: My wife is a physicist who studies neutrinos. She was given these buttons at a physics event by a physicist who studies how to use neutrinos in counterproliferation.</p>]]></content:encoded></item><item><title>bánh mì sandwich</title><link>https:://chrisphan.com/2012/08/02/banh-mi-sandwich/index.html</link><description><![CDATA[ A bánh mì sandwich served with fries and some yellow sauce on top of thin white waxed paper on a green tray. Yum!]]></description><guid>https:://chrisphan.com/2012/08/02/banh-mi-sandwich/index.html</guid><pubDate>Thu, 2 Aug 2012 14:36:28 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/banh_mi.jpg" alt="A bánh mì sandwich served with fries and some yellow sauce on top of thin white waxed paper on a green tray." /></p>
<p>Yum!</p>]]></content:encoded></item><item><title>blog name change</title><link>https:://chrisphan.com/2012/08/02/blog-name-change/index.html</link><description><![CDATA[ Administrative note: I’ve changed the name of this blog, reusing the name of my (now defunct and largely deleted) LiveJournal. I’m not sure I’m going]]></description><guid>https:://chrisphan.com/2012/08/02/blog-name-change/index.html</guid><pubDate>Thu, 2 Aug 2012 10:46:10 -0500</pubDate><content:encoded><![CDATA[
<p>Administrative note: I’ve changed the name of this blog, reusing the name of my (now defunct and largely deleted) LiveJournal. I’m not sure I’m going to keep this name, either.</p>
<p><strong>Update:</strong> Okay, I changed it again. I might tinker more later. (I’m sure this is the most interesting post <em>ever</em>.)</p>]]></content:encoded></item><item><title>Humans are not to be trusted!</title><link>https:://chrisphan.com/2012/08/01/humans-are-not-to-be-trusted/index.html</link><description><![CDATA[ A sign attached to a pole with a no-slash through a person and the text "Attention! Pay machine. Do not pay any person." Of course,]]></description><guid>https:://chrisphan.com/2012/08/01/humans-are-not-to-be-trusted/index.html</guid><pubDate>Wed, 1 Aug 2012 11:05:47 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/pay_machine.jpg" alt="A sign attached to a pole with a no-slash through a person and the text &quot;Attention! Pay machine. Do not pay any person.&quot;" /></p>
<p>Of course, given the increasing sophistication of ATM skimmers, I’m not sure machines are too trustworthy, either.</p>]]></content:encoded></item><item><title>future Twin Cities light rail (#2)</title><link>https:://chrisphan.com/2012/08/01/future-twin-cities-light-rail-2/index.html</link><description><![CDATA[ An not yet built light rail station in the median of a city street. There are a few traffic cones along the edge of the]]></description><guid>https:://chrisphan.com/2012/08/01/future-twin-cities-light-rail-2/index.html</guid><pubDate>Wed, 1 Aug 2012 11:03:03 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/tc_light_rail.jpg" alt="An not yet built light rail station in the median of a city street. There are a few traffic cones along the edge of the median. In the background is are some large buildings, some trees, and some construction cranes." /></p>]]></content:encoded></item><item><title>Fact checking Mitt Romney</title><link>https:://chrisphan.com/2012/07/27/fact-checking-mitt-romney/index.html</link><description><![CDATA[ Let’s wade into some poly-ticks. The British media is having a field day making fun of Mitt Romney’s recent stumbles in London, where he insulted]]></description><guid>https:://chrisphan.com/2012/07/27/fact-checking-mitt-romney/index.html</guid><pubDate>Fri, 27 Jul 2012 18:27:53 -0500</pubDate><content:encoded><![CDATA[
<p>Let’s wade into some poly-ticks.</p>
<p>The British media is having a field day making fun of Mitt Romney’s recent stumbles in London, where he insulted his hosts by criticizing their preparation for the 2012 Summer Olympics. (The <cite>Guardian</cite>‘s headline yesterday: <a href="http://www.guardian.co.uk/world/2012/jul/26/mitt-romney-olympics-blunder">“Mitt Romney’s Olympics blunder stuns No 10 and hands gift to Obama”</a>.) This has lead some bloggers and journalists to reprint <a href="http://books.google.com/books?id=PDpBpo5CVB4C&amp;lpg=PA39&amp;ots=wGt5NQax2a&amp;dq=mitt%20romney%20england%20is%20a%20small%20island&amp;pg=PA39#v=onepage&amp;q&amp;f=false">this passage</a> from Romney’s book, <cite>No Apology: The Case for American Greatness</cite>:</p>
<blockquote>
<p>England is just a small island. Its roads and houses are small. With few exceptions, it doesn’t make things that people in the rest of the world want to buy. And if it hadn’t been separated from the continent by water, it almost certainly would have been lost to Hitler’s ambitions.</p>
</blockquote>
<p>That’s pretty insulting, but is it true? Let’s take these assertions one by one:</p>
<ul>
<li>
<p><strong>#8220;England is just a small island.”</strong> Of course, on the face of it, this is false. England isn’t <em>any</em> kind of island. We’ll assume the governor meant Great Britain (which is an island), or the United Kingdom (which is a nation-state situated on a number of islands, the largest of which is Great Britain). Now, Wikipedia has a <a href="http://en.wikipedia.org/wiki/List_of_islands_by_area">list of the world’s largest islands</a> (by area), and Great Britain is the 9th largest in the world, so I wouldn’t personally consider it a small island. Sure, the U.K. is small (in area) compared to the United States—the U.K.’s area is about 243,610 km<sup>2</sup>, compared to 255,026 km<sup>2</sup> for my native state of Oregon—but the U.K. has some 63 million people, and a GDP of US$2.29 trillion, giving it the 9th largest economy in the world. It’s not an insignificant place.</p>
</li>
<li>
<p><strong>“Its roads and houses are small.”</strong> <a href="http://www.slate.com/blogs/moneybox/2012/07/26/mitt_romney_is_right_the_uk_has_really_small_houses.html">Matthew Ygelsais at <cite>Slate</cite> points out that it is true that the U.K. has smaller houses.</a> Of course, given the large increase in house sizes America has seen in the past few decades, I’m not sure this is a bad thing. (Remember, the U.K. didn’t have a subprime mortgage crisis, either—although some of their banks did need to be bailed out, because they got involved in <em>American</em> subprime mortgages.) As far as the roads go, it’s true that you will find narrow streets in the older parts of European cities, because such streets predate the invention of the automobile. Nevertheless, you will also find highways in the U.K. that look just like the ones in America:</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/m8.jpg" alt="A view of a British motorway (what I would call a freeway in American English) from a pedestrian bridge. It's a divided highway with two lanes on the left of traffic moving away from us and three lanes on the right with traffic moving toward us. There are on-ramps merging in both directions. In the center is a median lined with tall streetlights. In the distance are several tall buildings." /></p>
<p>Well, okay: modulo the side of the road the cars drive on.</p>
</li>
<li>
<p><strong>“With few exceptions, it doesn’t make things that people in the rest of the world want to buy.”</strong> To fact-check this claim, I made a small table:</p>
<table>
<thead>
<tr>
<th align="right"></th>
<th align="left">United States</th>
<th align="left">United Kingdom</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">Exports (2011)</td>
<td align="left">US$1.511 trillion</td>
<td align="left">US$495.4 billion</td>
</tr>
<tr>
<td align="right">Population (2011)</td>
<td align="left">313,847,465</td>
<td align="left">63,047,162</td>
</tr>
<tr>
<td align="right">Exports per capita</td>
<td align="left">US$4814</td>
<td align="left">US$7858</td>
</tr>
</tbody>
</table>
<p>For whatever it’s worth, the U.K. is the world’s 11th largest exporter.</p>
</li>
<li>
<p><strong>“And if it hadn’t been separated from the continent by water, it almost certainly would have been lost to Hitler’s ambitions.”</strong> I don’t know enough about World War II to evaluate the merit of this claim, but it does come across as a jerky thing to say. Look, the U.K. was fighting Nazi Germany as early as September 1939; the U.S. didn’t get involved in direct fighting until December 1941. By the way, the Battle for Britain, in which the British successfully resisted German invasion, occurred in 1940—while we were sitting on the sidelines.</p>
</li>
</ul>
<p>America is a great country. We shouldn’t have to say incorrect and jerky things about other countries to feel good about ourselves.</p>
<p>(Information about GDPs, country size, population, and exports were taken from the <a href="https://www.cia.gov/library/publications/the-world-factbook/"><cite>CIA World Factbook</cite></a>.)</p>]]></content:encoded></item><item><title>System Administrator Appreciation Day</title><link>https:://chrisphan.com/2012/07/27/system-administrator-appreciation-day/index.html</link><description><![CDATA[ I have learned (from BoingBoing , TeXblog , and a few other places) that today is System Administrator Appreciation Day . I don’t know who]]></description><guid>https:://chrisphan.com/2012/07/27/system-administrator-appreciation-day/index.html</guid><pubDate>Fri, 27 Jul 2012 16:45:54 -0500</pubDate><content:encoded><![CDATA[
<p>I have learned (from <a href="http://boingboing.net/2012/07/27/happy-sysadmin-day-2.html">BoingBoing</a>, <a href="http://texblog.net/latex-archive/events/sysadmin-day/">TeXblog</a>, and a few other places) that today is <a href="http://sysadminday.com/">System Administrator Appreciation Day</a>.</p>
<p>I don’t know who the system administrators are for this site. I pay a company, <a href="https://www.nearlyfreespeech.net/">NearlyFreeSpeech</a>, to host this site, <a href="http://chrisphan.com">ChrisPhan.com</a>, and <a href="http://phanbudd.com">PhanBudd.com</a>. I have not had any communication with NearlyFreeSpeech, save a few automated emails reminding me to renew domains, et cetra, so I haven’t had an opportunity to get to know my sysadmins. But I will say this: in the four or so years since I started using NearlyFreeSpeech to host my stuff, I have not, to my knowledge, experienced a second of downtime. So, NearlyFreeSpeech sysadmins, even though I don’t know who you are, you all rock, and you are very much appreciated!</p>]]></content:encoded></item><item><title>Michigan and Ontario photos</title><link>https:://chrisphan.com/2012/07/10/michigan-and-ontario-photos/index.html</link><description><![CDATA[ The Mackinac Bridge, connecting Michigan’s Upper Peninsula with the Mitten, is the third-longest suspension bridge in the world. A view of a large suspension bridge,]]></description><guid>https:://chrisphan.com/2012/07/10/michigan-and-ontario-photos/index.html</guid><pubDate>Tue, 10 Jul 2012 13:25:24 -0500</pubDate><content:encoded><![CDATA[
<p>The Mackinac Bridge, connecting Michigan’s Upper Peninsula with the Mitten, is the <a href="http://www.mackinacbridge.org/about-the-bridge-8/">third-longest suspension bridge in the world.</a></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/mich_ont_2012-07/1.jpg" alt="A view of a large suspension bridge, from almost underneath." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/mich_ont_2012-07/2.jpg" alt="Another view of the same large suspension bridge, from the side. We see the approach at the end of the bridge." /></p>
<p>Bikes parked on <a href="http://www.mackinac.com/">Mackinac Island</a>, where cars are banned:</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/mich_ont_2012-07/3.jpg" alt="A large collection of bikes, probably hundreds, parked in front of a square one-story building with a triangle-peaked roof. In the background are some tallish trees." /></p>
<p>The International Bridge, connecting Michigan and Ontario (from the Ontario side):</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/mich_ont_2012-07/4.jpg" alt="A view of a large body of water from its shore. We see a small amount of land in front of us, with a pile of rocks. In the distance is a long bridge, with a truss portion on both ends." /></p>
<p>In Sault Ste. Marie, you can see two sets of fireworks in early July, for Canada Day and Independence Day:</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/mich_ont_2012-07/5.jpg" alt="A oval sign that says &quot;Docks Riverfront Grill&quot;. Below is a letter board reading &quot;Join us for fireworks July 1 &amp; 4. Best view in the Soo.&quot;" /></p>
<p>The Soo Locks (allowing ship traffic between Lake Superior and Lake Huron):</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/mich_ont_2012-07/6.jpg" alt="A parallel group of locks, seen from the side. In the background is a long bridge." /></p>
<p>I got this awesome souvenir from Michigan:</p>
<p><img src="https://blog.chrisphan.com/flickr_photos//mich_ont_2012-07/7.jpg" alt="An oven mitt with a map of the &quot;mitten&quot; part of Michigan, showing the location of a few dozen Michigan locales." /></p>]]></content:encoded></item><item><title>Downers Grove Fire Station 5</title><link>https:://chrisphan.com/2012/06/30/downers-grove-fire-station-5/index.html</link><description><![CDATA[ Downers Grove Fire Station 5: A two-story fire station with three garage doors and a glass window with door in its front. The name of]]></description><guid>https:://chrisphan.com/2012/06/30/downers-grove-fire-station-5/index.html</guid><pubDate>Sat, 30 Jun 2012 17:29:22 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/dg_fire_station.jpg" alt="Downers Grove Fire Station 5: A two-story fire station with three garage doors and a glass window with door in its front. The name of the station is printed on the glass. There is a flagpole with a U.S. flag in front as well." /></p>]]></content:encoded></item><item><title>Is there a Ducks fan working for the Village of Downers Grove?</title><link>https:://chrisphan.com/2012/06/30/is-there-a-ducks-fan-working-for-the-village-of-downers-grove/index.html</link><description><![CDATA[ A lamp-post with a vertical banner reading "Shop, Eat, Play, Live". The words are alternating yellow and white, and the background is green. If so,]]></description><guid>https:://chrisphan.com/2012/06/30/is-there-a-ducks-fan-working-for-the-village-of-downers-grove/index.html</guid><pubDate>Sat, 30 Jun 2012 15:31:10 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/ducks_fan.jpg" alt="A lamp-post with a vertical banner reading &quot;Shop, Eat, Play, Live&quot;. The words are alternating yellow and white, and the background is green." /></p>
<p>If so, then awesome! Go Ducks!</p>]]></content:encoded></item><item><title>Facebook is not a good forum for political arguments</title><link>https:://chrisphan.com/2012/06/28/facebook-is-not-a-good-forum-for-political-arguments/index.html</link><description><![CDATA[ Every once so often, I get sucked into a political argument on Facebook. Sometimes someone will post one of those “share this if you agree”]]></description><guid>https:://chrisphan.com/2012/06/28/facebook-is-not-a-good-forum-for-political-arguments/index.html</guid><pubDate>Thu, 28 Jun 2012 16:12:32 -0500</pubDate><content:encoded><![CDATA[
<p>Every once so often, I get sucked into a political argument on Facebook. Sometimes someone will post one of those “share this if you agree” pictures, and I don’t agree with it. Sometimes one of my liberal friends’ conservative friends will make a comment, and because (I’m not proud to admit) I sometimes suffer from the tendency illustrated by <a href="http://xkcd.com/386/">xkcd #386</a>, I will feel moved to respond. Every one of these encounters has left me increasingly convinced that <strong>Facebook is not a good forum for political arguments</strong>. I’ve identified two reasons:</p>
<ol>
<li>The way Facebook displays comments is poorly suited for discussion.</li>
<li>People who post political content don’t necessarily want to spark a discussion, and it’s hard to tell.</li>
</ol>
<h1>The problems with Facebook’s commenting system</h1>
<p>A productive, respectful, and thoughtful exchange of ideas is most likely if every participant has carefully read and considered the previous contributions to the discussion. The design of Facebook’s commenting system discourages people from doing this.</p>
<p><img src="https://blog.chrisphan.com/wp-content/uploads/Screen-Shot-2012-06-28-at-14.51.21-.png" alt="A fake Facebook post (filled &quot;lorem ipsum&quot; plaaceholder text) followed by 12 comments, 10 of which have been collapsed. (The remaining two shown are also &quot;lorem ipsum&quot; placeholder text.)" /></p>
<p>That’s because:</p>
<ul>
<li>Facebook hides all but the two most recent comments.</li>
<li>After comments reach a certain length, Facebook hides the remainder of the comment behind a “See More” link.</li>
<li>Facebook will even truncate the original post, if it’s beyond a certain length, by hiding most of the post behind a “See More” link.</li>
</ul>
<p>The overall effect is to require additional effort for people to read everything that’s been said before. As a result, it’s easy for people to repeat points that have already been made, or to criticize others’ views without actually having read them in full, or without understanding the reasoning. People end up talking past each other.</p>
<p>Furthermore, Facebook encourages shorter comments, by having the [Enter] key post the comment, and requiring [Shift]-[Enter] to make a line break. This further discourages substantive discussion.</p>
<p>Don’t get me wrong: I don’t think these are poor design decisions on the part of Facebook’s engineers. Indeed, these design decisions are perfectly fine for comments congratulating people on a new job, wishing someone a happy birthday, or commiserating with someone who has had a poor day at work. <strong>They are just poorly suited to political arguments.</strong> I imagine this is because Mark Zuckerberg and his friends did not have political discussions in mind when they designed Facebook.</p>
<h1>It’s hard to tell when people actually want to have a discussion</h1>
<p>People don’t just use social networking sites to stay in touch with friends and family, but also as a way to express their identity. Political posts are no exception to that: for many of us, our political ideology and beliefs are an important part of our identity. And not everyone who posts political views is interested in having those view challenged. Sometimes they are looking for affirmations from like-minded friends. Sometimes they just want to share information or lines of argumentation with like-minded friends.</p>
<p><img src="https://blog.chrisphan.com/wp-content/uploads/Screen-Shot-2012-06-28-at-16.04.20-.png" alt="Posted on FB: &quot;I'm not actually interested in having a discussion about this; I'm just posting his Paul Krugman article as a way to perform my identity as a liberal NYT reader.&quot; Attached is a link to a Paul Krugman New York Times op-ed article titled &quot;The Great Abdication&quot;" /></p>
<p>By the way, there’s not necessarily anything wrong with this. I do believe that honest, frank debate of political issues makes for a better society, but such discussion can be draining. It’s reasonable for people to not want to engage in such discussion at all times. A good analogy would be someone who has an Obama ’12 bumper sticker on their car. Such a person doesn’t necessarily want to discuss the president’s policies with every driver they meet on the highway.</p>
<p>The problem is that’s it can be difficult to tell whether a poster is open to having their views challenged or not. So, when you respond to such posts, you run the risk of bothering someone.</p>]]></content:encoded></item><item><title>Happy 100th Birthday, Alan Turing!</title><link>https:://chrisphan.com/2012/06/23/happy-100th-birthday-alan-turing/index.html</link><description><![CDATA[ An Enigma machine: It's a black box, roughly the size of a suitcase. On the top of the machine is a typewriter-style keyboard in QWERTZ]]></description><guid>https:://chrisphan.com/2012/06/23/happy-100th-birthday-alan-turing/index.html</guid><pubDate>Sat, 23 Jun 2012 09:43:45 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/enigma.jpg" alt="An Enigma machine: It's a black box, roughly the size of a suitcase. On the top of the machine is a typewriter-style keyboard in QWERTZ layout. Behind the keyboard and another set of lights labelled with letters in a QWERTZ layout, and behind that are a set of three rotors. On the front are a bunch of wires and plugs." /></p>
<p>Today is the 100th birthday of one of the 20th century’s most under-appreciated people, British mathematician, computer scientist, and cryptoanalyst Alan Turing.</p>
<p>It’s impossible to live in modern society without coming into the consequences of Turing’s work. Alan Turing was a pioneer computer scientist, laying the theoretical framework for the information age. He also made key contributions to the Allies’ code-breaking efforts during World War II. It’s been estimated that his contributions sped up the defeat of Hitler by as much as two years.</p>
<p>Unfortunately, Alan Turing was a gay man in an age when it was illegal for men to have sex with other men.<a href="#notelawrence">*</a> Despite his contributions to winning the war, Turing was chemically castrated by the British goverment in the 1950s, and committed suicide as a result.</p>
<ul>
<li>For a general nontechnical introduction to this great man, you might want to check out <a href="http://www.radiolab.org/blogs/radiolab-blog/2012/mar/19/turing-problem/">this episode of the public radio program <em>Radiolab.</em></a></li>
<li><a href="http://www.telegraph.co.uk/news/politics/gordon-brown/6170112/Gordon-Brown-Im-proud-to-say-sorry-to-a-real-war-hero.html">Gordon Brown’s 2009 apology</a>, on behalf of the British government, for the government’s poor treatment of Alan Turing.</li>
<li><a href="http://blogs.scientificamerican.com/guest-blog/2012/04/26/how-alan-turing-invented-the-computer-age/">How Alan Turing Invented the Computer Age</a>, by computer scientist Ian Watson.</li>
</ul>
<p>(Pictured is the <a href="http://en.wikipedia.org/wiki/Enigma_machine">Enigma machine</a>, used by the German military to encrypt messages during the Second World War.)</p>
<p><strong>Edited to add (21:18 CDT):</strong></p>
<p>Here’s a neat video summarizing Turing’s work.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/gtRLmL70TH0?si=9tR9otKd-Pj9Hqy8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<p><a name="notelawrence"> </a></p>
<p>*<small>It’s worth noting that <a href="http://en.wikipedia.org/wiki/Lawrence_v._Texas"><em>as late as 2003</em></a>, it was illegal in some states in the U.S. for a man to have sex with another man.</small></p>]]></content:encoded></item><item><title>Mixed-case street sign</title><link>https:://chrisphan.com/2012/06/21/mixed-case-street-sign/index.html</link><description><![CDATA[ A perpendicular pair of street signs, one reading Blackburn Av, and the other reading 72nd St. The signs are mixed-case, rather than all caps. A]]></description><guid>https:://chrisphan.com/2012/06/21/mixed-case-street-sign/index.html</guid><pubDate>Thu, 21 Jun 2012 16:57:43 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/mixed_case_sign.jpg" alt="A perpendicular pair of street signs, one reading Blackburn Av, and the other reading 72nd St. The signs are mixed-case, rather than all caps." /></p>
<p><a href="http://mutcd.fhwa.dot.gov/htm/2009/part2/part2d.htm#section2D05_para02">A recent change to the MUTCD</a> (Manual on Uniform Traffic Control Devices) requires all new street-name signs to be in mixed case, as opposed to the more traditional all-uppercase format. This is probably why we’ve seen some mixed-case street-name signs (like this one) pop up in Downers Grove.</p>]]></content:encoded></item><item><title>View of downtown Naperville from the Millennium Carillon</title><link>https:://chrisphan.com/2012/06/19/view-of-downtown-naperville-from-the-millennium-carillon/index.html</link><description><![CDATA[ An aerial shot of downtown Naperville, Illinois from the top of the Millennium Carillon. There is a lake surrounded by short buildings, poking through a]]></description><guid>https:://chrisphan.com/2012/06/19/view-of-downtown-naperville-from-the-millennium-carillon/index.html</guid><pubDate>Tue, 19 Jun 2012 17:15:34 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/naperville.jpg" alt="An aerial shot of downtown Naperville, Illinois from the top of the Millennium Carillon. There is a lake surrounded by short buildings, poking through a blanked to green trees. The horizon is flat, but if you look very closely, there are bits of very distant Chicago skyscrapers visible." /></p>
<p>You can actually see some Chicago skyline if you <a href="https://blog.chrisphan.com/flickr_photos/naperville_big.jpg">zoom in</a>. (The Loop is about 45 km from the location of this photo.)</p>]]></content:encoded></item><item><title>I’m not sure what this means</title><link>https:://chrisphan.com/2012/06/19/im-not-sure-what-this-means/index.html</link><description><![CDATA[ A hand painted regulatory traffic sign, in which a pedestrian figure is behind a red no-slash, but has broken part of the slash with their]]></description><guid>https:://chrisphan.com/2012/06/19/im-not-sure-what-this-means/index.html</guid><pubDate>Tue, 19 Jun 2012 15:18:32 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/not_sure.jpg" alt="A hand painted regulatory traffic sign, in which a pedestrian figure is behind a red no-slash, but has broken part of the slash with their arm. There are red triangles emanating from where the figure's arm has broken the slash, representing shattered shards of the slash." /></p>
<p>This clearly-unofficial hand-painted sign was affixed to a signpost in Downtown Downers Grove.</p>]]></content:encoded></item><item><title>ACHIEVEMENT UNLOCKED: round-trip Empire Builder, Chicago to Portland</title><link>https:://chrisphan.com/2012/06/15/achievement-unlocked-round-trip-empire-builder-chicago-to-portland/index.html</link><description><![CDATA[ A friend asked me (via the Eff Bee) about my recent trip from Chicago to Portland, and back, on Amtrak’s Empire Builder . (I just]]></description><guid>https:://chrisphan.com/2012/06/15/achievement-unlocked-round-trip-empire-builder-chicago-to-portland/index.html</guid><pubDate>Fri, 15 Jun 2012 14:37:50 -0700</pubDate><content:encoded><![CDATA[
<p>A friend asked me (via the Eff Bee) about my recent trip from Chicago to Portland, and back, on Amtrak’s <a href="http://www.amtrak.com/servlet/ContentServer?c=AM_Route_C&amp;pagename=am%2FLayout&amp;cid=1241245653623">Empire Builder</a>. (I just got back yesterday.) I wrote a fairly long comment on Facebook, and I thought it would be good to reproduce it here (lightly edited):</p>
<p>It cost me $376.20 for a round-trip ticket from Portland to Chicago. I got a reserved coach seat instead of a sleeper car compartment. A sleeper car compartment is substantially more expensive.</p>
<p>The seat you get is sort of similar to an airplane seat except with considerably more legroom. You can recline the seat without even slightly inconveniencing the person behind you, and there is a leg rest you can pull out to help be more comfy. That said, it’s not as comfy as an actual bed.</p>
<p>There was electrical outlets on my train but no WiFi. I got 3G pretty consistently in Illinois, Wisconsin, Minnesota, and North Dakota. In Montana, you don’t get 3G except when you are close to towns. The rest of the time was hit-or-miss. (My carrier is Verizon.)</p>
<p>The trip takes about two days. On my return trip, I left Portland at 4:45 p.m. Tuesday and got into Chicago at about 7:00 p.m. Thursday. My train was 3 hours late—which is common—and was scheduled to arrive at 3:55 p.m. Thursday. (On the other hand, on the trip out to Portland, my train arrived slightly early.)</p>
<p>On the train, there is a observation car with tables, seats, and large windows. You can hang out there when you are tired of sitting in your coach seat.</p>
<p>I would recommend bringing some of your own food. (I brought crackers, bagels, a jar of peanut butter, dried fruit, tuna in packets, etc.) You can buy food from the cafe in the observation car, but it’s a bit overpriced. (A 12-ounce cup of coffee or a 12-ounce can of soda costs $2.) There is also a dining car which is basically a medium-priced sit-down restaurant. (The entrees are between $15 to $25.) If you get the sleeper car compartment, the dining car meals are included.</p>
<p>One very nice thing about the train is you see the landscape you can’t really see while flying or driving. <a href="https://web.archive.org/web/20190320222531/https://plus.google.com/101419088189446783565">My father-in-law</a> pointed out to me that the sleeping car accommodation, while expensive compared to a plane ticket, is not a bad deal compared to driving, staying in a hotel every night, and buying restaurant food for every meal.</p>
<p>Another thing I should mention is that half the train goes to (or comes from) Portland, and half of it goes to (or comes Seattle); they split apart (or join together) in Spokane. The practical significance of this is that the dining car goes to (or comes from) Seattle and the observation car goes to (or comes from) Portland. So, if you are coming from or to Portland, you won’t have the dining car west of Spokane (i.e. the first night on a eastbound trip, or the last morning on a westbound trip).</p>
<p>Overall, I think it’s worth taking the train if you aren’t in a hurry, want to see some beautiful landscape along the way, and don’t mind sleeping in a seat for two nights. I enjoyed my trip.</p>
<p> </p>]]></content:encoded></item><item><title>from the train #16 (Portland)</title><link>https:://chrisphan.com/2012/06/02/from-the-train-16-portland/index.html</link><description><![CDATA[ Several modern-looking apartment or condo buildings, with a taller one visible in the background. In front of the buildings are some trees, and bare area.]]></description><guid>https:://chrisphan.com/2012/06/02/from-the-train-16-portland/index.html</guid><pubDate>Sat, 2 Jun 2012 10:01:05 -0700</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/16.jpg" alt="Several modern-looking apartment or condo buildings, with a taller one visible in the background. In front of the buildings are some trees, and bare area. The sky is full of clouds, although some blue is visible." /></p>]]></content:encoded></item><item><title>from the train #15 (Vancouver, Washington)</title><link>https:://chrisphan.com/2012/06/02/from-the-train-15-vancouver-washington/index.html</link><description><![CDATA[ In the foreground is three lanes of a highway. Behind that is a grassy field, with a wooden fence in the distance, with wood buildings]]></description><guid>https:://chrisphan.com/2012/06/02/from-the-train-15-vancouver-washington/index.html</guid><pubDate>Sat, 2 Jun 2012 09:19:36 -0700</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/15.jpg" alt="In the foreground is three lanes of a highway. Behind that is a grassy field, with a wooden fence in the distance, with wood buildings inside. Also visible is a forested hill, sporting a radio tower. Sky is filled with dark clouds." /></p>]]></content:encoded></item><item><title>from the train #14 (east of The Dalles)</title><link>https:://chrisphan.com/2012/06/02/from-the-train-14-east-of-the-dalles/index.html</link><description><![CDATA[ Three bridges intersect in the Columbia River in a Y shape. The far leg of the Y has a truss design. On the other side]]></description><guid>https:://chrisphan.com/2012/06/02/from-the-train-14-east-of-the-dalles/index.html</guid><pubDate>Sat, 2 Jun 2012 07:54:24 -0700</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/14.jpg" alt="Three bridges intersect in the Columbia River in a Y shape. The far leg of the Y has a truss design. On the other side of the river are tall hills, with bands of exposed rock. A highway can be seen along the other side of the river. The sky is bright blue and there is some lens flare." /></p>]]></content:encoded></item><item><title>from the train #13 (east of Umatilla)</title><link>https:://chrisphan.com/2012/06/02/from-the-train-13-east-of-umatilla/index.html</link><description><![CDATA[ A view across the Columbia River. The river is filled with slight ripples. We see the land on the other side of the river but]]></description><guid>https:://chrisphan.com/2012/06/02/from-the-train-13-east-of-umatilla/index.html</guid><pubDate>Sat, 2 Jun 2012 06:13:52 -0700</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/13.jpg" alt="A view across the Columbia River. The river is filled with slight ripples. We see the land on the other side of the river but not much more. The sky is empty." /></p>]]></content:encoded></item><item><title>from the train #12 (east of Glacier NP)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-12-east-of-glacier-np/index.html</link><description><![CDATA[ In the foreground are lush dark green forests. In the background are a line of snowy mountains. The sky is filled with dark clouds. The]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-12-east-of-glacier-np/index.html</guid><pubDate>Fri, 1 Jun 2012 21:05:15 -0600</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/12.jpg" alt="In the foreground are lush dark green forests. In the background are a line of snowy mountains. The sky is filled with dark clouds. The reflection of the other side of the observation car is seen in the window through which this photo was taken." /></p>]]></content:encoded></item><item><title>from the train #11 (Cut Bank)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-11-cut-bank/index.html</link><description><![CDATA[ Below, we see a river flowing in an L-shape from the left side of the frame to the bottom. On our side of the river,]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-11-cut-bank/index.html</guid><pubDate>Fri, 1 Jun 2012 19:05:21 -0600</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/11.jpg" alt="Below, we see a river flowing in an L-shape from the left side of the frame to the bottom. On our side of the river, there are two ponds and a tree. Behind the river, the there is steep hill with bare exposed rock, with some trees and small buildings on top. There is also a structure next to the river at the bottom of the steep cliff. In the distance, there are pastures until the horizon." /></p>]]></content:encoded></item><item><title>from the train #10 (east of Malta)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-10-east-of-malta/index.html</link><description><![CDATA[ A rural outside view. There is an empty two-lane road, surrounded by grass. On the other side of the road is some trees, and if]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-10-east-of-malta/index.html</guid><pubDate>Fri, 1 Jun 2012 13:42:05 -0600</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/10.jpg" alt="A rural outside view. There is an empty two-lane road, surrounded by grass. On the other side of the road is some trees, and if you look closely, two horses. Behind the trees, the field extends to the horizon. The sky is partly cloudy." /></p>]]></content:encoded></item><item><title>from the train #9 (east of Williston)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-9-east-of-williston/index.html</link><description><![CDATA[ A view across a grassy field. The horizon is mostly flat, with some very gently rolling hills. The sky mostly clear with some white clouds.]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-9-east-of-williston/index.html</guid><pubDate>Fri, 1 Jun 2012 11:02:21 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/9.jpg" alt="A view across a grassy field. The horizon is mostly flat, with some very gently rolling hills. The sky mostly clear with some white clouds. This photo was taken through a window and there is a slight, subtle reflection visible." /></p>]]></content:encoded></item><item><title>from the train #8 (west of Des Lacs)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-8-west-of-des-lacs/index.html</link><description><![CDATA[ In front is a pond, lined with reeds. Behind the pond is a grassy field. Some farm buildings and trees can be seen on the]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-8-west-of-des-lacs/index.html</guid><pubDate>Fri, 1 Jun 2012 09:47:46 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/8.jpg" alt="In front is a pond, lined with reeds. Behind the pond is a grassy field. Some farm buildings and trees can be seen on the horizon." /></p>]]></content:encoded></item><item><title>from the train #7 (Lake Irvine)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-7-lake-irvine/index.html</link><description><![CDATA[ A view across a marshy lake, which stretches into the horizon. Above the horizon is a band of orangish-yellow sky. The rest of the sky]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-7-lake-irvine/index.html</guid><pubDate>Fri, 1 Jun 2012 07:26:29 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/7.jpg" alt="A view across a marshy lake, which stretches into the horizon. Above the horizon is a band of orangish-yellow sky. The rest of the sky is gray clouds." /></p>]]></content:encoded></item><item><title>from the train #6 (good morning North Dakota)</title><link>https:://chrisphan.com/2012/06/01/from-the-train-6-good-moring-north-dakota/index.html</link><description><![CDATA[ A shot of the horizon before dawn. Just above the horizon is a reddish orange band. The rest of the sky are alternating streaks of]]></description><guid>https:://chrisphan.com/2012/06/01/from-the-train-6-good-moring-north-dakota/index.html</guid><pubDate>Fri, 1 Jun 2012 05:06:53 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/6.jpg" alt="A shot of the horizon before dawn. Just above the horizon is a reddish orange band. The rest of the sky are alternating streaks of light blue and navy blue. The ground is still black." /></p>]]></content:encoded></item><item><title>from the train #5 (north of Winona)</title><link>https:://chrisphan.com/2012/05/31/from-the-train-5-north-of-winona/index.html</link><description><![CDATA[ A view looking north along the Mississippi right after sunset. There is a orange twinge to the sky which is reflected in the water. Part]]></description><guid>https:://chrisphan.com/2012/05/31/from-the-train-5-north-of-winona/index.html</guid><pubDate>Thu, 31 May 2012 20:43:07 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/5.jpg" alt="A view looking north along the Mississippi right after sunset. There is a orange twinge to the sky which is reflected in the water. Part of the train window frame is visible in this shot." /></p>]]></content:encoded></item><item><title>from the train #4 (La Crosse)</title><link>https:://chrisphan.com/2012/05/31/from-the-train-4-la-crosse/index.html</link><description><![CDATA[ The east channel of the Mississippi River, west of La Crosse, right before dusk. The cloudy sky is reflected in the river's waters. Both sides]]></description><guid>https:://chrisphan.com/2012/05/31/from-the-train-4-la-crosse/index.html</guid><pubDate>Thu, 31 May 2012 19:48:28 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/4.jpg" alt="The east channel of the Mississippi River, west of La Crosse, right before dusk. The cloudy sky is reflected in the river's waters. Both sides of the channel are lined by trees." /></p>
<p>And now I am in Minnesota, not far from where we will be moving later this summer.</p>]]></content:encoded></item><item><title>from the train #3 (Wisconsin)</title><link>https:://chrisphan.com/2012/05/31/from-the-train-3-wisconsin/index.html</link><description><![CDATA[ A flat rural area, with a patch of dirt in the foreground and green field behind it. In the distance, there are trees on the]]></description><guid>https:://chrisphan.com/2012/05/31/from-the-train-3-wisconsin/index.html</guid><pubDate>Thu, 31 May 2012 18:29:11 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/3.jpg" alt="A flat rural area, with a patch of dirt in the foreground and green field behind it. In the distance, there are trees on the other side of the field. A tree is in the foreground, too, in front of the dirt patch." /></p>]]></content:encoded></item><item><title>from the train #2 (Milwaukee)</title><link>https:://chrisphan.com/2012/05/31/from-the-train-2-milwaukee/index.html</link><description><![CDATA[ Two cars travel down a two-lane road, crossing a bridge over a river. In the background are a set of silos (probably grain silos) and]]></description><guid>https:://chrisphan.com/2012/05/31/from-the-train-2-milwaukee/index.html</guid><pubDate>Thu, 31 May 2012 15:45:05 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/2.jpg" alt="Two cars travel down a two-lane road, crossing a bridge over a river. In the background are a set of silos (probably grain silos) and a green space along a riverfront." /></p>]]></content:encoded></item><item><title>from the train #1 (Chicago)</title><link>https:://chrisphan.com/2012/05/31/from-the-train-1-chicago/index.html</link><description><![CDATA[ Through a window dotted with raindrops, we see a wet city street below, lined with three- to four-story brown buildings and street lights. A traffic]]></description><guid>https:://chrisphan.com/2012/05/31/from-the-train-1-chicago/index.html</guid><pubDate>Thu, 31 May 2012 15:05:20 -0500</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/train/1.jpg" alt="Through a window dotted with raindrops, we see a wet city street below, lined with three- to four-story brown buildings and street lights. A traffic signal is seen down the block. Cars are parked on the side of the street, and there are a few cars on the road." /></p>]]></content:encoded></item><item><title>to whom I paid tolls</title><link>https:://chrisphan.com/2012/05/29/to-whom-i-paid-tolls/index.html</link><description><![CDATA[ Mounted to the windshield of my car is an I-Pass toll transponder, which is Illinois’s version of the E-ZPass toll transponder used to collect tolls]]></description><guid>https:://chrisphan.com/2012/05/29/to-whom-i-paid-tolls/index.html</guid><pubDate>Tue, 29 May 2012 20:49:27 -0500</pubDate><content:encoded><![CDATA[
<p>Mounted to the windshield of my car is an <a href="http://www.illinoistollway.com/tolls-and-i-pass">I-Pass</a> toll transponder, which is Illinois’s version of the <a href="https://en.wikipedia.org/wiki/E-ZPass">E-ZPass</a> toll transponder used to collect tolls throughout much of the eastern half of the country. I find it both fascinating and creepy that using a toll transponder creates an electronic record of your whereabouts:</p>
<p><img src="https://blog.chrisphan.com/wp-content/uploads/tolls_may_2012.png" alt="A screen shot of a toll transponder report, showing the time and location the transponder was used, as well as the cost charged to the account. The record shows 11 transactions between May 4 and May 21, 2012, with transactions taking place in Ohio, New Jersey, New York, Pennsylvania, Indiana, and Illinois. The account was charged a total of $47.09." /></p>
<p>Some observations:</p>
<ul>
<li>Both the transponder in my car and the transponder in my wife’s car are in her name. (This report shows only tolls incurred by the transponder in my car.)</li>
<li>It costs more to cross the <a href="http://www.panynj.gov/bridges-tunnels/george-washington-bridge.html">George Washington Bridge</a> ($7.50) than it does to drive the entire 156-mile length of the <a href="https://www.getizoom.com/index.jsp">Indiana Toll Road</a> ($4.18). (Although, to be fair, the trip across the George Washington Bridge is much nicer than the trip across northern Indiana.)</li>
<li>In contrast to the George Washington Bridge, the <a href="http://www.drjtbc.org/default.aspx?pageid=87">Delaware Water Gap Toll Bridge</a> is a bargain at $1.</li>
<li>Both the Indiana Toll Road and <a href="http://www.ohioturnpike.org/">Ohio Turnpike</a> use a ticket system, where you take a ticket when you enter the toll road, and then pay tolls when you leave the toll road, based on how far you’ve travelled. (Since I have the I-Pass, I don’t need to take a ticket—it’s handled electronically.) That’s why you see only one tool recorded for each trip.</li>
<li>On the Illinois Tollway, by contrast, you simply pay a toll every so many miles along the highway (as well as at certain on- and off-ramps). The last two tolls, for example, represent my cost for using <a href="https://en.wikipedia.org/wiki/Interstate_355">I-355</a>.</li>
</ul>]]></content:encoded></item><item><title>socialized booze</title><link>https:://chrisphan.com/2012/05/28/socialized-booze/index.html</link><description><![CDATA[ The word “socialism” has been frequently misused recently, mostly in hyperbole about the recent health care reforms. However, socialism is alive and well in another]]></description><guid>https:://chrisphan.com/2012/05/28/socialized-booze/index.html</guid><pubDate>Mon, 28 May 2012 18:42:15 -0500</pubDate><content:encoded><![CDATA[
<p>The word “socialism” has been frequently misused recently, mostly in hyperbole about the recent health care reforms. However, socialism is alive and well in another sector of the economy, in a number states in which the government has a monopoly on retail sales of spirits. The <i>New York Times</i> <a href="https://www.nytimes.com/2012/05/27/us/in-washington-state-liquor-stores-are-about-to-go-private.html">describes the liquor control system in the state of Washington</a>, a system which will be eliminated on Friday:</p>
<blockquote>
<p>State control, in turn, made generations of civil servants tastemaking critics — their decisions on what to stock dictating what people could order in bars or buy in the stores.</p>
<p>In 2010, for example, a <a href="http://www.5oclockdistillery.com/" title="link to 5 O’Clock Distillery Web site">tiny distiller</a> here in Cashmere, called It’s Five O’Clock Somewhere, made a grape brandy that the owner, Colin Levi, was quite proud of. Liquor Control Board officials came by for a tasting and did not much care for it, Mr. Levi said, and that was that — it never went into distribution.</p>
</blockquote>
<p>Until 2009, I lived in Oregon, another state with a government monopoly on the sale of liquor. In 2002, Oregonians rejected <a href="https://en.wikipedia.org/wiki/Oregon_Ballot_Measure_23_(2002)">a ballot measure</a> that would have created a single-payer health care system in that state. At the time, I remarked that people in Oregon were afraid of “socialized medicine” but had no problem with “socialized booze”.</p>]]></content:encoded></item><item><title>Someone needs to take a stats class</title><link>https:://chrisphan.com/2012/05/21/someone-needs-to-take-a-stats-class/index.html</link><description><![CDATA[ “[I]n the end this is not a scientific survey. It’s a random survey.” —Rep. Daniel Webster (R-Florida), explaining his opposition to the Census Bureau’s American]]></description><guid>https:://chrisphan.com/2012/05/21/someone-needs-to-take-a-stats-class/index.html</guid><pubDate>Mon, 21 May 2012 19:19:53 -0400</pubDate><content:encoded><![CDATA[
<p><a href="https://www.nytimes.com/2012/05/20/sunday-review/the-debate-over-the-american-community-survey.html">“[I]n the end this is not a scientific survey. It’s a random survey.”</a>—Rep. Daniel Webster (R-Florida), explaining his opposition to the Census Bureau’s American Community Survey.</p>
<p>Rep. Webster should hope that his campaign advisors have a better understanding of sound polling methodology than he does.</p>
<p>(Via <a href="http://www.slate.com/blogs/moneybox/2012/05/20/gop_rep_daniel_webster_bashes_census_survey_as_quot_random_quot_rather_than_quot_scientific_quot_.html">Matthew Yglesias</a>.)</p>]]></content:encoded></item><item><title>Visit to the 9/11 Memorial</title><link>https:://chrisphan.com/2012/05/17/visit-to-the-911-memorial/index.html</link><description><![CDATA[ Today, Sarah and I visited the National September 11 Memorial, which sits on Ground Zero. Visiting the memorial requires a visitor pass. The passes are]]></description><guid>https:://chrisphan.com/2012/05/17/visit-to-the-911-memorial/index.html</guid><pubDate>Thu, 17 May 2012 23:37:10 -0400</pubDate><content:encoded><![CDATA[
<p>Today, Sarah and I visited the National September 11 Memorial, which sits on Ground Zero.</p>
<p>Visiting the memorial requires a visitor pass. The passes are free, but have to be reserved ahead of time on <a href="http://www.911memorial.org/">their web site</a>. (I reserved our passes in late April, and there were already no slots available on Friday, Saturday, or Sunday.)  There was about a 15 minute wait to enter the memorial, which included passing through metal detectors.</p>
<p>The memorial consists of a plaza full of trees, and two recessed pools in the footprints of the twin towers. Water flows down the sides of the pools, and the names of 9/11 victims line the rims of the pools.</p>
<p><img src="https://blog.chrisphan.com/flickr_photos/9_11_memorial/1.jpg" alt="A large square recessed pool with a smaller square hole in the center. Behind the pool are some trees, and behind those are some buildings, some of which are under construction. In the foreground, we see the rim of the pool lists names." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/9_11_memorial/2.jpg" alt="Sarah, a woman in her early thirties with long, brown hair in a ponytail, wearing a white blouse, facing away from the camera, solemnly contemplates the names on the rim of a recessed pool. There are trees on the other side of the pool, and tall buildings on behind the trees." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/9_11_memorial/3.jpg" alt="A line of trees circles the side of one of the recessed pools. Visitors to the memorial quietly contemplate the memorial." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/9_11_memorial/4.jpg" alt="Chris, a man in his early thirties with short dark brown hair, wearing a gray and blue windbreaker, looks over the rim of a recessed pool. Names are visible on the rim of the pool. Behind the pool are trees, and behind the trees are tall buildings, and a shorter glass building." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/9_11_memorial/5.jpg" alt="A large square recessed pool, with a smaller square hole in the middle. There are building under construction on the other side of the pool." /></p>
<p><img src="https://blog.chrisphan.com/flickr_photos/9_11_memorial/6.jpg" alt="Trees and patches of green lawn. In the background are tall buildings." /></p>]]></content:encoded></item><item><title>Looking forward to the 14th b’ak’tun</title><link>https:://chrisphan.com/2012/05/12/looking-forward-to-the-14th-baktun/index.html</link><description><![CDATA[ The media has been discussing the recent discovery of Mayan astronomical calculations of events well past 2012. They are saying that this debunks the notion]]></description><guid>https:://chrisphan.com/2012/05/12/looking-forward-to-the-14th-baktun/index.html</guid><pubDate>Sat, 12 May 2012 23:45:47 -0400</pubDate><content:encoded><![CDATA[
<p>The media has been discussing the recent discovery of Mayan astronomical calculations of events well past 2012. They are saying that this debunks the notion that the Maya predicted the end of the world on 21 December. Here’s a video news summary from <em>Slate</em>:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/47kRdCLALgo?si=2TgyxWVcfXVqH5PL" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<p>While this is really cool as an archaeological find, it doesn’t debunk anything <em>that hasn’t been debunked a many, many times before</em>. Indeed, the notion that the Maya ascribed any eschatological meaning to the end of the 13th b’ak’tun has been throughly discredited. For example, here’s an expert on the ancient Maya <a href="http://www.usatoday.com/tech/science/2007-03-27-maya-2012_n.htm">quoted in 2009</a>:</p>
<blockquote>
<p>“For the ancient Maya, it was a huge celebration to make it to the end of a whole cycle,” says Sandra Noble, executive director of the Foundation for the Advancement of Mesoamerican Studies in Crystal River, Fla. To render Dec. 21, 2012, as a doomsday or moment of cosmic shifting, she says, is “a complete fabrication and a chance for a lot of people to cash in.”</p>
</blockquote>
<p>And here’s a Mayan elder <a href="http://www.msnbc.msn.com/id/33261483/ns/technology_and_science-science/t/even-maya-are-getting-sick-hype">quoted by the Associated Press in 2009</a>:</p>
<blockquote>
<p>Apolinario Chile Pixtun is tired of being bombarded with frantic questions about the Mayan calendar supposedly “running out” on Dec. 21, 2012. After all, it’s not the end of the world.</p>
<p>Or is it?</p>
<p>Definitely not, the Mayan elder insists. “I came back from England last year and, man, they had me fed up with this stuff.”</p>
</blockquote>
<p>Let me tell you why I find the 2012 hype obnoxious: One of the key tenets of this 2012 stuff is that the ancient Mayan civilization had important insights that are now being ignored by modern Western society. Its believers hold themselves as more “enlightened” for recognizing the value of this native culture. Except, in reality, the hype is based on ignoring what the Maya said and misappropriating their voice to push silly new-age ideas.</p>
<p>Hopefully, these latest archaeological finds will tamp down this 2012 nonsense.</p>]]></content:encoded></item><item><title>PhanBlog: now with blogroll!</title><link>https:://chrisphan.com/2012/05/09/phanblog-now-with-blogroll/index.html</link><description><![CDATA[ I’ve added a blogroll, which you should see on the left of the main page of this blog. (Of course, some of these blogs regularly]]></description><guid>https:://chrisphan.com/2012/05/09/phanblog-now-with-blogroll/index.html</guid><pubDate>Wed, 9 May 2012 00:14:58 -0400</pubDate><content:encoded><![CDATA[
<p>I’ve added a blogroll, which you should see on the left of the <a href="http://blog.chrisphan.com/">main page</a> of this blog. (Of course, some of these blogs regularly express opinions with which I disagree, so you shouldn’t construe inclusion on my blogroll as an endorsement of that author’s political views.)</p>]]></content:encoded></item><item><title>Agricultural area cautions</title><link>https:://chrisphan.com/2012/04/29/agricultural-area-cautions/index.html</link><description><![CDATA[ A white sign is posted in front of some bushes, behind which is a farm. The sign reads: Agricultural area cautions: Stay on trail. Look.]]></description><guid>https:://chrisphan.com/2012/04/29/agricultural-area-cautions/index.html</guid><pubDate>Sun, 29 Apr 2012 21:31:27 -0400</pubDate><content:encoded><![CDATA[
<p><img src="https://blog.chrisphan.com/flickr_photos/ag_area.jpg" alt="A white sign is posted in front of some bushes, behind which is a farm. The sign reads: Agricultural area cautions: Stay on trail. Look. Don't touch. Respect farmer's rights, privacy, and property. Watch for health hazards and projectiles from farm machinery. Protect livestock from litter. Do not feed, call, yell at, or tease livestock. Please do not photograph residents. Be aware of electric fences. Avoid biohazards: Do not enter farm buildings, pastures, ponds, or fields." /></p>]]></content:encoded></item><item><title>A bowl full of candy bars is another example of “a breakfast they’ll want to eat”</title><link>https:://chrisphan.com/2012/04/28/nutella-and-media-literacy/index.html</link><description><![CDATA[ Recently, the makers of Nutella settled a class-action lawsuit from a San Diego mother who claimed advertising mislead her into thinking the stuff was healthy.]]></description><guid>https:://chrisphan.com/2012/04/28/nutella-and-media-literacy/index.html</guid><pubDate>Sat, 28 Apr 2012 14:55:39 -0400</pubDate><content:encoded><![CDATA[
<p>Recently, the makers of Nutella settled a class-action lawsuit from a San Diego mother who claimed advertising mislead her into thinking the stuff was healthy.</p>
<p>I found a YouTube video of one of the ads embedded in <a href="http://www.nj.com/njvoices/index.ssf/2012/04/in_nutella_lawsuit_over_false.html">Carly Rothman’s article about the lawsuit</a>:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/ThIrw_LpuRA?si=qyBMSq50K1ehgQQk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<p>Here’s a question for you: Do you think the health claims in this ad are misleading?</p>
<p>That’s a trick question, because the ad makes <i>no</i> health claims. The mother in the ad says “it’s perfect on multigrain toast, and even whole wheat waffles”—in this context, “perfect” could mean “healthy”, but it could also mean “really yummy”. She says it’s made from “simple, quality ingredients”, which is also true of a stick of butter. The mother also says that after feeding her kids Nutella, “I feel good that they’re ready to tackle the day”. None of these statements imply the stuff is <em>healthy.</em> In fact, the words “healthy”, “balanced breakfast”, or “low-fat” appear nowhere in the ad.</p>
<p>(Mind you, I haven’t seen any of the other Nutella ads, so I’m not saying Ferrero, the makers of Nutella, isn’t guilty of making false health claims, just that this particular ad doesn’t make any.)</p>
<p>This commercial is a great illustration of how an advertiser can leave an impression (in this case, that Nutella is healthy) without explicitly saying it. Of course, this is done by advertisers all the time: a textbook example is the use of attractive women to give the impression that using the product (often some extremely mediocre beer) will attract such women. This is why we need more media literacy education. It’s not enough to ban advertising that’s blatantly false—you have to make people aware of advertisers’ subtle tricks.</p>
<p>Also, I agree with Carly Rothman: if you are going to start feeding some food to your kids every morning, perhaps it would be wise to glance at the nutrition label beforehand.</p>]]></content:encoded></item><item><title>My photography featured on the BBC News website!</title><link>https:://chrisphan.com/2012/04/25/my-photography-featured-on-the-bbc-news-website/index.html</link><description><![CDATA[ Screen shot of the BBC news site from 2012. The headline reads "Perthshire village of Dull wants to forge tiles with US town of Boring"]]></description><guid>https:://chrisphan.com/2012/04/25/my-photography-featured-on-the-bbc-news-website/index.html</guid><pubDate>Wed, 25 Apr 2012 08:35:00 -0400</pubDate><content:encoded><![CDATA[
<p><img src="/wp-content/uploads/bbc_small.png" alt="Screen shot of the BBC news site from 2012. The headline reads &quot;Perthshire village of Dull wants to forge tiles with US town of Boring&quot;" /></p>
<p>Yesterday, I found a photo I took in 2003 used on the BBC News site! It’s pretty awesome. Here’s what happened:</p>
<p>Back in 2003, I received a digital camera as a graduation gift. I used it to take a photo of one of my favorite signs: the sign for the Boring/Oregon City exit on U.S. 26. I was relatively new to photography; I don’t think it’s my best work.</p>
<p><img src="/wp-content/uploads/Boringorcity-300x225.jpg" alt="A highway exit sign listing the destinations Boring and Oregon City" /></p>
<p>The next year, <a href="https://en.wikipedia.org/wiki/File:Boringorcity.jpg">I uploaded a copy of this photo to Wikipedia</a>. I didn’t know any better, so I reduced the image to 512 × 384, which you are not supposed to do when putting photos on Wikipedia. If I had access to the original full-size file, I’d replace the one on Wikipedia. The closest I have is <a href="https://secure.flickr.com/photos/functoruser/57094722/">this Flickr photo</a>, taken in the same session, which lacks the truck.</p>
<p>Yesterday, one of my friends from high school posted <a href="http://www.bbc.co.uk/news/uk-scotland-tayside-central-17825138">a BBC News article</a> on her Facebook wall. According to the BBC, the village of Dull in the Scottish Highlands wants to become the sister community of Boring, Oregon. I followed the link because I, like almost anyone who attended <a href="http://www.oregontrailschools.com/Page/970">Boring Middle School</a>, was excited to see Boring featured in the international media. But then I saw the photo on the article, which they presumably took from Wikipedia, and said “HOLY CRAP! That picture of the ‘Boring, Oregon City’ sign? It’s my picture!”</p>
<p>I am extremely honored to find my work featured by the BBC!</p>
<p>Since many of my Flickr photos are available under Creative Commons licenses, I am used to seeing them occasionally appear on blogs. I believe this is the first time, however, that my work has been used in an international news story!</p>]]></content:encoded></item><item><title>(anti)social reading apps</title><link>https:://chrisphan.com/2012/04/24/antisocial-reading-apps/index.html</link><description><![CDATA[ THIS. Except: when I click on a link on the Eff Bee to an article and I’m asked to add an app to follow the]]></description><guid>https:://chrisphan.com/2012/04/24/antisocial-reading-apps/index.html</guid><pubDate>Tue, 24 Apr 2012 19:47:37 -0400</pubDate><content:encoded><![CDATA[
<p><a href="http://theoatmeal.com/pl/state_web_spring/yahoo">THIS.</a></p>
<p>Except: when I click on a link on the Eff Bee to an article and I’m asked to add an app to follow the link, I don’t Google for the article—I refuse to read it at all. I refuse to reward antisocial behavior.</p>]]></content:encoded></item><item><title>First post</title><link>https:://chrisphan.com/2012/04/23/first-post/index.html</link><description><![CDATA[ Welcome to PhanBlog! I’ve created this blog to share my valuable insights with the rest of the world. I am planning to post about funny]]></description><guid>https:://chrisphan.com/2012/04/23/first-post/index.html</guid><pubDate>Mon, 23 Apr 2012 21:03:30 -0400</pubDate><content:encoded><![CDATA[
<p>Welcome to PhanBlog!</p>
<p>I’ve created this blog to share my valuable insights with the rest of the world. I am planning to post about funny things found on the Intertubes, politics, mathematics, and perhaps <i>West Wing</i> episodes (because more online discussion of six-year-old TV shows can’t hurt). Anyway, in the mean time, here is a video of my parents’ cat:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Wt4RpPhZxPM?si=9TQUBniMmwIjE11K" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>]]></content:encoded></item></channel></rss>