<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><id>https://aaronholmes.net</id><title>Bits, Bobs &amp; Breakpoints — Aaron Holmes</title><updated>2026-07-06T18:09:48.872105+00:00</updated><author><name>Aaron Holmes</name></author><link href="https://aaronholmes.net"/><link href="https://aaronholmes.net/rss.xml" rel="self"/><generator uri="https://lkiesow.github.io/python-feedgen" version="1.0.0">python-feedgen</generator><rights>2025, Aaron Holmes</rights><subtitle>Bits, Bobs &amp; Breakpoints — Aaron Holmes</subtitle><entry><id>https://aaronholmes.net/2026/browser_based_vcard_qr_code_generator.html</id><title>Browser-Based URL and vCard QR Code Generator</title><updated>2026-06-01T17:06:58+00:00</updated><content>&lt;section id="browser-based-url-and-vcard-qr-code-generator"&gt;
&lt;h1&gt;Browser-Based URL and vCard QR Code Generator&lt;a class="headerlink" href="#browser-based-url-and-vcard-qr-code-generator" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2026-05-25"&gt;25 May 2026&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/javascript.html"&gt;JavaScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/qr-code.html"&gt;QR Code&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/svg.html"&gt;SVG&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/utility.html"&gt;Utility&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/frontend.html"&gt;Frontend&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a single HTML file that turns a URL or
&lt;a class="reference external" href="https://datatracker.ietf.org/doc/html/rfc2426"&gt;vCard&lt;/a&gt; contact details into a
QR code and saves it as a scalable SVG - handy for business cards, signage, or
anything headed to print. It runs entirely in your browser with no internet
connection, so nothing you type ever leaves your device.&lt;/p&gt;
&lt;section id="opening-it"&gt;
&lt;h2&gt;Opening It&lt;a class="headerlink" href="#opening-it" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="/_static/files/2026/browser_based_vcard_qr_code_generator/qr-studio.html"&gt;Open the generator&lt;/a&gt;
in your browser, or access it right in this page, or download that file and open a local copy - it behaves the
same either way, since the whole thing runs client-side. The build form is on
the left; the QR code, the download buttons, and the design controls are on the
right. The code re-renders automatically whenever you change a field - there is
no “generate” button to press.&lt;/p&gt;
&lt;iframe src="/_static/files/2026/browser_based_vcard_qr_code_generator/qr-studio.html" style="width:100%;height:500px;"&gt;&lt;/iframe&gt;&lt;/section&gt;
&lt;section id="build-a-qr-for"&gt;
&lt;h2&gt;Build a QR For&lt;a class="headerlink" href="#build-a-qr-for" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The buttons at the top pick what the code encodes:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL&lt;/strong&gt; - any link, including &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;https://&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;mailto:&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;tel:&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sms:&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;geo:&lt;/span&gt;&lt;/code&gt;, and custom app schemes. This is the default.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contact (vCard)&lt;/strong&gt; - a contact card a phone can import directly into its
address book.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The form below changes to match. Each mode keeps its own saved data, so you can
switch back and forth without losing what you’d typed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="entering-a-url"&gt;
&lt;h2&gt;Entering a URL&lt;a class="headerlink" href="#entering-a-url" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In URL mode, paste your address into the &lt;strong&gt;URL&lt;/strong&gt; field. The same scheme prefixes
that work on a phone work here too. The preview updates live, and the encoded
payload is shown beneath it. &lt;strong&gt;Clear URL&lt;/strong&gt; wipes the field and its saved copy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="entering-a-contact"&gt;
&lt;h2&gt;Entering a Contact&lt;a class="headerlink" href="#entering-a-contact" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fill in whatever applies: name, organization, title, address, website, and a
note. Every field is optional, and blank ones are simply left out of the code.
As you type, the preview and the vCard payload beneath it update live.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="phones-and-emails"&gt;
&lt;h2&gt;Phones and Emails&lt;a class="headerlink" href="#phones-and-emails" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Use &lt;strong&gt;+ Add phone&lt;/strong&gt; and &lt;strong&gt;+ Add email&lt;/strong&gt; to add rows, and the &lt;strong&gt;×&lt;/strong&gt; on a row to
remove it. Each row has a type, an optional custom label, and a primary star.&lt;/p&gt;
&lt;section id="types-and-labels"&gt;
&lt;h3&gt;Types and Labels&lt;a class="headerlink" href="#types-and-labels" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Pick a &lt;strong&gt;type&lt;/strong&gt; from the dropdown - Mobile, Work, Home, and so on. To give an
entry a custom name like &lt;em&gt;Store&lt;/em&gt;, type it into the &lt;strong&gt;label&lt;/strong&gt; field on the row.&lt;/p&gt;
&lt;p&gt;For an entry you really want to read as its label, set the type to
&lt;strong&gt;None / label only&lt;/strong&gt;. On Android a standard type can override the label, so
dropping the type lets the label win. iOS shows the label either way.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-primary-star"&gt;
&lt;h3&gt;The Primary Star&lt;a class="headerlink" href="#the-primary-star" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Tap the &lt;strong&gt;★&lt;/strong&gt; to mark one phone and one email as primary. Whatever imports the
card treats that entry as the default.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="country-codes"&gt;
&lt;h3&gt;Country Codes&lt;a class="headerlink" href="#country-codes" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Phone rows have a country picker; search it by country name or dial code. If you
paste or type a number that begins with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;+&lt;/span&gt;&lt;/code&gt;, the tool detects the country and
strips the prefix for you, leaving just the local number.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="designing-the-code"&gt;
&lt;h2&gt;Designing the Code&lt;a class="headerlink" href="#designing-the-code" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The QR card on the right has its design controls in two places:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The block of options directly beneath &lt;strong&gt;Download SVG / Copy / Reset design&lt;/strong&gt;
controls the QR matrix itself - background, color, gradient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;LOGO / SHAPE / FRAME&lt;/strong&gt; tabs below it control everything that wraps the
QR - a center icon, the module shape, and the surrounding frame and label.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Every choice applies live, is saved in your browser, and survives reloads.&lt;/p&gt;
&lt;section id="background-and-color"&gt;
&lt;h3&gt;Background and Color&lt;a class="headerlink" href="#background-and-color" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt; - check &lt;strong&gt;Transparent&lt;/strong&gt; to drop the white plate. Useful when
placing the code over artwork.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Color&lt;/strong&gt; - click the swatch to open the color picker (hue strip, a 2D
saturation/value square, and an editable hex field).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gradient&lt;/strong&gt; - check the box to fill the QR’s dark modules with a gradient
instead of a flat color. A &lt;strong&gt;To&lt;/strong&gt; row appears for the end color and a
&lt;strong&gt;Linear / Radial&lt;/strong&gt; toggle. Linear adds a &lt;strong&gt;Direction&lt;/strong&gt; row with an
eight-point compass; pick where the second color should sit. Radial doesn’t
need a direction - it goes center to edge. Turning the gradient on auto-bumps
error correction to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;H&lt;/span&gt;&lt;/code&gt;, because the varying contrast across modules is
harder for scanners to threshold. If you pick a color light enough that the
contrast against the white background gets soft, the tool warns you with a
toast.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="error-correction"&gt;
&lt;h3&gt;Error Correction&lt;a class="headerlink" href="#error-correction" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Below the QR’s options is a small &lt;strong&gt;L / M / Q / H&lt;/strong&gt; selector. Higher levels
survive more wear and dirt but produce a denser code. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;M&lt;/span&gt;&lt;/code&gt; is a sensible
default; drop to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;L&lt;/span&gt;&lt;/code&gt; if a long contact won’t fit. The tool auto-bumps to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;H&lt;/span&gt;&lt;/code&gt;
whenever a center logo, a gradient, or a risky module shape is in use, so the
code can recover what’s covered or softened.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="center-logo"&gt;
&lt;h3&gt;Center Logo&lt;a class="headerlink" href="#center-logo" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;LOGO&lt;/strong&gt; tab puts a small icon at the center of the code. Pick one of the
social presets (Instagram, Facebook, X, LinkedIn, YouTube, Email, Phone,
Website, Location) or use &lt;strong&gt;Upload custom image&lt;/strong&gt; to load your own (PNG, JPEG,
GIF, WebP, or SVG - SVG keeps everything vector and stays sharp at any size).
The uploaded image shows up as a &lt;strong&gt;Custom&lt;/strong&gt; tile in the picker, and re-uploading
replaces it.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Size&lt;/strong&gt; - the icon and its plate, as a percentage of the QR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Background&lt;/strong&gt; - the shape of the plate behind the icon, &lt;strong&gt;Square&lt;/strong&gt; or
&lt;strong&gt;Circle&lt;/strong&gt;. The plate clears the QR modules in its footprint exactly, with no
partial-module artifacts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Color&lt;/strong&gt; - the logo color. By default it tracks the QR’s foreground; if you
change the QR color, the logo follows. Once you pick a color explicitly it
becomes independent, and a &lt;strong&gt;Match QR&lt;/strong&gt; button appears next to the gradient
toggle so you can re-inherit at any time. Custom raster images ignore this
setting - the image has its own pixels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gradient&lt;/strong&gt; - same controls as the QR’s gradient. Applies to preset SVG icons
by substituting their stroke and fill references; custom raster images aren’t
affected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Selecting any logo automatically bumps error correction to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;H&lt;/span&gt;&lt;/code&gt; so the code can
recover the modules the logo covers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="shape"&gt;
&lt;h3&gt;Shape&lt;a class="headerlink" href="#shape" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;SHAPE&lt;/strong&gt; tab changes how the data modules look. The default is &lt;strong&gt;Square&lt;/strong&gt;.
Other choices include &lt;strong&gt;Dots&lt;/strong&gt; (small circles), &lt;strong&gt;Rounded&lt;/strong&gt; (corner radii fill
in where neighbors are absent), &lt;strong&gt;Horizontal rounded&lt;/strong&gt; (pill-shaped), and
several decorative variants: &lt;strong&gt;Pointed&lt;/strong&gt;, &lt;strong&gt;Notched&lt;/strong&gt;, &lt;strong&gt;Hooks&lt;/strong&gt;, and
&lt;strong&gt;Triangles&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The three corner finder patterns stay as plain squares regardless of the shape
- scanners use them to locate the code, so leaving them predictable keeps things
scannable. The more decorative shapes (dots, hooks, triangles, notched)
auto-bump error correction to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;H&lt;/span&gt;&lt;/code&gt; for the same reason.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="frame"&gt;
&lt;h3&gt;Frame&lt;a class="headerlink" href="#frame" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;FRAME&lt;/strong&gt; tab puts a border around the code and an optional text label:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Style: &lt;strong&gt;None&lt;/strong&gt;, &lt;strong&gt;Square&lt;/strong&gt;, &lt;strong&gt;Rounded&lt;/strong&gt;, or &lt;strong&gt;Circle&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Color&lt;/strong&gt; - the frame’s stroke color, independent of the QR’s foreground.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gradient&lt;/strong&gt; - a gradient fill for the frame’s stroke, with the same Linear /
Radial / Direction controls as the QR. For a &lt;strong&gt;Circle&lt;/strong&gt; frame, Radial does
what you’d expect: the gradient transitions exactly across the stroke’s inside
edge to its outside edge, since the geometry is naturally radial. For Square
and Rounded frames a true inside-to-outside gradient isn’t representable on a
rectangular stroke; Radial falls back to a centered halo where the corners
pick up more of the end color than the side midpoints do. Linear works as
expected on every frame shape.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Padding&lt;/strong&gt; - the gap between the QR matrix and the inner edge of the frame.
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/code&gt; makes the frame touch the QR’s outermost dark modules; higher values add
space between them. If you turn on a gradient while padding is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/code&gt;, the tool
bumps it to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;1&lt;/span&gt;&lt;/code&gt; - a frame touching gradient-filled modules with no quiet
zone tends to defeat scanners.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Thickness&lt;/strong&gt; - the stroke width. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/code&gt; is allowed, useful for text-only
setups where you want the label but not a visible border.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below those, a divider separates the frame’s appearance from its text:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Text&lt;/strong&gt; - up to 40 characters, e.g. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SCAN&lt;/span&gt; &lt;span class="pre"&gt;ME&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Font&lt;/strong&gt; - &lt;strong&gt;Sans&lt;/strong&gt;, &lt;strong&gt;Serif&lt;/strong&gt;, or &lt;strong&gt;Mono&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Placement&lt;/strong&gt; - &lt;strong&gt;Outside&lt;/strong&gt; the frame (the canvas grows beyond it) or
&lt;strong&gt;Inside&lt;/strong&gt; (the frame grows to enclose the text alongside the QR). Circle
frames only support outside.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Position&lt;/strong&gt; - &lt;strong&gt;Top&lt;/strong&gt; or &lt;strong&gt;Bottom&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Size&lt;/strong&gt; - how big the text is.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Text color&lt;/strong&gt; - independent of the frame color. Like the logo color, it
defaults to tracking the frame color until you pick something explicitly; a
&lt;strong&gt;Match frame&lt;/strong&gt; button reverts to inheriting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gradient&lt;/strong&gt; - end color, Linear / Radial, and Direction, applied to the text
fill. At small text sizes the effect is subtle because the gradient spans only
the text’s bounding box - pick high-contrast endpoints or a horizontal
direction if you want a strongly visible gradient.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="resetting-the-design"&gt;
&lt;h2&gt;Resetting the Design&lt;a class="headerlink" href="#resetting-the-design" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Reset design&lt;/strong&gt;, to the right of Download and Copy, clears every visual setting
- background, color, all four gradients (QR, frame, logo, text), logo, shape,
frame, frame text, error correction - back to defaults. The contact or URL
itself isn’t touched.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="saving-your-work"&gt;
&lt;h2&gt;Saving Your Work&lt;a class="headerlink" href="#saving-your-work" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Everything you enter is saved in your browser automatically, so what you had
open is still there when you come back. &lt;strong&gt;Clear all fields&lt;/strong&gt; wipes the vCard
form and its saved copy; &lt;strong&gt;Clear URL&lt;/strong&gt; does the same in URL mode. &lt;strong&gt;Reset
design&lt;/strong&gt; clears just the design choices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the saved copy is tied to the specific browser and file location.
Moving or renaming the file starts fresh, and some browsers are strict about
storage on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;file://&lt;/span&gt;&lt;/code&gt; URLs - serving the file over &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;http&lt;/span&gt;&lt;/code&gt; avoids that.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="exporting"&gt;
&lt;h2&gt;Exporting&lt;a class="headerlink" href="#exporting" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Download SVG&lt;/strong&gt; - the QR code as a vector file, for print or design tools.
Stays crisp at any size. The one exception is a custom raster image used as a
logo; if you want full vector all the way through, upload an SVG.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Download .vcf&lt;/strong&gt; - the raw contact card, to import or share directly. (vCard
mode only.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copy URL&lt;/strong&gt; / &lt;strong&gt;Copy vCard&lt;/strong&gt; - copies the encoded payload to your clipboard.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="before-you-print"&gt;
&lt;h2&gt;Before You Print&lt;a class="headerlink" href="#before-you-print" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Always scan and import the finished code on a real phone before sending
anything to print.&lt;/strong&gt; A code that looks fine but imports the wrong details is
worse than none at all. Gradients, dense shapes, and tight padding all push on a
scanner’s ability to find and decode the code - the tool nudges settings toward
safer choices (ECC, padding) when you turn those on, but nothing beats verifying
on the actual device the recipient will use.&lt;/p&gt;
&lt;p&gt;One harmless quirk to expect: on Windows the country flags in vCard mode appear
as two-letter codes instead of emoji - the dial code is always shown beside
them, so nothing is actually missing.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2026/browser_based_vcard_qr_code_generator.html"/><category term="JavaScript"/><category term="QR Code"/><category term="SVG"/><category term="Utility"/><category term="Frontend"/><published>2026-05-25T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2025/interview_coding_take_homes_part_3.html</id><title>Interview Coding Take-Homes: Part 3</title><updated>2026-01-17T01:50:22+00:00</updated><content>&lt;section id="interview-coding-take-homes-part-3"&gt;
&lt;h1&gt;Interview Coding Take-Homes: Part 3&lt;a class="headerlink" href="#interview-coding-take-homes-part-3" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2025-12-15"&gt;15 December 2025&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/interviewing.html"&gt;Interviewing&lt;/a&gt;&lt;/p&gt;
&lt;section id="ucla-health-population-analysis"&gt;
&lt;h2&gt;UCLA Health - Population Analysis&lt;a class="headerlink" href="#ucla-health-population-analysis" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This take-home was about the data ingestion and cleaning population data.
The goal was to take messy JSON from an API and turn it
into a clean CSV, so the analysis and visualization could focus on the real
questions without getting bogged down in data cleanup.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="goals"&gt;
&lt;h2&gt;Goals&lt;a class="headerlink" href="#goals" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Produce a CSV with a fixed header order and stable types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep each transformation small and unit-testable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fail fast on missing required fields and log useful diagnostics.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="why-this-approach"&gt;
&lt;h2&gt;Why this approach&lt;a class="headerlink" href="#why-this-approach" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Even though the dataset was small and straightforward, it had all the typical
real-world issues: keys with spaces, inconsistent casing, and numbers as
strings. Instead of using heavy tools, I focused on keeping things clear,
with predictable output and a simple flow I could easily follow.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="repository"&gt;
&lt;h2&gt;Repository&lt;a class="headerlink" href="#repository" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The implementation is in the &lt;cite&gt;population-analysis&lt;/cite&gt; repo
under the &lt;cite&gt;Analysis/&lt;/cite&gt; directory. See the source and examples at:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/aholmes/population-analysis/tree/aba1e5330fabbd1df162d00770b853b4838f1cae/Analysis"&gt;population-analysis (Analysis)&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="process-overview"&gt;
&lt;h2&gt;Process overview&lt;a class="headerlink" href="#process-overview" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Load JSON from the API or from the cached sample used in tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rename and normalize keys so everything aligns with the internal schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coerce types (strings -&amp;gt; ints/dates) and fail if required data is missing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Emit two CSVs: one raw mapping for auditing and one cleaned file for analysis.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="key-implementation-details"&gt;
&lt;h2&gt;Key implementation details&lt;a class="headerlink" href="#key-implementation-details" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;section id="handling-messy-json-keys"&gt;
&lt;h3&gt;Handling messy JSON keys&lt;a class="headerlink" href="#handling-messy-json-keys" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The prompt demanded a tight mapping between API fields and output columns.
Because the API returns keys with spaces and wobbly casing, the data model
leans on &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;[JsonPropertyName]&lt;/span&gt;&lt;/code&gt; attributes to translate them into clean C#
properties:&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id1"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/31bcb1d423b419e86a94650082dc9be3/PopulationEntry.cs"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;PopulationEntry.cs&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id1" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;1&lt;/span&gt;&lt;span class="na"&gt;[JsonPropertyName(&amp;quot;ID State&amp;quot;)]&lt;/span&gt;
&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IdState&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;&lt;span class="na"&gt;[JsonPropertyName(&amp;quot;ID Year&amp;quot;)]&lt;/span&gt;
&lt;span class="linenos"&gt;5&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IdYear&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;6&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="linenos"&gt;7&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Population&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;8&lt;/span&gt;&lt;span class="na"&gt;[JsonPropertyName(&amp;quot;Slug State&amp;quot;)]&lt;/span&gt;
&lt;span class="linenos"&gt;9&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SlugState&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;This keeps the mapping explicit and makes it obvious which API field feeds
each column.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="fetching-and-caching-the-data"&gt;
&lt;h3&gt;Fetching and caching the data&lt;a class="headerlink" href="#fetching-and-caching-the-data" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The application calls the public census API, but I do not re-fetch on every
test run. Instead the client caches the payload locally so the API stays quiet
while I iterate:&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id2"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/1d30d24066964e4040d8104d509bbf17/Api.cs"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;Api.cs&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id2" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;1&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GetFromCache&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;httpClientFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Api&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="linenos"&gt;5&lt;/span&gt;&lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseAddress&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://datausa.io/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;On a fresh pull, the JSON hits disk before deserialization. That keeps the
workflow testable and reinforces a clean separation of concerns:&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id3"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/1d30d24066964e4040d8104d509bbf17/Api.cs"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;Api.cs&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id3" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SeekOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Begin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CopyToAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cacheDestination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cacheDestination&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FlushAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogDebug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;API data written to cache.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LogDebug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Failed to write API JSON result cache.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Seek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SeekOrigin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Begin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeserializeAsync&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;/section&gt;
&lt;section id="example-input-trimmed"&gt;
&lt;h2&gt;Example input (trimmed)&lt;a class="headerlink" href="#example-input-trimmed" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is an example of the API shape-keys with spaces, mixed casing, and numeric
types that arrive as JSON numbers.&lt;/p&gt;
&lt;div class="literal-block-wrapper docutils container" id="id4"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/37ff9631812b18bf066a50e354c48847/sample_input.json"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;sample_input.json&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id4" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;1&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;ID State&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;04000US01&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;State&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Alabama&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;Year&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;Population&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5054253&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;Slug State&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;alabama&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;ID State&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;04000US02&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;State&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Alaska&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;Year&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;Population&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;733971&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;Slug State&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;alaska&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;5&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The ingest pipeline renames those columns to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;state&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;slug&lt;/span&gt;&lt;/code&gt;, etc.,
and asserts that the types stay stable before writing the normalized CSV.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="normalized-csv-representative-rows"&gt;
&lt;h2&gt;Normalized CSV (representative rows)&lt;a class="headerlink" href="#normalized-csv-representative-rows" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The cleaned CSV fixes the header order and uses explicit types. Representative
rows:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;id,state,slug,year,population
04000US01,Alabama,alabama,2023,5054253
04000US02,Alaska,alaska,2023,733971
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="notes-on-implementation"&gt;
&lt;h2&gt;Notes on implementation&lt;a class="headerlink" href="#notes-on-implementation" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API keys such as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;ID&lt;/span&gt; &lt;span class="pre"&gt;State&amp;quot;&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;Slug&lt;/span&gt; &lt;span class="pre"&gt;State&amp;quot;&lt;/span&gt;&lt;/code&gt; map to canonical names
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;id&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;slug&lt;/span&gt;&lt;/code&gt;) so downstream code never reasons about the raw schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validation is blunt by design: missing required fields fail the run; weird
values get logged for inspection instead of disappearing quietly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Every time a new API field appeared, I did the same ritual: dump a single
response to disk, diff it against the schema, and verify the mapping by
regenerating the CSV. That quick loop kept regressions visible without a
ton of ceremony.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing-and-verification"&gt;
&lt;h2&gt;Testing and verification&lt;a class="headerlink" href="#testing-and-verification" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;section id="testing-the-pipeline"&gt;
&lt;h3&gt;Testing the pipeline&lt;a class="headerlink" href="#testing-the-pipeline" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before trusting the CSV, I walk through the same routine I use on most
take-homes: run the automated suite, then spot-check the binary output.&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;population-analysis
&lt;span class="gp"&gt;$ &lt;/span&gt;dotnet&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The tests live in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;population-analysis/Test&lt;/span&gt;&lt;/code&gt; and use xUnit + Moq. They verify
that the ingestion pipeline does what I expect even when the API or filesystem
behaves badly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="what-the-tests-cover"&gt;
&lt;h3&gt;What the tests cover&lt;a class="headerlink" href="#what-the-tests-cover" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference download internal" download="" href="../_downloads/79b6cf25d0da88a6432a2548e7f597b3/AnalysisApi.cs"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;Test/AnalysisApi.cs&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; drives the API client through both code paths. It
ensures cached payloads short-circuit HTTP calls, verifies that cache files
are written before parsing, and checks that failures log meaningful errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference download internal" download="" href="../_downloads/0162ed221410323e736249d2647be44d/AnalysisReport.cs"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;Test/AnalysisReport.cs&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; exercises the aggregation layer. It confirms that
populations group by state/year, headers stay deterministic, sorted tables
behave, and the factor column lines up with each year.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference download internal" download="" href="../_downloads/0162ed221410323e736249d2647be44d/AnalysisReport.cs"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;Test/AnalysisReport.cs&lt;/span&gt;&lt;/code&gt;&lt;/a&gt; also reflection-loads the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Report&lt;/span&gt;&lt;/code&gt; helpers so I
can assert on the tables without spinning up the CLI.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="manual-sanity-checks"&gt;
&lt;h3&gt;Manual sanity checks&lt;a class="headerlink" href="#manual-sanity-checks" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Automated tests catch regressions, but I still run a quick end-to-end pass to
see the CSV with my own eyes:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;population-analysis
&lt;span class="gp"&gt;$ &lt;/span&gt;dotnet&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;--project&lt;span class="w"&gt; &lt;/span&gt;Analysis/Analysis.csproj
&lt;span class="go"&gt;Enter a path to write the CSV file to:&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I point it at &lt;a class="reference download internal" download="" href="../_downloads/036e28f7d826b93a8d18c7568be6d7a9/population.csv"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;population.csv&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;,
inspect the generated CSV/raw pair, and spot-check a few rows against the
original JSON. When a slug or population looks wrong, I can walk back through
the normalization rules immediately.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="running-with-docker"&gt;
&lt;h3&gt;Running with Docker&lt;a class="headerlink" href="#running-with-docker" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you prefer not to set up .NET locally, the application also runs in a
Docker container. The image is multi-arch and supports both AMD64 and ARM64,
so it should work on most systems.&lt;/p&gt;
&lt;p&gt;Pull and run it like this:&lt;/p&gt;
&lt;div class="highlight-console notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gp"&gt;$ &lt;/span&gt;docker&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt; &lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;id&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="k"&gt;)&lt;/span&gt;:&lt;span class="k"&gt;$(&lt;/span&gt;id&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt; &lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;/path/to/output/directory:/csv_destination&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt; &lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;--rm&lt;span class="w"&gt; &lt;/span&gt;-it&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="gp"&gt;&amp;gt; &lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;aholmes0/population-analysis:latest
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This mounts a local directory to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/csv_destination&lt;/span&gt;&lt;/code&gt; inside the container,
where the CSV files get written. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;-u&lt;/span&gt;&lt;/code&gt; flag runs as your user ID to avoid
permission issues with the output files.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="tradeoffs"&gt;
&lt;h2&gt;Tradeoffs&lt;a class="headerlink" href="#tradeoffs" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The pipeline favors clarity and observability over extreme throughput. It
assumes the dataset fits on one machine without drama.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Formal schema enforcement (JSON Schema, etc.) would help for larger teams,
but I skipped it here to keep iteration fast.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="analysis-and-findings"&gt;
&lt;h2&gt;Analysis and findings&lt;a class="headerlink" href="#analysis-and-findings" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With the cleaned CSV ready, I shifted into exploration mode. The dataset spans
multiple years across every U.S. state and territory, so it is a natural fit
for trend comparisons. The headline question people kept asking was:
&lt;strong&gt;Are Californians moving to Texas?&lt;/strong&gt; Rather than lean on anecdotes, I ran the
numbers.&lt;/p&gt;
&lt;p&gt;Key steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Compute year-over-year population changes per state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normalize growth rates with z-scores and compare peers head-to-head.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flag periods where migration signals diverged.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plot each view so the story is obvious without reading code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Result: both California and Texas keep growing, and their growth curves tend
to move in tandem. That implies broader economic or demographic drivers
rather than a one-way California -&amp;gt; Texas pipeline.&lt;/p&gt;
&lt;section id="testing-the-idea"&gt;
&lt;h3&gt;Testing the idea&lt;a class="headerlink" href="#testing-the-idea" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I do not accept charts at face value, so I poked at the data from a few angles:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cross-check the raw counts.&lt;/strong&gt; Before normalizing, I spot-checked California
and Texas populations against the Census CSV to ensure the ingest layer did
not mangle digits. Having the raw CSV beside the formatted one made this
painless.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validate the story with multiple transforms.&lt;/strong&gt; The z-score plot highlights
divergences, but I also built the rank-change visualization to confirm the
same periods popped out. If two independent views disagree, the notebook
gets deleted.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interrogate the edges.&lt;/strong&gt; Whenever a state’s growth looked extreme, I
tracked it back to the underlying rows to see if the spike came from a real
trend or a data glitch. That habit kept the write-up grounded in facts, not
vibes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="output-and-visualization"&gt;
&lt;h3&gt;Output and visualization&lt;a class="headerlink" href="#output-and-visualization" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The cleaned population data:&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id5"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/036e28f7d826b93a8d18c7568be6d7a9/population.csv"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;population.csv&lt;/span&gt; &lt;span class="pre"&gt;(first&lt;/span&gt; &lt;span class="pre"&gt;10&lt;/span&gt; &lt;span class="pre"&gt;rows)&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id5" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&amp;quot;State Name&amp;quot;,&amp;quot;2013&amp;quot;,&amp;quot;2014&amp;quot;,&amp;quot;2015&amp;quot;,&amp;quot;2016&amp;quot;,&amp;quot;2017&amp;quot;,&amp;quot;2018&amp;quot;,&amp;quot;2019&amp;quot;,&amp;quot;2020&amp;quot;,&amp;quot;2021&amp;quot;,&amp;quot;2022&amp;quot;,&amp;quot;2022 Factors&amp;quot;
&lt;span class="linenos"&gt; 2&lt;/span&gt;&amp;quot;Alabama&amp;quot;,&amp;quot;4799277&amp;quot;,&amp;quot;4817678 (0.38%)&amp;quot;,&amp;quot;4830620 (0.27%)&amp;quot;,&amp;quot;4841164 (0.22%)&amp;quot;,&amp;quot;4850771 (0.20%)&amp;quot;,&amp;quot;4864680 (0.29%)&amp;quot;,&amp;quot;4876250 (0.24%)&amp;quot;,&amp;quot;4893186 (0.35%)&amp;quot;,&amp;quot;4997675 (2.14%)&amp;quot;,&amp;quot;5028092 (0.61%)&amp;quot;,&amp;quot;2;2;97;12959&amp;quot;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&amp;quot;Alaska&amp;quot;,&amp;quot;720316&amp;quot;,&amp;quot;728300 (1.11%)&amp;quot;,&amp;quot;733375 (0.70%)&amp;quot;,&amp;quot;736855 (0.47%)&amp;quot;,&amp;quot;738565 (0.23%)&amp;quot;,&amp;quot;738516 (-0.01%)&amp;quot;,&amp;quot;737068 (-0.20%)&amp;quot;,&amp;quot;736990 (-0.01%)&amp;quot;,&amp;quot;735951 (-0.14%)&amp;quot;,&amp;quot;734821 (-0.15%)&amp;quot;,&amp;quot;389;1889&amp;quot;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&amp;quot;Arizona&amp;quot;,&amp;quot;6479703&amp;quot;,&amp;quot;6561516 (1.26%)&amp;quot;,&amp;quot;6641928 (1.23%)&amp;quot;,&amp;quot;6728577 (1.30%)&amp;quot;,&amp;quot;6809946 (1.21%)&amp;quot;,&amp;quot;6946685 (2.01%)&amp;quot;,&amp;quot;7050299 (1.49%)&amp;quot;,&amp;quot;7174064 (1.76%)&amp;quot;,&amp;quot;7079203 (-1.32%)&amp;quot;,&amp;quot;7172282 (1.31%)&amp;quot;,&amp;quot;2;13;311;887&amp;quot;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&amp;quot;Arkansas&amp;quot;,&amp;quot;2933369&amp;quot;,&amp;quot;2947036 (0.47%)&amp;quot;,&amp;quot;2958208 (0.38%)&amp;quot;,&amp;quot;2968472 (0.35%)&amp;quot;,&amp;quot;2977944 (0.32%)&amp;quot;,&amp;quot;2990671 (0.43%)&amp;quot;,&amp;quot;2999370 (0.29%)&amp;quot;,&amp;quot;3011873 (0.42%)&amp;quot;,&amp;quot;3006309 (-0.18%)&amp;quot;,&amp;quot;3018669 (0.41%)&amp;quot;,&amp;quot;3;47;79;271&amp;quot;
&lt;span class="linenos"&gt; 6&lt;/span&gt;&amp;quot;California&amp;quot;,&amp;quot;37659181&amp;quot;,&amp;quot;38066920 (1.08%)&amp;quot;,&amp;quot;38421464 (0.93%)&amp;quot;,&amp;quot;38654206 (0.61%)&amp;quot;,&amp;quot;38982847 (0.85%)&amp;quot;,&amp;quot;39148760 (0.43%)&amp;quot;,&amp;quot;39283497 (0.34%)&amp;quot;,&amp;quot;39346023 (0.16%)&amp;quot;,&amp;quot;39455353 (0.28%)&amp;quot;,&amp;quot;39356104 (-0.25%)&amp;quot;,&amp;quot;2;2;2;53;92821&amp;quot;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&amp;quot;Colorado&amp;quot;,&amp;quot;5119329&amp;quot;,&amp;quot;5197580 (1.53%)&amp;quot;,&amp;quot;5278906 (1.56%)&amp;quot;,&amp;quot;5359295 (1.52%)&amp;quot;,&amp;quot;5436519 (1.44%)&amp;quot;,&amp;quot;5531141 (1.74%)&amp;quot;,&amp;quot;5610349 (1.43%)&amp;quot;,&amp;quot;5684926 (1.33%)&amp;quot;,&amp;quot;5723176 (0.67%)&amp;quot;,&amp;quot;5770790 (0.83%)&amp;quot;,&amp;quot;2;5;59;9781&amp;quot;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&amp;quot;Connecticut&amp;quot;,&amp;quot;3583561&amp;quot;,&amp;quot;3592053 (0.24%)&amp;quot;,&amp;quot;3593222 (0.03%)&amp;quot;,&amp;quot;3588570 (-0.13%)&amp;quot;,&amp;quot;3594478 (0.16%)&amp;quot;,&amp;quot;3581504 (-0.36%)&amp;quot;,&amp;quot;3575074 (-0.18%)&amp;quot;,&amp;quot;3570549 (-0.13%)&amp;quot;,&amp;quot;3605330 (0.97%)&amp;quot;,&amp;quot;3611317 (0.17%)&amp;quot;,&amp;quot;3611317&amp;quot;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&amp;quot;Delaware&amp;quot;,&amp;quot;908446&amp;quot;,&amp;quot;917060 (0.95%)&amp;quot;,&amp;quot;926454 (1.02%)&amp;quot;,&amp;quot;934695 (0.89%)&amp;quot;,&amp;quot;943732 (0.97%)&amp;quot;,&amp;quot;949495 (0.61%)&amp;quot;,&amp;quot;957248 (0.82%)&amp;quot;,&amp;quot;967679 (1.09%)&amp;quot;,&amp;quot;981892 (1.47%)&amp;quot;,&amp;quot;993635 (1.20%)&amp;quot;,&amp;quot;5;37;41;131&amp;quot;
&lt;span class="linenos"&gt;10&lt;/span&gt;&amp;quot;District of Columbia&amp;quot;,&amp;quot;619371&amp;quot;,&amp;quot;633736 (2.32%)&amp;quot;,&amp;quot;647484 (2.17%)&amp;quot;,&amp;quot;659009 (1.78%)&amp;quot;,&amp;quot;672391 (2.03%)&amp;quot;,&amp;quot;684498 (1.80%)&amp;quot;,&amp;quot;692683 (1.20%)&amp;quot;,&amp;quot;701974 (1.34%)&amp;quot;,&amp;quot;683154 (-2.68%)&amp;quot;,&amp;quot;670587 (-1.84%)&amp;quot;,&amp;quot;3;223529&amp;quot;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Key analysis code blocks and observations:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="helper-functions-for-analysis"&gt;
&lt;h3&gt;Helper Functions for Analysis&lt;a class="headerlink" href="#helper-functions-for-analysis" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Before diving into visualizations, I defined helper classes and functions to
handle the data transformations consistently across plots.&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id6"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;FillData class and zscore helper functions&lt;/span&gt;&lt;a class="headerlink" href="#id6" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;FillData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NamedTuple&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;    &lt;span class="n"&gt;year1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;    &lt;span class="n"&gt;year2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;    &lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;    &lt;span class="n"&gt;zscore2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;    &lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;    &lt;span class="n"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;    &lt;span class="n"&gt;middle_x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;    &lt;span class="n"&gt;middle_y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;zscore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Calculate the zscore of a change.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_fill_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year_idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zscore2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Get data needed for plot_fill(...) and fill(...)&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;17&lt;/span&gt;    &lt;span class="n"&gt;year1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;year2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;18&lt;/span&gt;    &lt;span class="n"&gt;zscore_change1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;19&lt;/span&gt;    &lt;span class="n"&gt;zscore_change2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zscore2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;zscore2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;20&lt;/span&gt;    &lt;span class="n"&gt;middle_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year_idx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;year_idx&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="linenos"&gt;21&lt;/span&gt;    &lt;span class="n"&gt;middle_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="linenos"&gt;22&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;FillData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;year2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zscore2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zscore_change1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zscore_change2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middle_x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middle_y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;23&lt;/span&gt;
&lt;span class="linenos"&gt;24&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;plot_fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FillData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#1f77b4&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#ff7f0e&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;25&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Draws the plot for fill data between fill_data.year1 and fill_data.year2&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;26&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;change2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Both changes are declining&lt;/span&gt;
&lt;span class="linenos"&gt;27&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# First change declines more&lt;/span&gt;
&lt;span class="linenos"&gt;28&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2193&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2193&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;29&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Second change declines more&lt;/span&gt;
&lt;span class="linenos"&gt;30&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2193&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2193&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;31&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;change2&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Both changes are growing&lt;/span&gt;
&lt;span class="linenos"&gt;32&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Change1 grows less&lt;/span&gt;
&lt;span class="linenos"&gt;33&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2191&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2191&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;34&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Change2 grows less&lt;/span&gt;
&lt;span class="linenos"&gt;35&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2191&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2191&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;36&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# One is growing, the other is declining&lt;/span&gt;
&lt;span class="linenos"&gt;37&lt;/span&gt;        &lt;span class="n"&gt;change1_arrow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2193&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2191&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;38&lt;/span&gt;        &lt;span class="n"&gt;change2_arrow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2193&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;change2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\u2191&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;39&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;change1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;change2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Change1 declines more or grows less&lt;/span&gt;
&lt;span class="linenos"&gt;40&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change1_arrow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change2_arrow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;41&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Change 2 declines more or grows less&lt;/span&gt;
&lt;span class="linenos"&gt;42&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change1_arrow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;change2_arrow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;43&lt;/span&gt;
&lt;span class="linenos"&gt;44&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="linenos"&gt;45&lt;/span&gt;    &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FillData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;46&lt;/span&gt;    &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;47&lt;/span&gt;    &lt;span class="n"&gt;arrow_left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="linenos"&gt;48&lt;/span&gt;    &lt;span class="n"&gt;arrow_right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="linenos"&gt;49&lt;/span&gt;    &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
&lt;span class="linenos"&gt;50&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;51&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Fills the space between fill_data.year1 and fill_data.year2&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;52&lt;/span&gt;    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fill_between&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;year2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="linenos"&gt;53&lt;/span&gt;                     &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zscore1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zscore2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;iloc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="linenos"&gt;54&lt;/span&gt;                     &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;55&lt;/span&gt;    &lt;span class="n"&gt;middle_x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;middle_x&lt;/span&gt;
&lt;span class="linenos"&gt;56&lt;/span&gt;    &lt;span class="n"&gt;middle_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;middle_y&lt;/span&gt;
&lt;span class="linenos"&gt;57&lt;/span&gt;    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FancyBboxPatch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;middle_x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middle_y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;58&lt;/span&gt;                                        &lt;span class="n"&gt;boxstyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;round,pad=0.01&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;white&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zorder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;59&lt;/span&gt;    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FancyBboxPatch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;middle_x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middle_y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;60&lt;/span&gt;                                        &lt;span class="n"&gt;boxstyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;round,pad=0.01&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;facecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;white&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;edgecolor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zorder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;61&lt;/span&gt;    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="linenos"&gt;62&lt;/span&gt;        &lt;span class="n"&gt;arrow_left&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;section id="year-over-year-change-analysis"&gt;
&lt;h3&gt;Year-over-Year Change Analysis&lt;a class="headerlink" href="#year-over-year-change-analysis" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The first visualization examines year-over-year population changes, normalized
by z-scores to compare states on the same scale. The plot highlights periods
where California and Texas growth rates diverged significantly, using filled
areas and arrows to mark those intervals.&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id7"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;YoY change calculation and plotting&lt;/span&gt;&lt;a class="headerlink" href="#id7" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yaxis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_major_formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FuncFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percent_formatter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;california_change&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;california_zscore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;o&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;California&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texas_change&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;texas_zscore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;o&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Texas&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;california_zscore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;    &lt;span class="n"&gt;fill_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_fill_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;california_change&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;texas_change&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;california_zscore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;texas_zscore&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;    &lt;span class="n"&gt;ca_change&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;change1&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;    &lt;span class="n"&gt;tx_change&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;change2&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;    &lt;span class="n"&gt;plot_fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ca_change&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tx_change&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fill_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Normalized Year-over-Year Percentage Change in Population for California and Texas&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Year&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Z-Score of % Change&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="n"&gt;draw_legend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;California&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Texas&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img alt="Year-over-year population change plot with z-score normalization" class="align-center" src="../_images/yoy_plot.svg" /&gt;
&lt;/section&gt;
&lt;section id="rank-change-visualization"&gt;
&lt;h3&gt;Rank Change Visualization&lt;a class="headerlink" href="#rank-change-visualization" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This plot shows how states’ population ranks shifted from 2013 to 2022, with
bars representing 2022 populations and curved arrows indicating rank changes.
States that moved up or down in ranking are highlighted with colored bars and
connecting arcs.&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id8"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;Rank change plotting with custom legend handler&lt;/span&gt;&lt;a class="headerlink" href="#id8" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;HandlerArrowLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HandlerLine2D&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;create_artists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orig_handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xdescent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ydescent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trans&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;        &lt;span class="c1"&gt;# Create a line and an arrowhead as separate artists&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;        &lt;span class="n"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;        &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Line2D&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;xdescent&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;xdescent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orig_handle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_linestyle&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orig_handle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_color&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;        &lt;span class="n"&gt;arrow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Line2D&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;xdescent&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orig_handle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_color&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;markersize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;fontsize&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;None&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arrow&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yaxis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_major_formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FuncFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;millions_formatter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="n"&gt;bars_2022&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pop_2022_sorted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pop_2022_sorted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Relative population rank change between 2013 and 2022&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;State&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Population&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xticks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;
&lt;span class="linenos"&gt;17&lt;/span&gt;&lt;span class="n"&gt;line_handles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="linenos"&gt;18&lt;/span&gt;    &lt;span class="n"&gt;Line2D&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rank change&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="linenos"&gt;19&lt;/span&gt;    &lt;span class="n"&gt;Line2D&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;top three largest rank changes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="linenos"&gt;20&lt;/span&gt;    &lt;span class="n"&gt;Line2D&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;top three smallest rank changes&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="linenos"&gt;21&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;22&lt;/span&gt;&lt;span class="n"&gt;block_handles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="linenos"&gt;23&lt;/span&gt;    &lt;span class="n"&gt;patches&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Population &amp;amp; unchanged rank&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="linenos"&gt;24&lt;/span&gt;    &lt;span class="n"&gt;patches&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Population &amp;amp; changed rank&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;25&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;26&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;line_handles&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;block_handles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;handler_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HandlerArrowLine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line_handles&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_frame&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_alpha&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;27&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;28&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bars_2022&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pop_2022_sorted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;29&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;changed_states&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;30&lt;/span&gt;        &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COLOR4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;31&lt;/span&gt;        &lt;span class="n"&gt;prev_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_2013&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;32&lt;/span&gt;        &lt;span class="n"&gt;new_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_2022&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;33&lt;/span&gt;        &lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConnectionPatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="linenos"&gt;34&lt;/span&gt;            &lt;span class="n"&gt;xyA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prev_pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pop_2013_sorted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
&lt;span class="linenos"&gt;35&lt;/span&gt;            &lt;span class="n"&gt;xyB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pop_2022_sorted&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
&lt;span class="linenos"&gt;36&lt;/span&gt;            &lt;span class="n"&gt;coordsA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coordsB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;37&lt;/span&gt;            &lt;span class="n"&gt;axesA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axesB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;38&lt;/span&gt;            &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COLOR1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;top_3_states_by_position_change&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COLOR2&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;bottom_3_states_by_position_change&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;COLOR3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="linenos"&gt;39&lt;/span&gt;            &lt;span class="n"&gt;arrowstyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ArrowStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;simple&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;head_width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;head_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tail_width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
&lt;span class="linenos"&gt;40&lt;/span&gt;            &lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;41&lt;/span&gt;            &lt;span class="n"&gt;linewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt;42&lt;/span&gt;            &lt;span class="n"&gt;connectionstyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;arc3,rad=0.9&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;43&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;44&lt;/span&gt;        &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;45&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img alt="Population rank change visualization with arrows" class="align-center" src="../_images/rank_change_plot.svg" /&gt;
&lt;/section&gt;
&lt;section id="average-annual-growth-rate-map"&gt;
&lt;h3&gt;Average Annual Growth Rate Map&lt;a class="headerlink" href="#average-annual-growth-rate-map" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The final visualization maps average annual growth rates across all states
using a color gradient, with vertical markers for California and Texas. The
horizontal color bar provides context for the growth spectrum from highest
growth to population loss.&lt;/p&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id9"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;Gradient colormap visualization&lt;/span&gt;&lt;a class="headerlink" href="#id9" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="n"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;green&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;yellow&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;&lt;span class="n"&gt;cmap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LinearSegmentedColormap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mycmap&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;average_annual_rate_of_change_sorted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yaxis&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_major_formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FuncFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percent_formatter&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;&lt;span class="n"&gt;bars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;    &lt;span class="n"&gt;average_annual_rate_of_change_sorted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;    &lt;span class="n"&gt;average_annual_rate_of_change_sorted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;    &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;average_annual_rate_of_change_sorted&lt;/span&gt;&lt;span class="p"&gt;))],&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;    &lt;span class="n"&gt;zorder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# hide grid behind bars&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gca&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;California&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Texas&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;    &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;average_annual_rate_of_change_sorted&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_loc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;    &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_x&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_width&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="linenos"&gt;17&lt;/span&gt;    &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;axvline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;red&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linestyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;--&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;linewidth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;18&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Average Annual Rate of Change in Population for All States&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;19&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;State&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;20&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Average Annual Rate of Change (%)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;21&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xticks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;22&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zorder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# hide grid behind bars&lt;/span&gt;
&lt;span class="linenos"&gt;23&lt;/span&gt;&lt;span class="n"&gt;sm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ScalarMappable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cmap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;24&lt;/span&gt;&lt;span class="n"&gt;sm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_array&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="linenos"&gt;25&lt;/span&gt;&lt;span class="n"&gt;sm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_clim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;average_annual_rate_of_change_sorted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;26&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_axes&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;0.161&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.86&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.698&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="linenos"&gt;27&lt;/span&gt;&lt;span class="n"&gt;cbar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;colorbar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;horizontal&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;28&lt;/span&gt;&lt;span class="n"&gt;cbar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_ticks&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
&lt;span class="linenos"&gt;29&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Highest Growth&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;va&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;center&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;left&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;white&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontweight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;bold&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transAxes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;30&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Moderate Growth&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;va&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;center&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;center&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;black&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontweight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;bold&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transAxes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;31&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Loss&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;va&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;center&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ha&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;right&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;white&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontweight&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;bold&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cbar_ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transAxes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;32&lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;img alt="Average annual growth rate gradient map" class="align-center" src="../_images/gradient_plot.svg" /&gt;
&lt;p&gt;The full analysis including charts and findings is available in the Jupyter notebook:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference download internal" download="" href="../_downloads/8d4da87a3a967e212438f47b6bc8d8c5/PopulationAnalysis.ipynb"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;PopulationAnalysis.ipynb&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;a class="headerlink" href="#conclusion" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;In the end, this take-home took raw JSON and turned it into a clean CSV by
breaking it down into small, clear steps. That makes it simple to test and
audit, and gets you ready for the analysis. The practical approach-caching to
skip repeated API calls, clear key mappings, and straightforward validation-
shows good thinking and communication, not unnecessary complexity.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2025/interview_coding_take_homes_part_3.html"/><category term="Programming"/><category term="Software"/><category term="Interviewing"/><published>2025-12-15T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2025/interview_coding_take_homes_part_2b.html</id><title>Interview Coding Take-Homes: Part 2.b</title><updated>2025-08-28T23:26:51+00:00</updated><content>&lt;section id="interview-coding-take-homes-part-2-b"&gt;
&lt;h1&gt;Interview Coding Take-Homes: Part 2.b&lt;a class="headerlink" href="#interview-coding-take-homes-part-2-b" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2025-08-28"&gt;28 August 2025&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/interviewing.html"&gt;Interviewing&lt;/a&gt;&lt;/p&gt;
&lt;section id="ucla-health-terraform-module"&gt;
&lt;h2&gt;UCLA Health - Terraform Module&lt;a class="headerlink" href="#ucla-health-terraform-module" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This take-home was for a Senior Cloud DevOps Engineer position in a key IT organization at UCLA Health.&lt;/p&gt;
&lt;p&gt;This is part &lt;strong&gt;b&lt;/strong&gt; of a two-part take-home. Read the first part, &lt;a class="reference internal" href="interview_coding_take_homes_part_2a.html#interview-coding-take-homes-part-2-a"&gt;&lt;span class="std std-ref"&gt;Interview Coding Take-Homes: Part 2.a&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="prompt"&gt;
&lt;h2&gt;Prompt&lt;a class="headerlink" href="#prompt" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;You are a terraform developer building a new module to help with naming
resources deployed within the cloud environment. You will have two inputs
to this module identifying a “base_name” and “resource_type” with which
you will have to evaluate and generate a “resource_name” as an output.
The “resource_name” that you generate should follow these rules:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;You should setup the “resource_type” to only allow the values of
“virtual_machine”, “key_vault”, and “storage_account”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the resource_type is “virtual_machine” you should take the
“base_name” and append “vm-” to the front of it and “-00” to the back.
If the base name and and values you’re appending are greater than 15
characters you should truncate the “base_name” only in order to be 15
characters when combined with your additional characters. Note that the
base_name can be greater than 15 characters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the resource_type is “key_vault” you should append “kv-” to the
front of “base_name” and then set all characters to lower case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the resource_type is “storage_account” you should append “sa” to the
front of “base_name and then remove all “-” from the name and then set
all characters to lower case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should also build a secondary module that calls your naming module.
This parent module should intake a map which has the “base_name” as the
key and the “resource_type” as the value. It should present each
key/value pair in this map to your naming module.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Parent Module should reflect all the outputs of the child module
and allow for additional outputs if the child module outputs are
expanded in the future without further modification to the parent.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Please write these modules as you would for a production environment
following best practices and structure that makes it easy to share
with other team members and allows them to use it quickly after
receiving it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can reference the naming module either through a local path or a
github URL as long as the entire package can be run from a computer
with public internet access.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="my-approach"&gt;
&lt;h2&gt;My Approach&lt;a class="headerlink" href="#my-approach" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Whew - that’s a lot to read.&lt;/p&gt;
&lt;p&gt;Although I knew what Terraform is, my experience with it is very limited.
So first and foremost, I read the &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started"&gt;Get Started - AWS&lt;/a&gt;
tutorial. To avoid unintentionally incurring costs, I used &lt;a class="reference external" href="https://github.com/localstack/localstack"&gt;LocalStack&lt;/a&gt;
instead of AWS for my testing.&lt;/p&gt;
&lt;p&gt;After completing the tutorial, I relied heavily on the &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language"&gt;Terraform documentation&lt;/a&gt;
to complete the prompt.&lt;/p&gt;
&lt;p&gt;Here is the project structure I ended up with.&lt;/p&gt;
&lt;p class="plantuml"&gt;
&lt;object data="../_images/plantuml-8142d066f5d6ef7a3309d9c5d18f663e11f14c28.svg" type="image/svg+xml" style="width:183px;height:414px;background:#FFFFFF;"&gt;
&lt;img src="../_images/plantuml-8142d066f5d6ef7a3309d9c5d18f663e11f14c28.png" alt="&amp;#64;startfiles
/main.tf
/batch/
/batch/main.tf
/batch/variables.tf
/batch/outputs.tf
/naming/
/naming/main.tf
/naming/variables.tf
/naming/locals.tf
/naming/outputs.tf
/outputs.tf
/versions.tf
/terraform.tf
/tests/batch.tftest.hcl
/tests/naming.tftest.hcl
&amp;#64;endfiles"/&gt;

&lt;/object&gt;&lt;/p&gt;
&lt;p&gt;The specifics of these files is documented in &lt;a class="reference internal" href="_resource_name_mapper.html#resource-name-mapper"&gt;&lt;span class="std std-ref"&gt;Resource Name Mapper&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;section id="resource-type-constraints"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_type&lt;/span&gt;&lt;/code&gt; Constraints&lt;a class="headerlink" href="#resource-type-constraints" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;You should setup the “resource_type” to only allow the values of
“virtual_machine”, “key_vault”, and “storage_account”&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="literal-block-wrapper docutils container" id="id1"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/45aa8cde1c717768f02f31751c907d93/variables.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;naming/variables.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id1" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 6&lt;/span&gt;&lt;span class="kr"&gt;variable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;&amp;quot;resource_type&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Must be one of `virtual_machine`, `key_vault`, or `storage_account`.&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;validation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;virtual_machine&amp;quot;, &amp;quot;key_vault&amp;quot;, &amp;quot;storage_account&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;var.resource_type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;error_message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;`resource_type` must be one of `virtual_machine`, `key_vault`, or `storage_account`.&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This requirement uses an &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/values/variables"&gt;input variable&lt;/a&gt;
block that contains a &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/values/variables#custom-validation-rules"&gt;validation&lt;/a&gt;
block. The &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/functions/contains"&gt;contains(list, value)&lt;/a&gt;
function is used to constrain the input variable to the three acceptable values.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="base-name-and-resource-name-alterations"&gt;
&lt;h3&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;base_name&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_name&lt;/span&gt;&lt;/code&gt; Alterations&lt;a class="headerlink" href="#base-name-and-resource-name-alterations" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;If the resource_type is “virtual_machine” you should take the
“base_name” and append “vm-” to the front of it and “-00” to the back.
If the base name and and values you’re appending are greater than 15
characters you should truncate the “base_name” only in order to be 15
characters when combined with your additional characters. Note that the
base_name can be greater than 15 characters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the resource_type is “key_vault” you should append “kv-” to the
front of “base_name” and then set all characters to lower case.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the resource_type is “storage_account” you should append “sa” to the
front of “base_name and then remove all “-” from the name and then set
all characters to lower case.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="literal-block-wrapper docutils container" id="id2"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/b78de3d664cea340b4d4cf1a39b00398/locals.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;naming/locals.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id2" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;base_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;var.resource_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;virtual_machine&amp;quot; ? substr(var.base_name, 0, 15 - length(&amp;quot;vm-&amp;quot;) - length(&amp;quot;-00&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;var.resource_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;key_vault&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;var.base_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;5&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;var.base_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;-&amp;quot;, &amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="c1"&gt; # storage account&lt;/span&gt;
&lt;span class="linenos"&gt;6&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This requirement is handled by a lengthy &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/expressions/conditionals#conditional-expressions"&gt;conditional expression&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Line 3 is specific to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;virtual_machine&lt;/span&gt;&lt;/code&gt;’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;base_name&lt;/span&gt;&lt;/code&gt;. As the requirements
state, we truncate the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;base_name&lt;/span&gt;&lt;/code&gt; to 15 characters, minus the length of
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;vm-&lt;/span&gt;&lt;/code&gt; prefix and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;-00&lt;/span&gt;&lt;/code&gt; suffix we add to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_name&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;key_vault&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;storage_account&lt;/span&gt;&lt;/code&gt; are handled here as well.&lt;/p&gt;
&lt;div class="literal-block-wrapper docutils container" id="id3"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/b78de3d664cea340b4d4cf1a39b00398/locals.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;naming/locals.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id3" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;resource_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;var.resource_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;virtual_machine&amp;quot; ? &amp;quot;vm-${local.base_name}-00&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;var.resource_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;key_vault&amp;quot; ? &amp;quot;kv-${local.base_name}&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sa${local.base_name}&amp;quot;&lt;/span&gt;&lt;span class="c1"&gt; # storage account&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And here we use another conditional expression to add the prefix and suffix to
the resource names.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="secondary-module"&gt;
&lt;h3&gt;Secondary Module&lt;a class="headerlink" href="#secondary-module" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="arabic simple" start="5"&gt;
&lt;li&gt;&lt;p&gt;You should also build a secondary module that calls your naming module.
This parent module should intake a map which has the “base_name” as the
key and the “resource_type” as the value. It should present each
key/value pair in this map to your naming module.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;I’ve named this module &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch&lt;/span&gt;&lt;/code&gt; because it processes a “batch” of resources together.&lt;/p&gt;
&lt;div class="literal-block-wrapper docutils container" id="id4"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/84f23a82df98f8d92a46689de9ba8cbc/variables.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch/variables.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id4" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;1&lt;/span&gt;&lt;span class="kr"&gt;variable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;&amp;quot;resources&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;A map of base names and resource types.&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt; # {&amp;quot;app&amp;quot;:&amp;quot;virtual_machine&amp;quot;, &amp;quot;data&amp;quot;:&amp;quot;storage_account&amp;quot;, ...}&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The module takes the input &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resources&lt;/span&gt;&lt;/code&gt; as a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;string&lt;/span&gt;&lt;/code&gt; &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/functions/map"&gt;map&lt;/a&gt;.&lt;/p&gt;
&lt;div class="literal-block-wrapper docutils container" id="id5"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/f3e5f2bc7770befdc8d1d5fb938587f8/main.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch/main.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id5" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;1&lt;/span&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;&amp;quot;naming&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;for_each&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;var.resources&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;../naming&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;
&lt;span class="linenos"&gt;5&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;base_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;each.key&lt;/span&gt;
&lt;span class="linenos"&gt;6&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;resource_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;each.value&lt;/span&gt;
&lt;span class="linenos"&gt;7&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch&lt;/span&gt;&lt;/code&gt; module uses the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;naming&lt;/span&gt;&lt;/code&gt; module. From the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resources&lt;/span&gt;&lt;/code&gt;
input variable, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;base_name&lt;/span&gt;&lt;/code&gt; is set to its key, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_type&lt;/span&gt;&lt;/code&gt;
is set to its value.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;ol class="arabic simple" start="6"&gt;
&lt;li&gt;&lt;p&gt;The Parent Module should reflect all the outputs of the child module
and allow for additional outputs if the child module outputs are
expanded in the future without further modification to the parent.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="literal-block-wrapper docutils container" id="id6"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/55335c0a11c1e0e3013b27ca31a6e0eb/outputs.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch/outputs.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id6" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;1&lt;/span&gt;&lt;span class="kr"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;&amp;quot;resource_names&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;A map of base names to formatted resource names.&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;3&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;module.naming&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;v.resource_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The module sets the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;resource_names&lt;/span&gt;&lt;/code&gt; &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/values/outputs"&gt;output&lt;/a&gt;
variable as an &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/expressions/for#result-types"&gt;object&lt;/a&gt;
that reflects the outputs from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;naming&lt;/span&gt;&lt;/code&gt; module.&lt;/p&gt;
&lt;div class="literal-block-wrapper docutils container" id="id7"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/55335c0a11c1e0e3013b27ca31a6e0eb/outputs.tf"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch/outputs.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id7" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-tf notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;6&lt;/span&gt;&lt;span class="kr"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;&amp;quot;all_naming_outputs&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;7&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;module.naming&lt;/span&gt;
&lt;span class="linenos"&gt;8&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The requirement for “future” outputs wasn’t completely clear to me, so I
opted to just return all possible outputs from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;naming&lt;/span&gt;&lt;/code&gt; module.
This way, any new outputs added to that module will also output in the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;batch&lt;/span&gt;&lt;/code&gt; module as the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;all_naming_outputs&lt;/span&gt;&lt;/code&gt; output variable.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="production-quality"&gt;
&lt;h3&gt;Production Quality&lt;a class="headerlink" href="#production-quality" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;ol class="arabic simple" start="7"&gt;
&lt;li&gt;&lt;p&gt;Please write these modules as you would for a production environment
following best practices and structure that makes it easy to share
with other team members and allows them to use it quickly after
receiving it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;To the best of my knowledge, I followed Terraform’s best practices when
writing these modules, and the structure (the names of the files and their
contents) reflects what I found in their &lt;a class="reference external" href="https://developer.hashicorp.com/terraform/language/modules/develop/structure"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;section id="tests"&gt;
&lt;h4&gt;Tests&lt;a class="headerlink" href="#tests" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Of course, any production system needs tests. I added several tests for both modules.&lt;/p&gt;
&lt;p&gt;Their contents are truncated here, but you can download the files to see each test.&lt;/p&gt;
&lt;div class="literal-block-wrapper docutils container" id="id8"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/ca1dc9c0a4c507779e62d5cd580d8be5/batch.tftest.hcl"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;tests/batch.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id8" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-hcl notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;long_vm_name_is_truncated&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;plan&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;./batch&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;resources&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fooBARbaz-FOObarBAZ&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;virtual_machine&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;output.resource_names&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fooBARbaz-FOObarBAZ&amp;quot;] == &amp;quot;vm-fooBARbaz-00&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;error_message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;VM name is wrong&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;17&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="literal-block-wrapper docutils container" id="id9"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/ab0c08bf3e259972f43db3de5cd26e8b/naming.tftest.hcl"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;tests/naming.tf&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id9" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-hcl notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;resource_type_can_be_virtual_machine&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;plan&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;./naming&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;base_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;resource_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;virtual_machine&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;assert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;output.resource_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;vm-foo-00&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="na"&gt;error_message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;VM name is wrong&amp;quot;&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2025/interview_coding_take_homes_part_2b.html"/><category term="Programming"/><category term="Software"/><category term="Interviewing"/><published>2025-08-28T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2025/interview_coding_take_homes_part_2a.html</id><title>Interview Coding Take-Homes: Part 2.a</title><updated>2025-08-28T23:26:51+00:00</updated><content>&lt;section id="interview-coding-take-homes-part-2-a"&gt;
&lt;h1&gt;Interview Coding Take-Homes: Part 2.a&lt;a class="headerlink" href="#interview-coding-take-homes-part-2-a" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2025-08-18"&gt;18 August 2025&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/interviewing.html"&gt;Interviewing&lt;/a&gt;&lt;/p&gt;
&lt;section id="ucla-health-maze-bug"&gt;
&lt;h2&gt;UCLA Health - Maze Bug&lt;a class="headerlink" href="#ucla-health-maze-bug" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This take-home was for a Senior Cloud DevOps Engineer position in a key IT organization at UCLA Health.&lt;/p&gt;
&lt;p&gt;This is part &lt;strong&gt;a&lt;/strong&gt; of a two-part take-home. Read the second part, &lt;a class="reference internal" href="interview_coding_take_homes_part_2b.html#interview-coding-take-homes-part-2-b"&gt;&lt;span class="std std-ref"&gt;Interview Coding Take-Homes: Part 2.b&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="prompt"&gt;
&lt;h2&gt;Prompt&lt;a class="headerlink" href="#prompt" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;This is an intentionally incorrect python script to play through a maze. Can you spot the error and get it working?&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id1"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/13b72c4e8cd7bf8738a0abbf0a13042d/pymaze-broken.py"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;pymaze-broken.py&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id1" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;random&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="c1"&gt;# Maze dimensions&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&lt;span class="c1"&gt;# Maze symbols&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="n"&gt;WALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="n"&gt;EMPTY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="n"&gt;PLAYER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;P&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="n"&gt;EXIT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;E&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="n"&gt;ITEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="c1"&gt;# Function to initialize the maze&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;initialize_maze&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;EMPTY&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="linenos"&gt;17&lt;/span&gt;    &lt;span class="c1"&gt;# Place walls&lt;/span&gt;
&lt;span class="linenos"&gt;18&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;19&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;20&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;21&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;22&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;23&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;24&lt;/span&gt;    &lt;span class="c1"&gt;# Place player&lt;/span&gt;
&lt;span class="linenos"&gt;25&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;
&lt;span class="linenos"&gt;26&lt;/span&gt;    &lt;span class="c1"&gt;# Place exit&lt;/span&gt;
&lt;span class="linenos"&gt;27&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EXIT&lt;/span&gt;
&lt;span class="linenos"&gt;28&lt;/span&gt;    &lt;span class="c1"&gt;# Place items&lt;/span&gt;
&lt;span class="linenos"&gt;29&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Adjust the number of items as needed&lt;/span&gt;
&lt;span class="linenos"&gt;30&lt;/span&gt;        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;31&lt;/span&gt;            &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;32&lt;/span&gt;            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;33&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EMPTY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;34&lt;/span&gt;                &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ITEM&lt;/span&gt;
&lt;span class="linenos"&gt;35&lt;/span&gt;                &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="linenos"&gt;36&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;
&lt;span class="linenos"&gt;37&lt;/span&gt;
&lt;span class="linenos"&gt;38&lt;/span&gt;&lt;span class="c1"&gt;# Function to print the maze&lt;/span&gt;
&lt;span class="linenos"&gt;39&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;print_maze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;40&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;41&lt;/span&gt;        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;42&lt;/span&gt;
&lt;span class="linenos"&gt;43&lt;/span&gt;&lt;span class="c1"&gt;# Function to move the player&lt;/span&gt;
&lt;span class="linenos"&gt;44&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;45&lt;/span&gt;    &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;46&lt;/span&gt;    &lt;span class="n"&gt;new_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="linenos"&gt;47&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;48&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EMPTY&lt;/span&gt;
&lt;span class="linenos"&gt;49&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;
&lt;span class="linenos"&gt;50&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="linenos"&gt;51&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="linenos"&gt;52&lt;/span&gt;
&lt;span class="linenos"&gt;53&lt;/span&gt;&lt;span class="c1"&gt;# Function to find the player&amp;#39;s position&lt;/span&gt;
&lt;span class="linenos"&gt;54&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;55&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;span class="linenos"&gt;56&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])):&lt;/span&gt;
&lt;span class="linenos"&gt;57&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;58&lt;/span&gt;                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;59&lt;/span&gt;
&lt;span class="linenos"&gt;60&lt;/span&gt;&lt;span class="c1"&gt;# Main function to run the game&lt;/span&gt;
&lt;span class="linenos"&gt;61&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="linenos"&gt;62&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initialize_maze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;63&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Welcome to the maze game!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;64&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Use WASD to move. Try to find the exit (E) while collecting items (*)!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;65&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;66&lt;/span&gt;        &lt;span class="n"&gt;print_maze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;67&lt;/span&gt;        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Enter your move (WASD): &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;68&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;W&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;69&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;70&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;S&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;71&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;72&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;73&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;74&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;75&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;76&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;77&lt;/span&gt;            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Invalid move! Use WASD.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;78&lt;/span&gt;            &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="linenos"&gt;79&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;moved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;80&lt;/span&gt;            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Cannot move there! Try another direction.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;81&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;82&lt;/span&gt;            &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;83&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EXIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;84&lt;/span&gt;                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Congratulations! You found the exit!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;85&lt;/span&gt;                &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="linenos"&gt;86&lt;/span&gt;
&lt;span class="linenos"&gt;87&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;88&lt;/span&gt;    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/section&gt;
&lt;section id="my-approach"&gt;
&lt;h2&gt;My Approach&lt;a class="headerlink" href="#my-approach" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;section id="testing-the-application"&gt;
&lt;h3&gt;Testing the Application&lt;a class="headerlink" href="#testing-the-application" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First, I executed the code to see what it does and how it behaves.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ python pymaze-broken.py
Welcome to the maze game!
Use WASD to move. Try to find the exit (E) while collecting items (*)!
##########
#P       #
#        #
#        #
#  *     #
#*       #
# *      #
#        #
#       E#
##########
Enter your move (WASD):
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So far, so good.&lt;/p&gt;
&lt;p&gt;The code states to gather items and find the exit, so let’s do that.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;##########
#        #
#        #
#        #
#        #
#        #
#        #
#       P#
#       E#
##########
Enter your move (WASD):
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt; moves around, so that’s us, the player.&lt;/p&gt;
&lt;p&gt;Gathering items worked without issue, so let’s try to “find the exit.”&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Enter your move (WASD): s
##########
#        #
#        #
#        #
#        #
#        #
#        #
#        #
#       P#
##########
Enter your move (WASD):
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Uh oh … looks like the game doesn’t finish when the user finds the exit.&lt;/p&gt;
&lt;p&gt;In fact, we can keep moving around, but now the exit is gone.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Enter your move (WASD): w
##########
#        #
#        #
#        #
#        #
#        #
#        #
#       P#
#        #
##########
Enter your move (WASD):
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="examining-the-code"&gt;
&lt;h3&gt;Examining the Code&lt;a class="headerlink" href="#examining-the-code" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Next, I looked at parts of the code, starting from the application entrypoint.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;61&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="linenos"&gt;62&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initialize_maze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;63&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Welcome to the maze game!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;64&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Use WASD to move. Try to find the exit (E) while collecting items (*)!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;65&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;66&lt;/span&gt;        &lt;span class="n"&gt;print_maze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;67&lt;/span&gt;        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Enter your move (WASD): &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;68&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;W&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;69&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;70&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;S&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;71&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;72&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;73&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;74&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;75&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;76&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;77&lt;/span&gt;            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Invalid move! Use WASD.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;78&lt;/span&gt;            &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="linenos"&gt;79&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;moved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;80&lt;/span&gt;            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Cannot move there! Try another direction.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;81&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;82&lt;/span&gt;            &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;83&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EXIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;84&lt;/span&gt;                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Congratulations! You found the exit!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;85&lt;/span&gt;                &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We can see several calls to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;move_player&lt;/span&gt;&lt;/code&gt; in response to the WASD inputs,
and then a check for whether the player has moved onto the exit position.&lt;/p&gt;
&lt;p&gt;This last check seems to be what stops the main &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;while&lt;/span&gt;&lt;/code&gt; loop on line 65,
so we need to figure out what prevented that condition from triggering.
My intuition says we need to understand what &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;maze&lt;/span&gt;&lt;/code&gt; contains in order to
check whether this condition is correct.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;83&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EXIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;84&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Congratulations! You found the exit!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;85&lt;/span&gt;    &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="debugging"&gt;
&lt;h3&gt;Debugging&lt;a class="headerlink" href="#debugging" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Because this is new code I haven’t seen before, the most expedient next step is to run
the application in a &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Debugger"&gt;debugger&lt;/a&gt;. This way
I can see what &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;maze&lt;/span&gt;&lt;/code&gt; contains without needing to manually walk through the code.
This quickly gives me a mental map of what’s happening in the application.&lt;/p&gt;
&lt;p&gt;Python includes a debugger called &lt;a class="reference external" href="https://docs.python.org/3/library/pdb.html"&gt;pdb&lt;/a&gt;
that I will use for this. There are other tools, such as VSCode, but this application
is simple enough that we should be able to figure this out on the command line.&lt;/p&gt;
&lt;p&gt;We start &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/code&gt; with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;-m&lt;/span&gt; &lt;span class="pre"&gt;pdb&lt;/span&gt; &lt;span class="pre"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ python -m pdb pymaze-broken.py
&amp;gt; pymaze-broken.py(1)&amp;lt;module&amp;gt;()
-&amp;gt; import random
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It helps to get a quick reference of the commands available to us.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) ?

Documented commands (type help &amp;lt;topic&amp;gt;):
========================================
EOF    cl         disable     ignore    n        return  u          where
a      clear      display     interact  next     retval  unalias
alias  commands   down        j         p        run     undisplay
args   condition  enable      jump      pp       rv      unt
b      cont       exceptions  l         q        s       until
break  continue   exit        list      quit     source  up
bt     d          h           ll        r        step    w
c      debug      help        longlist  restart  tbreak  whatis

Miscellaneous help topics:
==========================
exec  pdb
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I know I want to see what &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;maze&lt;/span&gt;&lt;/code&gt; looks like,
so I will put a breakpoint right after that,
on line 63. Then, I will let the application
continue running.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) b 63
Breakpoint 1 at pymaze-broken.py:63
(Pdb) c
&amp;gt; pymaze-broken.py(63)main()
-&amp;gt; print(&amp;quot;Welcome to the maze game!&amp;quot;)
(Pdb) l
 58                     return (i, j)
 59
 60     # Main function to run the game
 61     def main():
 62         maze = initialize_maze()
 63 B-&amp;gt;     print(&amp;quot;Welcome to the maze game!&amp;quot;)
 64         print(&amp;quot;Use WASD to move. Try to find the exit (E) while collecting items (*)!&amp;quot;)
 65         while True:
 66             print_maze(maze)
 67             direction = input(&amp;quot;Enter your move (WASD): &amp;quot;).upper()
 68             if direction == &amp;#39;W&amp;#39;:
(Pdb)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If we type a variable’s name, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/code&gt; prints its
string representation.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) maze
[[&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39;P&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;E&amp;#39;, &amp;#39;#&amp;#39;], [&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;]]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Fortunately for us, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;maze&lt;/span&gt;&lt;/code&gt; is a list and we don’t need to do anything fancy to see its contents.&lt;/p&gt;
&lt;p&gt;That said, it is nearly unparseable in a single line, so we can tell &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/code&gt; to “pretty print” the
objet instead.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) pp maze
[[&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39;P&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;E&amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;]]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So we know we’re looking at a matrix whose values represent the different characters seen in the maze.
Given that we’re trying to figure out the comparison of the player position within the maze to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EXIT&lt;/span&gt;&lt;/code&gt;
variable, let’s check what some of these values are too.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) player_pos
*** NameError: name &amp;#39;player_pos&amp;#39; is not defined
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Oops - that didn’t work. Let’s see where &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;player_pos&lt;/span&gt;&lt;/code&gt; gets set. If we look back at the code,
we see that it gets set in both &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;move_player&lt;/span&gt;&lt;/code&gt; …&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;44&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;45&lt;/span&gt;    &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;46&lt;/span&gt;    &lt;span class="n"&gt;new_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="linenos"&gt;47&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;48&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EMPTY&lt;/span&gt;
&lt;span class="linenos"&gt;49&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;
&lt;span class="linenos"&gt;50&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="linenos"&gt;51&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and in the main loop …&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;79&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;moved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;80&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Cannot move there! Try another direction.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;81&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;82&lt;/span&gt;    &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In Python, block-level assignments in methods are scoped to
those methods, so we know that the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;move_player&lt;/span&gt;&lt;/code&gt; assignment
is irrelevant here, which means we need line 82 to run.&lt;/p&gt;
&lt;p&gt;Let’s put a breakpoint there and step through the code.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) b 82
Breakpoint 2 at pymaze-broken.py:82
(Pdb) c
Welcome to the maze game!
Use WASD to move. Try to find the exit (E) while collecting items (*)!
##########
#P       #
#     *  #
#        #
#        #
#*       #
#    *   #
#        #
#       E#
##########
Enter your move (WASD):
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now it can get a little tricky to manage both the application
flow and the debugger. My command line input will currently be
sent to the application, not the debugger, because the application
is reading from STDIN.&lt;/p&gt;
&lt;p&gt;Here’s what happens when I enter input into the application.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Enter your move (WASD): d
&amp;gt; pymaze-broken.py(82)main()
-&amp;gt; player_pos = find_player(maze)
(Pdb)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We hit the breakpoint we set earlier! The application is now
paused again, and we can input into the debugger.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) l
 77                 print(&amp;quot;Invalid move! Use WASD.&amp;quot;)
 78                 continue
 79             if not moved:
 80                 print(&amp;quot;Cannot move there! Try another direction.&amp;quot;)
 81             else:
 82 B-&amp;gt;             player_pos = find_player(maze)
 83                 if maze[player_pos[0]][player_pos[1]] == EXIT:
 84                     print(&amp;quot;Congratulations! You found the exit!&amp;quot;)
 85                     break
 86
 87     if __name__ == &amp;quot;__main__&amp;quot;:
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We want to see what &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;find_player&lt;/span&gt;&lt;/code&gt; is doing, so let’s “step into” it.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) s
--Call--
&amp;gt; pymaze-broken.py(54)find_player()
-&amp;gt; def find_player(maze):
(Pdb) n
&amp;gt; pymaze-broken.py(55)find_player()
-&amp;gt; for i in range(len(maze)):
(Pdb) l
 50             return True
 51         return False
 52
 53     # Function to find the player&amp;#39;s position
 54     def find_player(maze):
 55  -&amp;gt;     for i in range(len(maze)):
 56             for j in range(len(maze[i])):
 57                 if maze[i][j] == PLAYER:
 58                     return (i, j)
 59
 60     # Main function to run the game
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I also stepped to the “next” instruction, so we’re now at the
beginning of the outer &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/code&gt; loop. Let’s see what some of these
instructions are doing.&lt;/p&gt;
&lt;p&gt;Given that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;maze&lt;/span&gt;&lt;/code&gt; is a matrix, it seems like the outer &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/code&gt;
loop will iterate over rows. Let’s make sure.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) list(range(len(maze)))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That looks right - there are ten rows in the maze. Let’s step
into the first iteration, and double-check whether the inner
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;for&lt;/span&gt;&lt;/code&gt; loop iterates over columns.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) s
&amp;gt; pymaze-broken.py(56)find_player()
-&amp;gt; for j in range(len(maze[i])):
(Pdb) list(range(len(maze[i])))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;That also looks right - there are ten columns for the row &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;i&lt;/span&gt;&lt;/code&gt;,
which is currently row &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;0&lt;/span&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) i
0
(Pdb) maze[i]
[&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Let’s step into this and check the next instructions.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) s
&amp;gt; pymaze-broken.py(57)find_player()
-&amp;gt; if maze[i][j] == PLAYER:
(Pdb) i
0
(Pdb) !j # we need a preceeding `!` because `j` is the pdb &amp;quot;jump&amp;quot; command
0
(Pdb) maze[i][j]
&amp;#39;#&amp;#39;
(Pdb) PLAYER
&amp;#39;P&amp;#39;
(Pdb) maze[i][j] == PLAYER
False
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So it seems that we’re iterating over every character in the maze
to determine whether that character is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt;. If the character is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt;
then we know we’ve found the player, and we return their (i,j) position.&lt;/p&gt;
&lt;p&gt;Let’s make sure - we’ll set a breakpoint at the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;return&lt;/span&gt;&lt;/code&gt; statement.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) b 58
Breakpoint 3 at pymaze-broken.py:58
(Pdb) c
&amp;gt; pymaze-broken.py(58)find_player()
-&amp;gt; return (i, j)
(Pdb) (i, j)
(1, 2)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If we print the maze again, we’ll see that (1, 2) is indeed where the
character &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt; is.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) pp maze
[[&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39;P&amp;#39;,
# truncated
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We should also note that the position the player &lt;cite&gt;was&lt;/cite&gt; in is now
a space, while the position that the player &lt;cite&gt;now&lt;/cite&gt; occupies was a space
and is now a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By now we can start to postulate on the behavior and the possible
origin of the error.&lt;/p&gt;
&lt;p&gt;We know, in the UI:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;When the player reaches &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt;, the application does not exit&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The player can continue to move around, and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt; disappears&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And in the code:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Previous player positions are replaced with a space&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current player position is replaced with a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some value is compared with the variable &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EXIT&lt;/span&gt;&lt;/code&gt; (the character &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Is it possible that we want to compare &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt; with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt;, but we can’t
because &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt; is now gone?&lt;/p&gt;
&lt;p&gt;Let’s continue on to our exit condition.&lt;/p&gt;
&lt;p&gt;To save us some sanity, let’s clear all the breakpoints.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) b
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at pymaze-broken.py:63
        breakpoint already hit 1 time
2   breakpoint   keep yes   at pymaze-broken.py:82
        breakpoint already hit 7 times
3   breakpoint   keep yes   at pymaze-broken.py:58
        breakpoint already hit 5 times
(Pdb) cl 1
Deleted breakpoint 1 at pymaze-broken.py:63
(Pdb) cl 2
Deleted breakpoint 1 at pymaze-broken.py:82
(Pdb) cl 3
Deleted breakpoint 3 at pymaze-broken.py:58
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We need to get the character to the final position before the exit,
then we add that breakpoint. We know we can do this because the application
pauses for our input anyway.&lt;/p&gt;
&lt;p&gt;Once the character is where we need it, press &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;^C&lt;/span&gt;&lt;/code&gt; to switch input
from the application back to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/code&gt;, then press &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;enter&lt;/span&gt;&lt;/code&gt; once. This lets us issue commands to
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/code&gt; again.&lt;/p&gt;
&lt;p&gt;Add the breakpoint back to line 82, continue execution, and move the player
onto the exit.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Enter your move (WASD): s
##########
#        #
#     *  #
#        #
#        #
#*       #
#    *   #
#       P#
#       E#
##########
Enter your move (WASD):
Program interrupted. (Use &amp;#39;cont&amp;#39; to resume).

&amp;gt; pymaze-broken.py(67)main()
-&amp;gt; direction = input(&amp;quot;Enter your move (WASD): &amp;quot;).upper()
(Pdb) b 82
Breakpoint 5 at pymaze-broken.py:82
(Pdb) c
Invalid move! Use WASD.
##########
#      * #
#        #
#        #
#        #
#        #
# *      #
#       P#
#       E#
##########
Enter your move (WASD): s
&amp;gt; pymaze-broken.py(82)main()
-&amp;gt; player_pos = find_player(maze)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Let’s check &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;player_pos&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) n
&amp;gt; pymaze-broken.py(83)main()
-&amp;gt; if maze[player_pos[0]][player_pos[1]] == EXIT:
(Pdb) player_pos
(8, 8)
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Is that right?&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) pp maze
[[&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39;*&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39; &amp;#39;, &amp;#39;P&amp;#39;, &amp;#39;#&amp;#39;],
 [&amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;, &amp;#39;#&amp;#39;]]
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It is … but the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt; has been replaced with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt;! In fact,
where we expected to check whether the player was on the exit,
it turns out we’ve been checking whether the player position
is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt; this whole time, which it always is!&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;(Pdb) maze[player_pos[0]][player_pos[1]]
&amp;#39;P&amp;#39;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So that’s our error - we always check the character at the current
player position after the player has moved, which means it is always
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;P&lt;/span&gt;&lt;/code&gt;, and therefore never &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;E&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="my-solution"&gt;
&lt;h3&gt;My Solution&lt;a class="headerlink" href="#my-solution" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class='scrollable' /&gt;&lt;div class="docutils container"&gt;
&lt;div class="literal-block-wrapper docutils container" id="id2"&gt;
&lt;div class="code-block-caption"&gt;&lt;span class="caption-text"&gt;&lt;a class="reference download internal" download="" href="../_downloads/8b6c36b30ff85de8d383746152dd841a/pymaze-working.py"&gt;&lt;code class="xref download docutils literal notranslate"&gt;&lt;span class="pre"&gt;pymaze-working.py&lt;/span&gt;&lt;/code&gt;&lt;/a&gt;&lt;/span&gt;&lt;a class="headerlink" href="#id2" title="Link to this code"&gt;#&lt;/a&gt;&lt;/div&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt; 1&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;random&lt;/span&gt;
&lt;span class="linenos"&gt; 2&lt;/span&gt;
&lt;span class="linenos"&gt; 3&lt;/span&gt;&lt;span class="c1"&gt;# Maze dimensions&lt;/span&gt;
&lt;span class="linenos"&gt; 4&lt;/span&gt;&lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="linenos"&gt; 5&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="linenos"&gt; 6&lt;/span&gt;
&lt;span class="linenos"&gt; 7&lt;/span&gt;&lt;span class="c1"&gt;# Maze symbols&lt;/span&gt;
&lt;span class="linenos"&gt; 8&lt;/span&gt;&lt;span class="n"&gt;WALL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt; 9&lt;/span&gt;&lt;span class="n"&gt;EMPTY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;10&lt;/span&gt;&lt;span class="n"&gt;PLAYER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;P&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;11&lt;/span&gt;&lt;span class="n"&gt;EXIT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;E&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;12&lt;/span&gt;&lt;span class="n"&gt;ITEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;
&lt;span class="linenos"&gt;13&lt;/span&gt;
&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="n"&gt;EXIT_POS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;15&lt;/span&gt;
&lt;span class="linenos"&gt;16&lt;/span&gt;&lt;span class="c1"&gt;# Function to initialize the maze&lt;/span&gt;
&lt;span class="linenos"&gt;17&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;initialize_maze&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="linenos"&gt;18&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;EMPTY&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="linenos"&gt;19&lt;/span&gt;    &lt;span class="c1"&gt;# Place walls&lt;/span&gt;
&lt;span class="linenos"&gt;20&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;21&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;22&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;23&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;24&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;25&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;
&lt;span class="linenos"&gt;26&lt;/span&gt;    &lt;span class="c1"&gt;# Place player&lt;/span&gt;
&lt;span class="linenos"&gt;27&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;
&lt;span class="linenos"&gt;28&lt;/span&gt;    &lt;span class="c1"&gt;# Place exit&lt;/span&gt;
&lt;span class="linenos"&gt;29&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EXIT_POS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;EXIT_POS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EXIT&lt;/span&gt;
&lt;span class="linenos"&gt;30&lt;/span&gt;    &lt;span class="c1"&gt;# Place items&lt;/span&gt;
&lt;span class="linenos"&gt;31&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Adjust the number of items as needed&lt;/span&gt;
&lt;span class="linenos"&gt;32&lt;/span&gt;        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;33&lt;/span&gt;            &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;34&lt;/span&gt;            &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;35&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EMPTY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;36&lt;/span&gt;                &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ITEM&lt;/span&gt;
&lt;span class="linenos"&gt;37&lt;/span&gt;                &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="linenos"&gt;38&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;
&lt;span class="linenos"&gt;39&lt;/span&gt;
&lt;span class="linenos"&gt;40&lt;/span&gt;&lt;span class="c1"&gt;# Function to print the maze&lt;/span&gt;
&lt;span class="linenos"&gt;41&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;print_maze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;42&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;43&lt;/span&gt;        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;44&lt;/span&gt;
&lt;span class="linenos"&gt;45&lt;/span&gt;&lt;span class="c1"&gt;# Function to move the player&lt;/span&gt;
&lt;span class="linenos"&gt;46&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;47&lt;/span&gt;    &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;48&lt;/span&gt;    &lt;span class="n"&gt;new_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="linenos"&gt;49&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;WALL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;50&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;player_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EMPTY&lt;/span&gt;
&lt;span class="linenos"&gt;51&lt;/span&gt;        &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;new_pos&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;
&lt;span class="linenos"&gt;52&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="linenos"&gt;53&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="linenos"&gt;54&lt;/span&gt;
&lt;span class="linenos"&gt;55&lt;/span&gt;&lt;span class="c1"&gt;# Function to find the player&amp;#39;s position&lt;/span&gt;
&lt;span class="linenos"&gt;56&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="linenos"&gt;57&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;span class="linenos"&gt;58&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])):&lt;/span&gt;
&lt;span class="linenos"&gt;59&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;PLAYER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;60&lt;/span&gt;                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;61&lt;/span&gt;
&lt;span class="linenos"&gt;62&lt;/span&gt;&lt;span class="c1"&gt;# Main function to run the game&lt;/span&gt;
&lt;span class="linenos"&gt;63&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;span class="linenos"&gt;64&lt;/span&gt;    &lt;span class="n"&gt;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initialize_maze&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;65&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Welcome to the maze game!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;66&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Use WASD to move. Try to find the exit (E) while collecting items (*)!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;67&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;68&lt;/span&gt;        &lt;span class="n"&gt;print_maze&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;69&lt;/span&gt;        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Enter your move (WASD): &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="linenos"&gt;70&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;W&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;71&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;72&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;S&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;73&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;74&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;75&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;76&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;D&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;77&lt;/span&gt;            &lt;span class="n"&gt;moved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;move_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="linenos"&gt;78&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;79&lt;/span&gt;            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Invalid move! Use WASD.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;80&lt;/span&gt;            &lt;span class="k"&gt;continue&lt;/span&gt;
&lt;span class="linenos"&gt;81&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;moved&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;82&lt;/span&gt;            &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Cannot move there! Try another direction.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;83&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;84&lt;/span&gt;            &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;85&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EXIT_POS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;86&lt;/span&gt;                &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Congratulations! You found the exit!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="linenos"&gt;87&lt;/span&gt;                &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="linenos"&gt;88&lt;/span&gt;
&lt;span class="linenos"&gt;89&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="linenos"&gt;90&lt;/span&gt;    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;My solution checks the player’s position against the known exit position,
rather than the &lt;cite&gt;characters&lt;/cite&gt; at those positions.&lt;/p&gt;
&lt;p&gt;This means we set up a variable to hold that position.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;14&lt;/span&gt;&lt;span class="n"&gt;EXIT_POS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MAZE_HEIGHT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAZE_WIDTH&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Which we use to replace line 29 in the broken code to set up the maze.
This reduces code duplication and eases future maintenance.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;29&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;EXIT_POS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]][&lt;/span&gt;&lt;span class="n"&gt;EXIT_POS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EXIT&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Which is then used to make the final exit condition.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="linenos"&gt;85&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;player_pos&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EXIT_POS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here is a full diff between the two files.&lt;/p&gt;
&lt;div class="highlight-udiff notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gd"&gt;--- /home/runner/work/aaronholmes.net/aaronholmes.net/source/_static/files/2025/interview_coding_take_homes_part_2a/pymaze-broken.py&lt;/span&gt;
&lt;span class="gi"&gt;+++ /home/runner/work/aaronholmes.net/aaronholmes.net/source/_static/files/2025/interview_coding_take_homes_part_2a/pymaze-working.py&lt;/span&gt;
&lt;span class="gu"&gt;@@ -10,6 +10,8 @@&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;PLAYER = &amp;#39;P&amp;#39;
&lt;span class="w"&gt; &lt;/span&gt;EXIT = &amp;#39;E&amp;#39;
&lt;span class="w"&gt; &lt;/span&gt;ITEM = &amp;#39;*&amp;#39;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+EXIT_POS = (MAZE_HEIGHT - 2, MAZE_WIDTH - 2)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;# Function to initialize the maze
&lt;span class="w"&gt; &lt;/span&gt;def initialize_maze():
&lt;span class="gu"&gt;@@ -24,7 +26,7 @@&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    # Place player
&lt;span class="w"&gt; &lt;/span&gt;    maze[1][1] = PLAYER
&lt;span class="w"&gt; &lt;/span&gt;    # Place exit
&lt;span class="gd"&gt;-    maze[MAZE_HEIGHT - 2][MAZE_WIDTH - 2] = EXIT&lt;/span&gt;
&lt;span class="gi"&gt;+    maze[EXIT_POS[0]][EXIT_POS[1]] = EXIT&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    # Place items
&lt;span class="w"&gt; &lt;/span&gt;    for _ in range(3):  # Adjust the number of items as needed
&lt;span class="w"&gt; &lt;/span&gt;        while True:
&lt;span class="gu"&gt;@@ -80,7 +82,7 @@&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;            print(&amp;quot;Cannot move there! Try another direction.&amp;quot;)
&lt;span class="w"&gt; &lt;/span&gt;        else:
&lt;span class="w"&gt; &lt;/span&gt;            player_pos = find_player(maze)
&lt;span class="gd"&gt;-            if maze[player_pos[0]][player_pos[1]] == EXIT:&lt;/span&gt;
&lt;span class="gi"&gt;+            if player_pos == EXIT_POS:&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;                print(&amp;quot;Congratulations! You found the exit!&amp;quot;)
&lt;span class="w"&gt; &lt;/span&gt;                break
&lt;span class="w"&gt; &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2025/interview_coding_take_homes_part_2a.html"/><category term="Programming"/><category term="Software"/><category term="Interviewing"/><published>2025-08-18T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2025/interview_coding_take_homes_part_1.html</id><title>Interview Coding Take-Homes: Part 1</title><updated>2025-08-11T17:33:16+00:00</updated><content>&lt;section id="interview-coding-take-homes-part-1"&gt;
&lt;h1&gt;Interview Coding Take-Homes: Part 1&lt;a class="headerlink" href="#interview-coding-take-homes-part-1" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2025-08-03"&gt;3 August 2025&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/interviewing.html"&gt;Interviewing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As software engineers, we are frequently asked to demonstrate our ability to
architect and implement software. Sometimes this is done through algorithm and
data structure live-coding interviews, sometimes through take-home assignments,
often both, or through other means.&lt;/p&gt;
&lt;p&gt;I have been given a number of take-home assignments, which I usually focus on
polishing and treating like production-grade software (within reason).
The downside of this focus is the energy it can take - which is compounded
when actively looking for new work.&lt;/p&gt;
&lt;p&gt;To that end, I would like to showcase my past take-homes, which demonstrate
my ability to architect and write software.&lt;/p&gt;
&lt;section id="ucla-health-data-corruption"&gt;
&lt;h2&gt;UCLA Health - Data Corruption&lt;a class="headerlink" href="#ucla-health-data-corruption" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This take-home was for a Senior Software Engineer position in a research lab
at UCLA Health. You can find the full repository &lt;a class="reference external" href="https://github.com/aholmes/2020-InterviewRound3"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="prompt"&gt;
&lt;h2&gt;Prompt&lt;a class="headerlink" href="#prompt" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is the prompt provided by UCLA Health.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;Your local grocery store, Half Foods, have been encountering issues with
their system and needs you to help process some of their data. Every time
a customer makes a purchase, a text file is generated, containing the
barcodes of each product they bought as well as other information. A
sample file CustomerG.txt is as follows:&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="mi"&gt;01232020&lt;/span&gt;&lt;span class="n"&gt;Jamie&lt;/span&gt;
&lt;span class="n"&gt;BEVGTTKYGDGJHGTFBNGDVZJGDIPXVS&lt;/span&gt;
&lt;span class="n"&gt;CANFDNSKAVOUXSCGSYBHQYHNMDQOBL&lt;/span&gt;
&lt;span class="n"&gt;FRZNQQNPSESCHIMIXOUHNAWLXRZEPT&lt;/span&gt;
&lt;span class="n"&gt;BEVGZYUFGNIHDCZIPWLZJLPDSGNEAH&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;The first line includes the date (MMDDYYYY) as well as the customer
information. Each line following that is an item barcode, in no particular
order.&lt;/p&gt;
&lt;p&gt;The barcode can be broken down into these components:&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Subtype&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;Unique&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;BEVG&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;TTKYGD&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;GJHGTFBNGDVZJGDIPXVS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;The product type is always 4 letters long, the subtype is 6 letters long, and
the unique id is 20 letters long.&lt;/p&gt;
&lt;p&gt;You are also provided a product type key:
BEVG - Beverages
BAKE - Baked Goods
CANF - Canned Foods
CNSB - Condiments/Spices/Baking
SNCN - Snacks/Candy
DREG - Dairy/Eggs
FRZN - Frozen Foods
FRVG - Fruits/Vegetables
GRPA - Grains/Pastas
MTSF - Meat/Seafood
MISC – Misc&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="my-approach-to-the-code"&gt;
&lt;h2&gt;My Approach to the Code&lt;a class="headerlink" href="#my-approach-to-the-code" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This application is a .NET Core Console application written in C#.&lt;/p&gt;
&lt;section id="structure"&gt;
&lt;h3&gt;Structure&lt;a class="headerlink" href="#structure" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The domain code is organized per &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Domain-driven_design"&gt;Domain-Driven Design&lt;/a&gt;
(DDD) principles and guidelines.&lt;/p&gt;
&lt;p&gt;Business logic is shared between the DDD classes and a set of classes I’ve
named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ConsoleWriter&lt;/span&gt;&lt;/code&gt;s.&lt;/p&gt;
&lt;section id="domain"&gt;
&lt;h4&gt;Domain&lt;a class="headerlink" href="#domain" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The domain of the application is broken down as follows.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="aggregates"&gt;
&lt;h4&gt;Aggregates&lt;a class="headerlink" href="#aggregates" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;An Aggregate called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseAggregate&lt;/span&gt;&lt;/code&gt; is responsible for processing
questions about a set of Purchases (a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseEntity&lt;/span&gt;&lt;/code&gt;) in a file.
For example, this Aggregate can return the most common Product purchases in a
file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="entities"&gt;
&lt;h4&gt;Entities&lt;a class="headerlink" href="#entities" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;An Entity called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseEntity&lt;/span&gt;&lt;/code&gt; contains information on the Purchase,
representing the entire Purchase file.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This Entity holds the Purchase date, Customer name, and the three parts of a
Product entry in a file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This Entity is able to construct itself from a file. It parses this file and
sets the appropriate properties.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No instance methods exist on this Entity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A Purchase is considered an Entity because every Purchase is unique regardless
of the data contained within that Purchase. For example—however unlikely it
may be—two Customers with the same name may buy the exact same Products at the
same time as another Customer.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="values"&gt;
&lt;h4&gt;Values&lt;a class="headerlink" href="#values" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A Value type exists for each of the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barcode (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BarcodeValue&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customer (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CustomerValue&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Product ID (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProductIdValue&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Product Type (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProductTypeValue&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Product Subtype (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProductSubtypeValue&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Timestamp (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;TimestampValue&lt;/span&gt;&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are considered Value types because, in relation to a Purchase, each Value
is equivalent based on its properties. For example, a Product ID of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;BEVG&amp;quot;&lt;/span&gt;&lt;/code&gt;
represents a Product ID of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;BEVG&amp;quot;&lt;/span&gt;&lt;/code&gt; regardless of how many &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;quot;BEVG&amp;quot;&lt;/span&gt;&lt;/code&gt; entries
there are for a Purchase.&lt;/p&gt;
&lt;p&gt;Review &lt;a class="reference external" href="/_static/files/2025/interview_coding_take_homes_part_1/classStructure.puml"&gt;classStructure.puml&lt;/a&gt; to understand the relations
between these types.&lt;/p&gt;
&lt;a class="reference external image-reference" href="/_static/images/2025/interview_coding_take_homes_part_1/classStructure.svg"&gt;&lt;img alt="../_images/classStructure.svg" src="../_images/classStructure.svg" /&gt;
&lt;/a&gt;
&lt;p&gt;With the exception of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BarcodeValue&lt;/span&gt;&lt;/code&gt;, these Value types extend
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ValueBase&amp;lt;T&amp;gt;&lt;/span&gt;&lt;/code&gt;. This is done to manage the code that determines equality
between instances of Value types.&lt;/p&gt;
&lt;p&gt;Each Value type overrides the default &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;==&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;!=&lt;/span&gt;&lt;/code&gt; operators in order to
equate their values &lt;em&gt;by value&lt;/em&gt; rather than each instance &lt;em&gt;by reference&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Each Value type implements implicit cast methods between &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;string&lt;/span&gt;&lt;/code&gt;
(except for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;TimestampValue&lt;/span&gt;&lt;/code&gt; whose &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;T&lt;/span&gt;&lt;/code&gt; type is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DateTime&lt;/span&gt;&lt;/code&gt;) simply for
ease of use in treating these value types as strings.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="business-logic"&gt;
&lt;h3&gt;Business logic&lt;a class="headerlink" href="#business-logic" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The business logic for this application is primarily contained within
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Program.cs&lt;/span&gt;&lt;/code&gt; (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Main&lt;/span&gt;&lt;/code&gt;), the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseAggregate&lt;/span&gt;&lt;/code&gt;, and the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseEntity&lt;/span&gt;&lt;/code&gt;
classes. The code is documented and should be reviewed for further
clarification.&lt;/p&gt;
&lt;p&gt;Some of the business logic is non-Domain and is thus managed outside the DDD
guidelines. In this case, the output of information about purchases is handled
in classes that I’ve named &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ConsoleWriter&lt;/span&gt;&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;These classes work using the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Visitor_pattern"&gt;Visitor Pattern&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this design, the Visitor visits a writer that handles unique output for each
of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseAggregate&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;PurchaseEntity&lt;/span&gt;&lt;/code&gt; types. The output of these
Dispatchers is returned and written to the console by the Visitor.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="searching"&gt;
&lt;h3&gt;Searching&lt;a class="headerlink" href="#searching" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In order to handle corrupted Purchase Type data, a BK Tree is implemented to
discover the closest-matching Product Type when inputting data, or when
outputting Product Subtypes for a Product Type.&lt;/p&gt;
&lt;p&gt;References used:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Levenshtein_distance"&gt;https://en.wikipedia.org/wiki/Levenshtein_distance&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.csharpstar.com/csharp-string-distance-algorithm"&gt;https://www.csharpstar.com/csharp-string-distance-algorithm&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://www.geeksforgeeks.org/bk-tree-introduction-implementation/"&gt;https://www.geeksforgeeks.org/bk-tree-introduction-implementation/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="http://blog.notdot.net/2007/4/Damn-Cool-Algorithms-Part-1-BK-Trees"&gt;http://blog.notdot.net/2007/4/Damn-Cool-Algorithms-Part-1-BK-Trees&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://nullwords.wordpress.com/2013/03/13/the-bk-tree-a-data-structure-for-spell-checking/"&gt;https://nullwords.wordpress.com/2013/03/13/the-bk-tree-a-data-structure-for-spell-checking/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-considerations"&gt;
&lt;h3&gt;Other Considerations&lt;a class="headerlink" href="#other-considerations" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As much as possible, this code was written to be easily unit-testable.
Accordingly, the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Adapter_pattern"&gt;Wrapper Pattern&lt;/a&gt;
is employed to avoid using the static &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Console&lt;/span&gt;&lt;/code&gt; class directly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="unit-tests"&gt;
&lt;h3&gt;Unit Tests&lt;a class="headerlink" href="#unit-tests" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The application is thoroughly unit tested. The tests run on the &lt;em&gt;xUnit&lt;/em&gt;
testing framework for .NET and C#.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="scenarios"&gt;
&lt;h2&gt;Scenarios&lt;a class="headerlink" href="#scenarios" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The prompt included several questions I needed to answer.&lt;/p&gt;
&lt;section id="question-1"&gt;
&lt;h3&gt;Question 1&lt;a class="headerlink" href="#question-1" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;Write a program that takes any customer text file, and prints the
following information to the console:&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Name of the customer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Formatted date of purchase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Total number of items they purchased&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Here is an example of the expected output, from my application.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Jamie&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="n"&gt;AM&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Total&lt;/span&gt; &lt;span class="n"&gt;Items&lt;/span&gt; &lt;span class="n"&gt;Purchased&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="question-2"&gt;
&lt;h3&gt;Question 2&lt;a class="headerlink" href="#question-2" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;section id="part-1"&gt;
&lt;h4&gt;Part 1&lt;a class="headerlink" href="#part-1" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Extend your program so that a grocery store employee can easily access more
detailed information about a purchase given the same customer text file input. It is up to you how you want organize and display this, but you should be able to print the following information:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;For every existing product type, the number and list of unique IDs of
items purchased by the customer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The most common product type&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Here is an example of the expected output.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="n"&gt;purchased&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt; &lt;span class="n"&gt;IDs&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;were&lt;/span&gt; &lt;span class="n"&gt;purchased&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;GJHGTFBNGDVZJGDIPXVS&lt;/span&gt;
    &lt;span class="n"&gt;OUXSCGSYBHQYHNMDQOBL&lt;/span&gt;
    &lt;span class="n"&gt;SCHIMIXOUHNAWLXRZEPT&lt;/span&gt;
    &lt;span class="n"&gt;IHDCZIPWLZJLPDSGNEAH&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;purchased&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BEVG&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="part-2"&gt;
&lt;h4&gt;Part 2&lt;a class="headerlink" href="#part-2" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h4&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;The employee should also be able to put in a specific product type input,
and get the following information:&lt;/p&gt;
&lt;ol class="loweralpha simple"&gt;
&lt;li&gt;&lt;p&gt;Subtypes for that product type&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In addition, make sure your design allows for new product types to be
added in the future, as the grocery store expands its inventory. Create a
function that can easily add a new product type with its code to the key,
without affecting your program’s functionality.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The application pauses to accept user input.&lt;/p&gt;
&lt;p&gt;The expected input is a 4-character Product Type code, e.g., “BEVG,” “MISC,” etc.&lt;/p&gt;
&lt;p&gt;The application will accept one character at a time, showing suggestions for
possible Product Types as the user types.&lt;/p&gt;
&lt;p&gt;When the 4th character is entered, the application will display the following
Product Subtype information for the best match of the user’s Product Type
input.&lt;/p&gt;
&lt;p&gt;If there are no matches, the application will let the user know.&lt;/p&gt;
&lt;p&gt;Here is an example of the expected output when the user types “BEVG”&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Question&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;Input&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;Subtypes&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;Purchase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Press&lt;/span&gt; &lt;span class="n"&gt;Enter&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="n"&gt;searching&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Possible&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# this outputs when &amp;quot;B&amp;quot; is typed&lt;/span&gt;
        &lt;span class="n"&gt;BEVG&lt;/span&gt;
        &lt;span class="n"&gt;BAKE&lt;/span&gt;
        &lt;span class="n"&gt;DREG&lt;/span&gt;
        &lt;span class="n"&gt;CANF&lt;/span&gt;
        &lt;span class="n"&gt;CNSB&lt;/span&gt;
        &lt;span class="n"&gt;SNCN&lt;/span&gt;
        &lt;span class="n"&gt;FRZN&lt;/span&gt;
        &lt;span class="n"&gt;GRPA&lt;/span&gt;
        &lt;span class="n"&gt;MISC&lt;/span&gt;
        &lt;span class="n"&gt;MTSF&lt;/span&gt;
        &lt;span class="n"&gt;FRVG&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Possible&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# this outputs when &amp;quot;E&amp;quot; is typed after the previous &amp;quot;B&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;BEVG&lt;/span&gt;
        &lt;span class="n"&gt;BAKE&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Possible&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# this outputs when &amp;quot;V&amp;quot; is typed after the previous &amp;quot;E&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;BEVG&lt;/span&gt;
 &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Possible&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# this outputs when &amp;quot;G&amp;quot; is typed after the previous &amp;quot;V&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;BEVG&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BEVG&lt;/span&gt;

&lt;span class="n"&gt;Searching&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;BEVG&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Subtypes&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;BEVG&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;TTKYGD&lt;/span&gt;
    &lt;span class="n"&gt;ZYUFGN&lt;/span&gt;

&lt;span class="n"&gt;Input&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;character&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;Subtypes&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;Purchase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Press&lt;/span&gt; &lt;span class="n"&gt;Enter&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;stop&lt;/span&gt; &lt;span class="n"&gt;searching&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Either way, &lt;a class="reference internal" href="#part-2"&gt;Part 2&lt;/a&gt; will repeat forever until the user presses Enter/Return.&lt;/p&gt;
&lt;p&gt;Once this occurs, the application prompts the user to press Enter/Return to exit.&lt;/p&gt;
&lt;p&gt;The application is finished after this.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="question-3"&gt;
&lt;h3&gt;Question 3&lt;a class="headerlink" href="#question-3" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;A problem arises with the Half Foods database, partially corrupting some
of the customer purchase data. Luckily, you managed to figure out that
the data only changed in a consistent way, making it possible to fix.&lt;/p&gt;
&lt;p&gt;The first line of each text file remained the same, but for some of the
barcodes, a random letter was changed somewhere in product type.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="mi"&gt;05242020&lt;/span&gt;&lt;span class="n"&gt;James&lt;/span&gt;
&lt;span class="n"&gt;FRZNQQNPSESCHIMIXOUHNAWLXRZEPT&lt;/span&gt;
&lt;span class="n"&gt;BENGTTKYGDGJHGTFBNGDVZJGDIPXVS&lt;/span&gt;
&lt;span class="n"&gt;CDNFDNSKAVOUXSCGSYBHQYHNMDQOBL&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;Extend your program and modify your answer for Question 2 to account for these errors.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;When the application first loads file data, it will ensure correct Product
Type keys are parsed. It will attempt to find the intended Product Type key
with the use of a BK Tree.&lt;/p&gt;
&lt;p&gt;When a match is found, or if the Product Type key is already correct, this
Product Type key is imported.&lt;/p&gt;
&lt;p&gt;This same functionality is used for &lt;a class="reference internal" href="#question-2"&gt;Question 2&lt;/a&gt; &lt;a class="reference internal" href="#part-2"&gt;Part 2&lt;/a&gt;, when the user types a
Product Key.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="question-4"&gt;
&lt;h3&gt;Question 4&lt;a class="headerlink" href="#question-4" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The repository also contains this &lt;a class="reference external" href="https://github.com/aholmes/2020-InterviewRound3/blob/main/docs/THEORY.md"&gt;question and answer&lt;/a&gt;.
I’ve repeated it here for posterity.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;If only some of the files in the customer purchase database are corrupt,
how would you address this problem going forward? What if the database
was extremely large? How do you prepare for future data corruptions?
Write a brief summary of your approach.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Fortunately, I read the entire project requirement before starting. As such,
I started with a unit test that tested these problems, and I developed the
application with these questions in mind. These problems are solved, and the
unit tests now pass.&lt;/p&gt;
&lt;p&gt;Let me address each question in order.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;If only some of the files in the customer purchase database are corrupt,
how would you address this problem going forward?&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This concern is moot. The application begins with importing purchase data and
validates against the corrupted data scenario (where Product Types can be
wrong by a single character). This validation does require additional cycles
and memory to complete, but in most cases should not be a problem.&lt;/p&gt;
&lt;p&gt;My approach: always validate; never assume the data is correct.&lt;/p&gt;
&lt;p&gt;One issue that may arrise is with huge data sets, but in reality, how many
customers will purchase the excessive number of products that would be
necessary to significantly slow down a BK Tree? Taking some measurements,
this list of &lt;a class="reference external" href="https://raw.githubusercontent.com/dwyl/english-words/7cb484d/words_alpha.txt"&gt;370k words&lt;/a&gt; is indexed in ~20 seconds, and can search a
worst-case scenario, e.g., “zwitterionic” in ~100ms.&lt;/p&gt;
&lt;p&gt;This approach is not a concern across multiple purchases either if the system
can be parallelized. More than one purchase can be analyzed at a time,
reducing the total processing time further.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;What if the database was extremely large?&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Generally, I would start with considering what is actually possible or
likely. As I started in the previous question, it is unlikely customers will
purchase an unbelievable number of products. This means the use of an
efficient text searching data structure and algorithm, like a BK Tree, should
never become a bottle neck. Hopefully the bottle neck is I/O (network, disk,
etc).&lt;/p&gt;
&lt;p&gt;If we are processing purchase data across many sets of purchases, this could
realistically be problematic. If we were, say, analyzing every purchase made at Amazon for its entire existence, that is a lot of data! In this case, I would rely on parallelization first. Multiple cores, multiple machines, or multiple cloud processing instances can give you the raw resources required to churn through so much data. If this is still insufficient, then it’s time to start looking at different algorithms, or perhaps using statistics and probabilities, and whether 100% accurate numbers are needed.&lt;/p&gt;
&lt;blockquote class="pull-quote"&gt;
&lt;div&gt;&lt;p&gt;How do you prepare for future data corruptions?&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Future data corruptions are handled the same - the application supports this
from the start. Now, if we are processing data that we have already processed
because it is now corrupt, then we need to devise a mechanism to relate the
corrupted data to the corrected data. In some cases, reprocessing like that
may be best to just start anew.&lt;/p&gt;
&lt;p&gt;If we can’t do that, having implemented some infrastructure that can help us
manage this data would be a good idea. For example, an SNS topic could be
used to respond immediately to a Product ID change in a purchase, which can
then be validated and reinserted, and you could receive notifications that
data is becoming corrupt and stop it before it gets out of hand.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2025/interview_coding_take_homes_part_1.html"/><category term="Programming"/><category term="Software"/><category term="Interviewing"/><published>2025-08-03T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2024/making_a_copper_wire_tree.html</id><title>Making a Copper Wire Tree</title><updated>2025-08-03T05:23:22+00:00</updated><content>&lt;section id="making-a-copper-wire-tree"&gt;
&lt;h1&gt;Making a Copper Wire Tree&lt;a class="headerlink" href="#making-a-copper-wire-tree" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2024-08-08"&gt;8 August 2024&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/plants.html"&gt;Plants&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/crafts.html"&gt;Crafts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This presentation shows the steps I took to create a wire tree out of copper wire in the shape of an informal upright bonsai.&lt;/p&gt;
&lt;iframe src="https://onedrive.live.com/embed?resid=744C91776BC2B37F%21514390&amp;amp;authkey=!AD5c8K9WFOGVuTM&amp;amp;em=2&amp;amp;wdAr=1.7777777777777777" width="100%" height="692px" frameborder="0"&gt;This is an embedded &lt;a target="_blank" href="https://office.com"&gt;Microsoft Office&lt;/a&gt; presentation, powered by &lt;a target="_blank" href="https://office.com/webapps"&gt;Office&lt;/a&gt;.&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2024/making_a_copper_wire_tree.html"/><category term="Plants"/><category term="Crafts"/><published>2024-08-08T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2022/winter_is_canning_2022.html</id><title>Winter is Canning 2022</title><updated>2025-08-03T05:23:22+00:00</updated><content>&lt;section id="winter-is-canning-2022"&gt;
&lt;h1&gt;Winter is Canning 2022&lt;a class="headerlink" href="#winter-is-canning-2022" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2022-09-22"&gt;22 September 2022&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This presentation shows the steps I took to prepare for this years 6-month long “Winter is Canning” challenge. Growers compete for the glory of winning the best looking pepper plant in a soda can.&lt;/p&gt;
&lt;iframe src="https://onedrive.live.com/embed?resid=744C91776BC2B37F%21332356&amp;amp;authkey=%21AOngVfr-Rvqqj68&amp;amp;em=2&amp;amp;wdAr=1.7777777777777777" width="100%" height="692px" frameborder="0"&gt;This is an embedded &lt;a target="_blank" href="https://office.com"&gt;Microsoft Office&lt;/a&gt; presentation, powered by &lt;a target="_blank" href="https://office.com/webapps"&gt;Office&lt;/a&gt;.&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2022/winter_is_canning_2022.html"/><category term="Programming"/><category term="Software"/><published>2022-09-22T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2022/pair_programming.html</id><title>Pair Programming</title><updated>2025-08-03T05:23:22+00:00</updated><content>&lt;section id="pair-programming"&gt;
&lt;h1&gt;Pair Programming&lt;a class="headerlink" href="#pair-programming" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2022-04-06"&gt;6 April 2022&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Why should you pair program, and how do you do it?&lt;/p&gt;
&lt;iframe src="https://onedrive.live.com/embed?cid=744C91776BC2B37F&amp;amp;resid=744C91776BC2B37F%21333587&amp;amp;authkey=AAgMa_K-F711c8M&amp;amp;em=2&amp;amp;wdAr=1.7777777777777777" width="100%" height="692px" frameborder="0"&gt;This is an embedded &lt;a target="_blank" href="https://office.com"&gt;Microsoft Office&lt;/a&gt; presentation, powered by &lt;a target="_blank" href="https://office.com/webapps"&gt;Office&lt;/a&gt;.&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2022/pair_programming.html"/><category term="Programming"/><category term="Software"/><published>2022-04-06T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2021/my_dog_cleo.html</id><title>My Dog Cleo</title><updated>2025-08-03T05:23:22+00:00</updated><content>&lt;section id="my-dog-cleo"&gt;
&lt;h1&gt;My Dog Cleo&lt;a class="headerlink" href="#my-dog-cleo" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2021-10-28"&gt;28 October 2021&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/dog.html"&gt;Dog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This presentation is about my Great Dane, Cleo. She has passed recently, after I created this presentation.&lt;/p&gt;
&lt;iframe src="https://onedrive.live.com/embed?cid=744C91776BC2B37F&amp;amp;resid=744C91776BC2B37F%21296656&amp;amp;authkey=ALnzF6F5yvTftR0&amp;amp;em=2&amp;amp;wdAr=1.7777777777777777" width="100%" height="692px" frameborder="0"&gt;This is an embedded &lt;a target="_blank" href="https://office.com"&gt;Microsoft Office&lt;/a&gt; presentation, powered by &lt;a target="_blank" href="https://office.com/webapps"&gt;Office&lt;/a&gt;.&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2021/my_dog_cleo.html"/><category term="Dog"/><published>2021-10-28T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2021/types_in_software.html</id><title>Types in Software</title><updated>2025-08-03T05:23:22+00:00</updated><content>&lt;section id="types-in-software"&gt;
&lt;h1&gt;Types in Software&lt;a class="headerlink" href="#types-in-software" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2021-04-21"&gt;21 April 2021&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/software.html"&gt;Software&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This presentation is about types in software, why they are important, and what they do to help us.&lt;/p&gt;
&lt;p&gt;The presentation source code is at this &lt;a class="reference external" href="https://github.com/aholmes/TypesInSoftware_Presentation"&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;iframe src="https://onedrive.live.com/embed?cid=744C91776BC2B37F&amp;amp;resid=744C91776BC2B37F%21293209&amp;amp;authkey=AA40T98XszKasq8&amp;amp;em=2&amp;amp;wdAr=1.7763888888888888" width="100%" height="692px" frameborder="0"&gt;This is an embedded &lt;a target="_blank" href="https://office.com"&gt;Microsoft Office&lt;/a&gt; presentation, powered by &lt;a target="_blank" href="https://office.com/webapps"&gt;Office&lt;/a&gt;.&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2021/types_in_software.html"/><category term="Programming"/><category term="Software"/><published>2021-04-21T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2019/displaying_response_headers_and_pretty_json_with_curl.html</id><title>Displaying response headers and pretty JSON with cURL</title><updated>2026-01-17T01:50:22+00:00</updated><content>&lt;section id="displaying-response-headers-and-pretty-json-with-curl"&gt;
&lt;h1&gt;Displaying response headers and pretty JSON with cURL&lt;a class="headerlink" href="#displaying-response-headers-and-pretty-json-with-curl" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2019-09-19"&gt;19 September 2019&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/http.html"&gt;HTTP&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/bash.html"&gt;Bash&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/curl.html"&gt;curl&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/utility.html"&gt;Utility&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/productivity.html"&gt;Productivity&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/shell.html"&gt;Shell&lt;/a&gt;&lt;/p&gt;
&lt;section id="the-problem"&gt;
&lt;h2&gt;The Problem&lt;a class="headerlink" href="#the-problem" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I tend toward using cURL when testing HTTP services, but I had a difficult
time parsing the result when these services spit back unformatted JSON
responses. To make my life a little easier, I set out to find a way to bend
cURL to my will.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-solution"&gt;
&lt;h2&gt;The Solution&lt;a class="headerlink" href="#the-solution" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s get straight to it. To make cURL display both response headers and
formatted JSON, we need to make cURL send the headers to STDERR, so we can
then send STDOUT to a formatting utility.&lt;/p&gt;
&lt;p&gt;We can accomplish this as so.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-D&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/dev/stderr&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;http://example.org/some/url&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&amp;gt;&lt;span class="w"&gt;       &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;@some-file&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;json.tool
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This will show a nicely formatted response like this.&lt;/p&gt;
&lt;div class="highlight-shell-session notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="go"&gt;HTTP/1.1 500 Internal Server Error&lt;/span&gt;
&lt;span class="go"&gt;Content-Type: application/json; charset=utf-8&lt;/span&gt;
&lt;span class="go"&gt;X-Powered-By: ASP.NET&lt;/span&gt;
&lt;span class="go"&gt;Date: Wed, 18 Sep 2019 22:39:24 GMT&lt;/span&gt;
&lt;span class="go"&gt;Content-Length: 114&lt;/span&gt;

&lt;span class="go"&gt;{&lt;/span&gt;
&lt;span class="go"&gt;    &amp;quot;Status&amp;quot;: 3,&lt;/span&gt;
&lt;span class="go"&gt;    &amp;quot;Timestamp&amp;quot;: &amp;quot;2019-09-18T22:39:24.1659165Z&amp;quot;,&lt;/span&gt;
&lt;span class="go"&gt;    &amp;quot;Error&amp;quot;: {&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;Code&amp;quot;: 1,&lt;/span&gt;
&lt;span class="go"&gt;        &amp;quot;Message&amp;quot;: &amp;quot;An error has occurred.&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;    }&lt;/span&gt;
&lt;span class="go"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="what-s-going-on-here"&gt;
&lt;h2&gt;What’s Going On Here?&lt;a class="headerlink" href="#what-s-going-on-here" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let’s break this down a bit.&lt;/p&gt;
&lt;p&gt;After some initial research into how to send the HTTP headers to STDERR,
I found &lt;a class="reference external" href="https://akrabat.com/pretty-print-curl-i/"&gt;this article&lt;/a&gt; that demonstrated
the use of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;-D&lt;/span&gt; &lt;span class="pre"&gt;&amp;quot;/dev/stderr&amp;quot;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Breaking the command down:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;-s&lt;/span&gt;&lt;/code&gt; will silence the statistics output of cURL&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;-D&lt;/span&gt; &lt;span class="pre"&gt;&amp;quot;/dev/stderr&amp;quot;&lt;/span&gt;&lt;/code&gt; will send the HTTP headers to STDERR&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;python&lt;/span&gt; &lt;span class="pre"&gt;-m&lt;/span&gt; &lt;span class="pre"&gt;json.tool&lt;/span&gt;&lt;/code&gt; receives STDOUT, which is the JSON response of my service&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The other options are specific to my service request, and are not relevant to the formatting&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; you can also pipe the cURL output to a utility like &lt;a class="reference external" href="https://stedolan.github.io/jq/"&gt;jq&lt;/a&gt;,
I just happen to use &lt;a class="reference external" href="https://docs.python.org/3/library/json.html"&gt;python -m json.tool&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="a-step-further"&gt;
&lt;h2&gt;A Step Further&lt;a class="headerlink" href="#a-step-further" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These commands and then be turned into Bash aliases and functions.&lt;/p&gt;
&lt;p&gt;I have this in my &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;~/.bashrc&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;curl-json&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;curl -s -D &amp;quot;/dev/stderr&amp;quot;&amp;#39;&lt;/span&gt;
curl-json-format&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;curl-json&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;json.tool
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now I can use this command!&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$&lt;span class="w"&gt; &lt;/span&gt;curl-json-format&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;http://example.org/some/url&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&amp;gt;&lt;span class="w"&gt;      &lt;/span&gt;--data-binary&lt;span class="w"&gt; &lt;/span&gt;@some-file&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;python&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;json.tool
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2019/displaying_response_headers_and_pretty_json_with_curl.html"/><category term="HTTP"/><category term="Bash"/><category term="curl"/><category term="Utility"/><category term="Productivity"/><category term="Shell"/><published>2019-09-19T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2018/the_behavior_of_csharp_nested_static_classes.html</id><title>The Behavior of C# Nested Static Classes</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="the-behavior-of-c-nested-static-classes"&gt;
&lt;h1&gt;The Behavior of C# Nested Static Classes&lt;a class="headerlink" href="#the-behavior-of-c-nested-static-classes" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2018-07-26"&gt;26 July 2018&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/c.html"&gt;C#&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/net.html"&gt;.NET&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/experimental.html"&gt;Experimental&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/documentation.html"&gt;Documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While working on a code review, I found a nested static class that I needed to verify the validity of. I had three questions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Does the CLR create new instances when the containing class is instantiated?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do the static class members retain the same values across all instances of the containing class?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Is the nested class truly static?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you’ll read below, it turns out the nesting of a static class is a bit of a red herring. If you write C# regularly, you already know how this works.&lt;/p&gt;
&lt;section id="check-the-documentation"&gt;
&lt;h2&gt;Check the Documentation&lt;a class="headerlink" href="#check-the-documentation" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Like any good dev, I checked the documentation first.&lt;/p&gt;
&lt;p&gt;The Microsoft C# docs for &lt;a class="reference external" href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members"&gt;Static Classes and Static Class Members&lt;/a&gt; states the following.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;As is the case with all class types, the type information for
a static class is loaded by the .NET Framework common language
runtime (CLR) when the program that references the class is
loaded. The program cannot specify exactly when the class is
loaded. &lt;strong&gt;However, it is guaranteed to be loaded and to have its
fields initialized and its static constructor called before&lt;/strong&gt;
the class is referenced for the first time in your program.
&lt;strong&gt;A static constructor is only called one time, and a static
class remains in memory for the lifetime of the application
domain&lt;/strong&gt; in which your program resides.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This is pretty clear on static class behavior, but I still wasn’t sure whether there were additional nuances regarding nested static classes. We can find more information in the documentation regarding &lt;a class="reference external" href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/nested-types"&gt;Nested Types&lt;/a&gt;, however, this documentation is missing any information about static classes.&lt;/p&gt;
&lt;/section&gt;
&lt;hr class="docutils" /&gt;
&lt;section id="solving-the-unknown"&gt;
&lt;h2&gt;Solving the Unknown&lt;a class="headerlink" href="#solving-the-unknown" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With my questions unanswered, and a desire to be certain in my code review, it was time to create a test case. Here’s the code I wrote.&lt;/p&gt;
&lt;p&gt;By the way, I typically use &lt;a class="reference external" href="https://roslynpad.net/"&gt;RoslynPad&lt;/a&gt; for one-off tests like this.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// Foo is the containing/outer class that is instantiated&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// OuterI is used to retrieve the value of the integer&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// parameter for the constructor&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OuterI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;OuterI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// BarI returns the value of the nested static&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// class&amp;#39;s value, which points to the containing&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// class&amp;#39;s OuterI property&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InnerI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// This is the nested static class being tested&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Bar&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// This is used to retrieve the containing class&amp;#39;s&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// value of the OuterI property, which is set by&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// an instance of Foo. Keep in mind, this is a value type,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// not a reference type, and this is a field,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// not a property.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;InnerI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OuterI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I then tested two scenarios.&lt;/p&gt;
&lt;p&gt;The first scenario observes what happens when 1+n &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Foo&lt;/span&gt;&lt;/code&gt; s are
instantiated, followed by printing the value of each instance’s
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BarI&lt;/span&gt;&lt;/code&gt; property.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The second scenario observes what happens when n+1 &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Foo&lt;/span&gt;&lt;/code&gt; s are
instantiated, then immediately followed by printing the value of
the instances &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BarI&lt;/span&gt;&lt;/code&gt; property.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;hr class="docutils" /&gt;
&lt;section id="a-challenger-appears"&gt;
&lt;h2&gt;A Challenger Appears!&lt;a class="headerlink" href="#a-challenger-appears" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Before reading further&lt;/strong&gt;, I’d like to offer you a challenge;
predict what happens in both scenario 1 and 2.&lt;/p&gt;
&lt;/section&gt;
&lt;hr class="docutils" /&gt;
&lt;section id="the-behavior-discovered"&gt;
&lt;h2&gt;The Behavior, Discovered&lt;a class="headerlink" href="#the-behavior-discovered" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Figured it out?&lt;/p&gt;
&lt;p&gt;The output of the first scenario is:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;4
4
4
4
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The output of the second scenario is:&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;1
1
1
1
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;While this may be surprising (the first scenario caught me off
guard), the behavior is explained in the &lt;a class="reference external" href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members"&gt;Static Classes and Static Class Members&lt;/a&gt;
documentation. Indeed, this line applies to all static classes.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;A static constructor is only called one time, and a static
class remains in memory for the lifetime of the application
domain in which your program resides.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="why-does-this-occur"&gt;
&lt;h2&gt;Why Does this Occur?&lt;a class="headerlink" href="#why-does-this-occur" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So with that in mind, what’s actually happening here? Let’s make
a couple changes to observe the application execution in both
scenarios.&lt;/p&gt;
&lt;p&gt;Add a static constructor to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Bar&lt;/span&gt;&lt;/code&gt;, and insert a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Console.WriteLine&lt;/span&gt;&lt;/code&gt;
statement.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Bar&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;initialized&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;InnerI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OuterI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then, for both scenario 1 and 2, insert new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Console.WriteLine&lt;/span&gt;&lt;/code&gt; statements
between each operation.&lt;/p&gt;
&lt;p&gt;Scenario 1&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;new 1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;new 2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;new 3&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;new 4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 3&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Scenario 2&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 3&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar 4&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;BarI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now, if we execute these scenarios, the application execution
flow becomes clear. The reason for the observed behavior is as
stated in the documentation. The static class is set up before
it is accessed, and it is initialized only one time.&lt;/p&gt;
&lt;p&gt;Scenario 1 outputs the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="line-block"&gt;
&lt;div class="line"&gt;new 1&lt;/div&gt;
&lt;div class="line"&gt;new 2&lt;/div&gt;
&lt;div class="line"&gt;new 3&lt;/div&gt;
&lt;div class="line"&gt;new 4&lt;/div&gt;
&lt;div class="line"&gt;bar 1&lt;/div&gt;
&lt;div class="line"&gt;&lt;em&gt;initialized (BarI is accessed for the first time, and the static class is initialized)&lt;/em&gt;&lt;/div&gt;
&lt;div class="line"&gt;4&lt;/div&gt;
&lt;div class="line"&gt;bar 2&lt;/div&gt;
&lt;div class="line"&gt;4&lt;/div&gt;
&lt;div class="line"&gt;bar 3&lt;/div&gt;
&lt;div class="line"&gt;4&lt;/div&gt;
&lt;div class="line"&gt;bar 4&lt;/div&gt;
&lt;div class="line"&gt;4&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Scenario 2 outputs the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;div class="line-block"&gt;
&lt;div class="line"&gt;bar 1&lt;/div&gt;
&lt;div class="line"&gt;&lt;em&gt;initialized (BarI is called for the first time, and the static class is initialized)&lt;/em&gt;&lt;/div&gt;
&lt;div class="line"&gt;1&lt;/div&gt;
&lt;div class="line"&gt;bar 2&lt;/div&gt;
&lt;div class="line"&gt;1&lt;/div&gt;
&lt;div class="line"&gt;bar 3&lt;/div&gt;
&lt;div class="line"&gt;1&lt;/div&gt;
&lt;div class="line"&gt;bar 4&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Now I am curious what the non-gaurantee of &lt;em&gt;when&lt;/em&gt; the static class
is initialized means in runtimes other than the CLR.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2018/the_behavior_of_csharp_nested_static_classes.html"/><category term="C#"/><category term=".NET"/><category term="Experimental"/><category term="Documentation"/><published>2018-07-26T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2017/transparent_video_in_all_browsers_from_cross_domain_sources.html</id><title>Transparent Video in all Browsers from Cross-Domain Sources</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="transparent-video-in-all-browsers-from-cross-domain-sources"&gt;
&lt;h1&gt;Transparent Video in all Browsers from Cross-Domain Sources&lt;a class="headerlink" href="#transparent-video-in-all-browsers-from-cross-domain-sources" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2017-01-06"&gt;6 January 2017&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/javascript.html"&gt;JavaScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/canvas.html"&gt;Canvas&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/experimental.html"&gt;Experimental&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/ajax.html"&gt;AJAX&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/xmlhttprequest.html"&gt;XMLHttpRequest&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/video.html"&gt;Video&lt;/a&gt;&lt;/p&gt;
&lt;section id="a-brief-history-of-time-cross-domain-transparent-video"&gt;
&lt;h2&gt;A brief history of &lt;span class="strike"&gt;time&lt;/span&gt; cross-domain transparent video&lt;a class="headerlink" href="#a-brief-history-of-time-cross-domain-transparent-video" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Transparent video is not a terribly new concept in web development,
however, because browsers do not support transparency in videos,
accomplishing this requires &lt;a class="reference external" href="http://www.sciencelifeny.com/transparency/transparency.html"&gt;a unique solution&lt;/a&gt;
that involves a canvas element and a video with a separate alpha
channel.&lt;/p&gt;
&lt;p&gt;This solution does actually work very well to work around the
limitation. There is a gotcha to be aware of when using video
sources from a different origin, however; drawing to the canvas
with data from a different origin “&lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image#What_is_a_tainted_canvas"&gt;taints&lt;/a&gt;”
the canvas. Once a canvas has been tainted, you are no longer able
to extract data from the canvas. This breaks the workaround for
transparent video, which relies on extracting the values of the
alpha channel stored in a canvas. Thankfully, this can be worked
around &lt;strong&gt;in most&lt;/strong&gt; browsers by configuring &lt;a class="reference external" href="http://enable-cors.org/"&gt;CORS&lt;/a&gt;
correctly and setting the &lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-crossorigin"&gt;crossorigin&lt;/a&gt;
attribute on the source video element.&lt;/p&gt;
&lt;/section&gt;
&lt;hr class="docutils" /&gt;
&lt;section id="where-this-fails"&gt;
&lt;h2&gt;Where this fails&lt;a class="headerlink" href="#where-this-fails" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Unfortunately, like many things in web development, the latest versions of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Safari&lt;/span&gt; &lt;span class="pre"&gt;9.0.2&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Internet&lt;/span&gt; &lt;span class="pre"&gt;Explorer&lt;/span&gt; &lt;span class="pre"&gt;11&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Edge&lt;/span&gt; &lt;span class="pre"&gt;25&lt;/span&gt;&lt;/code&gt; do not correctly honor the CORS configuration when cross-domain data is drawn to a canvas. This means there was no way to achieve transparent video in these three browsers unless the source video comes from the same origin.&lt;/p&gt;
&lt;p&gt;After a lot of research, I stumbled across this &lt;a class="reference external" href="http://stackoverflow.com/a/19734500"&gt;answer&lt;/a&gt; regarding drawing cross-domain images to a canvas. The missing piece for me was the existence of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;URL.createObjectUrl()&lt;/span&gt;&lt;/code&gt; method.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-solution-in-its-entirety"&gt;
&lt;h2&gt;The solution in its entirety&lt;a class="headerlink" href="#the-solution-in-its-entirety" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Please reference &lt;a class="reference external" href="http://www.sciencelifeny.com/transparency/transparency.html"&gt;How to use transparency info from a video on a website&lt;/a&gt; for a more descriptive writeup on the basics of video transparency in browsers. The primary piece I have left out here is that you will need a video with the alpha channel stored in a separate position.&lt;/p&gt;
&lt;p&gt;First, the HTML. The page needs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A single video element that does not display (because the video will be drawn to the canvas)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A canvas whose width and height match the video, which is used to draw the video data to&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A canvas whose width matches the video, and whose height is twice the video height&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main JavaScript file execution is deferred in order to run after the page has finished loading.&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;script/main.js&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;video&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;display:none&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;autoplay&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;source&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;video.mp4&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;video/mp4&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;video&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;canvas&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1920&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1080&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;output&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;canvas&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;display:none;&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1920&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;2160&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;buffer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The JavaScript will reference all three HTML elements, references to the canvas’ 2D contexts and video width and height are saved, and the buffer and output canvas widths and heights are set.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;output&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2d&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;bufferCanvas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;buffer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;bufferCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;2d&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientWidth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;bufferCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bufferCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientWidth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;bufferCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bufferCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientHeight&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;video&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;outputCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In order to avoid excessive CPU usage, and to continually draw video frames to the canvas, a recursive method, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;determineDraw()&lt;/span&gt;&lt;/code&gt; is used in conjunction with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;requestAnimationFrame()&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lastDrawTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;determineDraw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// If the video has finished, there is no need to execute again, and this ends the script.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paused&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ended&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// If the current playhead of the video has not changed since the last time this method executed,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// there is no need to draw the same frame again.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// lastDrawTime&amp;#39;s initial value is -1 because video.currentTime will never be -1.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;lastDrawTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// If the video playhead has changed, the current frame is drawn (explained below).&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Store the current playhead position.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;lastDrawTime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Recurse.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;determineDraw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To kick things off&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;XMLHttpRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;video&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;crossorigin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;anonymous&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;loadeddata&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// now that our in-memory video element has loaded, we can remove the original video element.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;removeNode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;removeNode&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Once the video starts playing, recursion begins, and we draw to the canvas roughly every 16ms.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;play&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;determineDraw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// start playback&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// setting the in-memory video source URL to the in-memory object bypasses the tainted canvas cross-origin check.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;vid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;drawImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;video&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// this can be done without alphaData, except in Firefox which doesn&amp;#39;t like it when image is bigger than the canvas&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getImageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;alphaData&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getImageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Grabs every 4th data point (the alpha value) and overwrites the same data point on the RGB channel.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;len&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;alphaData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;putImageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="an-admission"&gt;
&lt;h2&gt;An admission&lt;a class="headerlink" href="#an-admission" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I started writing this post almost a year ago now, and I never got back around to breaking the code down into more describable parts.&lt;/p&gt;
&lt;p&gt;I also, unfortunately, am unable to include another significant portion of the code that allows these same concepts to work in some older browers, or those with iffy CORS support. I can give a hint, though: it uses XMLHttpRequest to get the video (instead of a video tag) and draws the request result to the canvas.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2017/transparent_video_in_all_browsers_from_cross_domain_sources.html"/><category term="JavaScript"/><category term="Canvas"/><category term="Experimental"/><category term="AJAX"/><category term="XMLHttpRequest"/><category term="Video"/><published>2017-01-06T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2016/using_git_with_the_git_directory_outside_the_git_repository_directory.html</id><title>Using Git with the .git directory outside the Git repository directory</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="using-git-with-the-git-directory-outside-the-git-repository-directory"&gt;
&lt;h1&gt;Using Git with the .git directory outside the Git repository directory&lt;a class="headerlink" href="#using-git-with-the-git-directory-outside-the-git-repository-directory" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2016-08-19"&gt;19 August 2016&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/git.html"&gt;Git&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/git-bash.html"&gt;Git-Bash&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/bash.html"&gt;Bash&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have a particular use case where I want to use Git on top of another version control system. The only problem I ran into is that the other VCS wanted to track the .git directory that Git creates for its own tracking purposes.&lt;/p&gt;
&lt;p&gt;Rather than mess about with making the existing VCS ignore this directory, I set out to make Git store the .git directory somewhere else. Turns out it’s pretty easy, but Git is fickle, and you have to set a couple environment variables rather than simply using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;--git-dir&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;--work-tree&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The bash script below creates a function named git in your environment that shells out to the real Git binary. It will also attempt to create a new directory in your home directory (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;~/gitdirs&lt;/span&gt;&lt;/code&gt;) to hold these new .git directories. This script also works in Git Bash!&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Store a reference to the Git binary&lt;/span&gt;
&lt;span class="nv"&gt;GIT_BIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;which&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;span class="c1"&gt;# The function that runs when you type `git`&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# The location .git directories are stored in&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;gitdirroot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/gitdirs
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# Create that directory if it does not exist&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$gitdirroot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$gitdirroot&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# Use the current working directory as the .git directory name&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;gitdirname&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$gitdirroot&lt;/span&gt;&lt;span class="s2"&gt;/`pwd | tr &amp;quot;&lt;/span&gt;/&lt;span class="s2"&gt;&amp;quot; &amp;#39;_&amp;#39;`&amp;quot;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# Set the two environment variables Git needs to use the new .git directory&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;GIT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$gitdirname&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;GIT_WORK_TREE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# Execute the Git command&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;$GIT_BIN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2016/using_git_with_the_git_directory_outside_the_git_repository_directory.html"/><category term="Git"/><category term="Git-Bash"/><category term="Bash"/><published>2016-08-19T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2016/simple_way_to_prevent_websites_jumping_from_scrollbars.html</id><title>Simple Way to Prevent Websites Jumping from Scrollbars</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="simple-way-to-prevent-websites-jumping-from-scrollbars"&gt;
&lt;h1&gt;Simple Way to Prevent Websites Jumping from Scrollbars&lt;a class="headerlink" href="#simple-way-to-prevent-websites-jumping-from-scrollbars" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2016-04-01"&gt;1 April 2016&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/css.html"&gt;CSS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A common occurance I see on websites, and a frequent question I see as well regards websites “jumping” when more content loads onto the page and a scrollbar becomes visible in the browser. The solution to this is remarkably easy, but I don’t think I’ve seen many developers mention it.&lt;/p&gt;
&lt;p&gt;The trick is simply to make the scrollbar present at all times.&lt;/p&gt;
&lt;p&gt;If your site creates a vertical scrollbar, use this CSS:&lt;/p&gt;
&lt;div class="highlight-css notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If horizontal, use this CSS:&lt;/p&gt;
&lt;div class="highlight-css notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And lastly, if your site creates scrollbars in both directions, you can just use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;overflow&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-css notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Just be aware that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;overflow-x&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;overflow-y&lt;/span&gt;&lt;/code&gt; may not be supported in your target browsers!&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-y"&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-y&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-x"&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-x&lt;/a&gt;&lt;/p&gt;
&lt;section id="update-jan-10th-2019"&gt;
&lt;h2&gt;Update Jan 10th, 2019&lt;a class="headerlink" href="#update-jan-10th-2019" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It turns out Mac OS and iOS may hide scrollbars regardless of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;overflow:&lt;/span&gt; &lt;span class="pre"&gt;scroll&lt;/span&gt;&lt;/code&gt; rule. Check out &lt;a class="reference external" href="https://gist.github.com/IceCreamYou/cd517596e5847a88e2bb0a091da43fb4"&gt;this fix&lt;/a&gt; to override this behavior.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2016/simple_way_to_prevent_websites_jumping_from_scrollbars.html"/><category term="CSS"/><published>2016-04-01T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2016/two_short_ack_filetype_definitions_for_typescript.html</id><title>Two short ack filetype definitions for TypeScript</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="two-short-ack-filetype-definitions-for-typescript"&gt;
&lt;h1&gt;Two short ack filetype definitions for TypeScript&lt;a class="headerlink" href="#two-short-ack-filetype-definitions-for-typescript" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2016-02-09"&gt;9 February 2016&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/ack.html"&gt;ack&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/typescript.html"&gt;TypeScript&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I search my TypeScript code a lot and finally got tired of using awk, grep, and friends to filter out irrelevant files. Here’s a definition for .ts files and .d.ts files to help you out.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;
&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tsdef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/.+&lt;/span&gt;\&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;\&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Put this in your &lt;a class="reference external" href="https://metacpan.org/pod/ack#Use-the-.ackrc-file"&gt;.ackrc&lt;/a&gt; file (or use those switches at the command line).&lt;/p&gt;
&lt;p&gt;Now you can search just your .ts files without also searching compiled .js and .d.ts files with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ack&lt;/span&gt; &lt;span class="pre"&gt;--ts&lt;/span&gt; &lt;span class="pre"&gt;--notsdef&lt;/span&gt; &lt;span class="pre"&gt;mySearch&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;More information &lt;a class="reference external" href="http://beyondgrep.com/documentation/ack-2.14-man.html#defining_your_own_types"&gt;in the ack manpage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2016/two_short_ack_filetype_definitions_for_typescript.html"/><category term="ack"/><category term="TypeScript"/><published>2016-02-09T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/simple_programming_patterns_and_conventions.html</id><title>Simple programming patterns and conventions</title><updated>2025-08-06T20:21:59+00:00</updated><content>&lt;section id="simple-programming-patterns-and-conventions"&gt;
&lt;h1&gt;Simple programming patterns and conventions&lt;a class="headerlink" href="#simple-programming-patterns-and-conventions" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-12-24"&gt;24 December 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/patterns.html"&gt;Patterns&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/conventions.html"&gt;Conventions&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/programming.html"&gt;Programming&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I thought it might be helpful to some developers to see some simple patterns and conventions in a variety of languages. Many of us know about more complex and abstract patterns, like the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Abstract_factory_pattern"&gt;Abstract Factory Pattern&lt;/a&gt; or the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Flyweight_pattern"&gt;Flyweight Pattern&lt;/a&gt;, but smaller patterns are rarely discussed outside of answers to questions.&lt;/p&gt;
&lt;p&gt;These are some patterns and conventions that I tend to use in any code I write. They range from one-liners to a couple of methods, and are mostly understandable at first glance. I’ve avoided going too much into why someone might choose any given pattern, and leave it as an exercise to the reader to determine where these patterns might be useful for them.&lt;/p&gt;
&lt;p&gt;As of now, I’ve only listed a single convention because I use it in a number of the patterns below. I’m sure the convention is controversial, so if you don’t agree with it, please keep in mind that the meat of this post is in the patterns.&lt;/p&gt;
&lt;p&gt;I will add other conventions and patterns in the future, and may add others from comments here or on reddit.&lt;/p&gt;
&lt;p&gt;A final note on the code below. I did not enclose all code in the required class or method blocks in order to keep the focus on the patterns alone. Additionally, I’ve specified the language that each example is written for; many of them work just fine in other languages. If you have any questions on why a pattern doesn’t make sense, or is not executing, don’t hesitate to ask.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;section id="code-conventions"&gt;
&lt;h2&gt;Code Conventions&lt;a class="headerlink" href="#code-conventions" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;section id="branching-flow-control-statements"&gt;
&lt;h3&gt;Branching flow-control statements&lt;a class="headerlink" href="#branching-flow-control-statements" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For branching flow-control statements, do not use braces and keep the code on a single line.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="return-statements"&gt;
&lt;h3&gt;Return statements&lt;a class="headerlink" href="#return-statements" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#, most C-like languages with some contingencies&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyBoolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="continuing-in-a-loop"&gt;
&lt;h2&gt;Continuing in a loop&lt;a class="headerlink" href="#continuing-in-a-loop" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#, most C-like languages&lt;/p&gt;
&lt;section id="breaking-out-of-a-loop"&gt;
&lt;h3&gt;Breaking out of a loop&lt;a class="headerlink" href="#breaking-out-of-a-loop" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#, most C-like languages&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;hr class="docutils" /&gt;
&lt;section id="code-patterns"&gt;
&lt;h2&gt;Code Patterns&lt;a class="headerlink" href="#code-patterns" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;section id="prevent-a-method-from-executing-more-than-once"&gt;
&lt;h3&gt;Prevent a method from executing more than once&lt;a class="headerlink" href="#prevent-a-method-from-executing-more-than-once" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is an easy way to prevent a method from executing multiple times. By checking a condition at the beginning, and then ensuring that condition is true immediately after, any subsequent calls will return immediately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#, Java with some contingencies&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;executed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MyFoo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// simply check the condition before any other code&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;executed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// then assign your variable&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="using-a-switch-statement-as-a-compact-alternative-to-if-statements"&gt;
&lt;h2&gt;Using a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;switch&lt;/span&gt;&lt;/code&gt; statement as a compact alternative to if statements&lt;a class="headerlink" href="#using-a-switch-statement-as-a-compact-alternative-to-if-statements" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: JavaScript&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myFoo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myBar&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FooBar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// while the next statement is false if this is true, the additional check is avoided with the `break` statement&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myFoo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myBaz&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;FooBaz&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DefaultMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="execute-multiple-using-blocks-without-braces"&gt;
&lt;h2&gt;Execute multiple &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;using&lt;/span&gt;&lt;/code&gt; blocks without braces&lt;a class="headerlink" href="#execute-multiple-using-blocks-without-braces" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Like any other block statement, in C#, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;using&lt;/span&gt;&lt;/code&gt; can be used without braces as well. This is especially useful to avoid excessive visual nesting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;myDisposableObject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Disposable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;myFoo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;myBar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Each of myDisposableObject, myFoo, and mBar are accessible here&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="avoid-unnecessary-awaits-by-passing-the-task-around"&gt;
&lt;h2&gt;Avoid unnecessary awaits by passing the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Task&lt;/span&gt;&lt;/code&gt; around&lt;a class="headerlink" href="#avoid-unnecessary-awaits-by-passing-the-task-around" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;At least for me, using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;async&lt;/span&gt;&lt;/code&gt; / &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;await&lt;/span&gt;&lt;/code&gt; in C# seemed to require making your methods that called asynchronous methods async themselves, and making those methods await. Instead, if your method does not need to await, you can make it return a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Task&lt;/span&gt;&lt;/code&gt; and then pass the task returned from an asynchronous method wherever you need it. This is especially helpful if you need to use &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;out&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ref&lt;/span&gt;&lt;/code&gt; in a method that calls an asynchronous method.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;MySyncMethod&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MyAsyncMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Waiting 1 second @ &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// here we await the result so we can execute code immediately after, usually to operate on the result of the Task&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Finished waiting @ &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MySyncMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Calling asynchronous method&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MyAsyncMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// MySyncMethod doesn&amp;#39;t need to execute code immediately after, so it is synchronous and only returns the Task&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="prevent-a-method-call-with-a-specific-type-during-compile-time"&gt;
&lt;h2&gt;Prevent a method call with a specific type during compile time&lt;a class="headerlink" href="#prevent-a-method-call-with-a-specific-type-during-compile-time" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I happened across this solution when clicking around Stack Overflow. Apologies for not crediting the solution; I don’t recall where I found it.&lt;/p&gt;
&lt;p&gt;You may have a method that accepts an abstract class, an interface, or some form of “base” class, but you want to restrict a certain subclass of that type from being used (perhaps the subclass is obsolete). Rather than checking the type during runtime and throwing an exception, you use this pattern to gain a compile time check in addition to a runtime check. This example uses constructors, but it works for methods as well.&lt;/p&gt;
&lt;p&gt;By default, the Obsolete annotation will display a warning. You can configure msbuild or Visual Studio to treat warnings as errors, which will prevent the following code from compiling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IBar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IBar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Baz&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IBar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IBar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;[Obsolete(&amp;quot;Foo cannot be instantiated with a Baz.&amp;quot;)]&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Baz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// overload the IBar constructor with the type that is disallowed&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Baz&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// this generates a warning during compile time, and an exception during runtime&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="define-and-declare-the-type-of-arrays-and-objects-in-typescript"&gt;
&lt;h2&gt;Define and declare the type of arrays and objects in TypeScript&lt;a class="headerlink" href="#define-and-declare-the-type-of-arrays-and-objects-in-typescript" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think this is a problem and solution unique to TypeScript. You need to define a variable as an array or an object, but either you’ve disallowed implicity any, or you need to declare the type of the variable. There are, of course, other ways to accomplish this, but I believe this is the most compact way.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: TypeScript&lt;/p&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myFoos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// here we simply cast the array to the specific type needed&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;myFood&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// the same pattern is used for objects as well&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="execute-multiple-async-tasks-in-parallel"&gt;
&lt;h2&gt;Execute multiple async tasks in parallel&lt;a class="headerlink" href="#execute-multiple-async-tasks-in-parallel" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You may need to execute a series of asynchronous tasks in parallel, and then await their result. There are a couple different ways I accomplish this, depending on how the tasks are created. You can use the pattern &lt;em&gt;Avoid unnecessary awaits by passing the ``Task`` around&lt;/em&gt; here as well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Language&lt;/strong&gt;: C#&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MyFirstMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// here we use a List&amp;lt;Task&amp;gt; in order to optionally add tasks to await&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aCondition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// if aCondition is true, two tasks are added to the list&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// this method will complete after 1 second, when all three tasks are completed&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MySecondMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// here an array is initialized because there is no need to conditionally add more tasks&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhenAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/simple_programming_patterns_and_conventions.html"/><category term="Patterns"/><category term="Conventions"/><category term="Programming"/><published>2015-12-24T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/printing_function_body_in_chromes_console.html</id><title>Printing function body in Chrome’s console</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="printing-function-body-in-chrome-s-console"&gt;
&lt;h1&gt;Printing function body in Chrome’s console&lt;a class="headerlink" href="#printing-function-body-in-chrome-s-console" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-07-01"&gt;1 July 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/chrome.html"&gt;Chrome&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Chrome used to, by default, print a function body in the console if you entered a function name into it, or if you called &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;console.log()&lt;/span&gt;&lt;/code&gt; with a function name.&lt;/p&gt;
&lt;p&gt;What happens now is that Chrome will print a link to the function which, when clicked, will navigate your source viewer to that function.&lt;/p&gt;
&lt;p&gt;For example, executing (or logging) &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BLT.TypeScript.Text.truncate&lt;/span&gt;&lt;/code&gt; will print &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;function&lt;/span&gt; &lt;span class="pre"&gt;truncate(input,&lt;/span&gt; &lt;span class="pre"&gt;length,&lt;/span&gt; &lt;span class="pre"&gt;ellipsize)&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For me, navigating away from my source viewer when I want a reference to a function is distracting. I am not aware of a way to re-enable the old behavior, but an alternative is to now call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;toString()&lt;/span&gt;&lt;/code&gt; on the function. Unfortunately, it does not appear that whitespace is preserved.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;BLT.TypeScript.Text.truncate.toString()&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here is the actual function body:&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;truncate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ellipsize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ellipsize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ellipsize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;whitespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\\s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;truncatedStr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;whitespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;truncatedStr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;truncatedStr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ellipsize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; ...&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;whitespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;substr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ellipsize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; ...&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/printing_function_body_in_chromes_console.html"/><category term="Chrome"/><published>2015-07-01T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/reading_an_http_request_response_body_from_exceptions.html</id><title>Reading an HTTP Request Response Body from Exceptions</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="reading-an-http-request-response-body-from-exceptions"&gt;
&lt;h1&gt;Reading an HTTP Request Response Body from Exceptions&lt;a class="headerlink" href="#reading-an-http-request-response-body-from-exceptions" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-04-16"&gt;16 April 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/c.html"&gt;C#&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/net.html"&gt;.NET&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/http.html"&gt;HTTP&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/debugging.html"&gt;Debugging&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Every so often I need to read the response body of a failed HTTP request while debugging a .NET application in Visual Studio. It’s not immediately obvious how you can do this, so here’s a quick way to do so. You can use these same methods when working directly with an HTTP response object or an HTTP request object as well.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Open the Immediate Window under Debug &amp;gt; Windows &amp;gt; Immediate, or by pressing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;CTRL&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;ALT&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;I&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’ll need to cast your exception to a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;WebException&lt;/span&gt;&lt;/code&gt;. Try either of these, depending on what kind of exception you’re working with.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InnerException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Still no luck? Look in the Locals window and see if you can find the correct exception that has the HTTP response object in it. You’ll know you have the right one when the Immediate Window prints something other than &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;null&lt;/span&gt;&lt;/code&gt;. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;The remote server returned an error: (404) Not Found.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;The remote server returned an error: (404) Not Found.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpWebResponse&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProtocolError&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Now you can get the response stream from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;WebException&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InnerException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebException&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponseStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SyncMemoryStream&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SyncMemoryStream&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SyncMemoryStream&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SyncMemoryStream&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;CanRead&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;CanSeek&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;CanTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;CanWrite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;78&lt;/span&gt;
    &lt;span class="n"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;ReadTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;WriteTimeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Create a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;StreamReader&lt;/span&gt;&lt;/code&gt; object just for ease of use.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;BaseStream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SyncMemoryStream&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;CurrentEncoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8Encoding&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;EndOfStream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="5"&gt;
&lt;li&gt;&lt;p&gt;Finally, read the stream contents. This is the HTTP response body:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadToEnd&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;{&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;Message&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;The index &amp;#39;products&amp;#39; for service &amp;#39;search&amp;#39; was not found.&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;}&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/reading_an_http_request_response_body_from_exceptions.html"/><category term="C#"/><category term=".NET"/><category term="HTTP"/><category term="Debugging"/><published>2015-04-16T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/circuit_scribe_art_project_step_number_3.html</id><title>Circuit Scribe art project step #3</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="circuit-scribe-art-project-step-3"&gt;
&lt;h1&gt;Circuit Scribe art project step #3&lt;a class="headerlink" href="#circuit-scribe-art-project-step-3" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-01-25"&gt;25 January 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/circuit-scribe.html"&gt;Circuit-Scribe&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/circuit-scribe-seattle.html"&gt;Circuit-Scribe-Seattle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I finally took the time to start maping out where I’ll need to draw my Circuit Scribe ink lines. I also drew where I want to place LEDs and calculated resistor values. I may need to revisit some of this to use less resistors to lower the load on the circuit, but I’m not sure. I’ll have to draw out a couple circuits and test.&lt;/p&gt;
&lt;p&gt;The LEDs I have need a forward voltage of 3.2 and a max forward current of 20mA. With one LED, I’ve found that 3 80.6Ω resistors in series gives an appropriate brightness without hitting the max current rating. I’m hoping that the ~130Ω resistance I’ve placed in a few places will allow a similar brightness for two LEDs in series. Some individual LEDs are placed on the ~130Ω resistance rail as well, and for those I added two additional 80.6Ω resistors in series bringing the total resistance up to ~290Ω. I may have to drop my source voltage to 5V to avoid burning out some LEDs, or add more resistors.&lt;/p&gt;
&lt;p&gt;Some individual LEDs are placed on the ~130 Ω resistance rail as well, and for those I added two additional 80.6 Ω resistors in series bringing the total resistance up to ~290 Ω. I may have to drop my source voltage to 5 V to avoid burning out some LEDs, or add more resistors.&lt;/p&gt;
&lt;p&gt;Some calculations follow.&lt;/p&gt;
&lt;div class="highlight-text notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Measurement              Value
Source voltage           9
LED forward voltage      3.2
LED max forward current  20 mA
Single resistor          80.6Ω
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For single LEDs I calculated &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;R&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;((9&lt;/span&gt; &lt;span class="pre"&gt;-&lt;/span&gt; &lt;span class="pre"&gt;3.2)&lt;/span&gt; &lt;span class="pre"&gt;/&lt;/span&gt; &lt;span class="pre"&gt;0.02)&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;290&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I need &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;R&lt;/span&gt; &lt;span class="pre"&gt;/&lt;/span&gt; &lt;span class="pre"&gt;80.6&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;3.6&lt;/span&gt;&lt;/code&gt; resistors. I rounded down to 3. I didn’t experience any excessive heat with this configuration.&lt;/p&gt;
&lt;p&gt;For two LEDs in series I used four 80.6Ω resistors; two in series, and those two in parallel with two more 80.6Ω resistors also in parallel. The total resistance is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;R&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;1&lt;/span&gt; &lt;span class="pre"&gt;/&lt;/span&gt; &lt;span class="pre"&gt;(1/80&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;1/80&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;1/(80&lt;/span&gt; &lt;span class="pre"&gt;+&lt;/span&gt; &lt;span class="pre"&gt;80))&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;32&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The power, then, is calculated as &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;I&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;(9&lt;/span&gt; &lt;span class="pre"&gt;-&lt;/span&gt; &lt;span class="pre"&gt;3.2&lt;/span&gt; &lt;span class="pre"&gt;-&lt;/span&gt; &lt;span class="pre"&gt;3.2)&lt;/span&gt; &lt;span class="pre"&gt;/&lt;/span&gt; &lt;span class="pre"&gt;32&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;8.1mA&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For driving a single LED off the 32Ω rail, we need to add additional resistors in series to limit the maximum forward current into the LED.&lt;/p&gt;
&lt;p&gt;We already know that the resistance required for a single LED is 290Ω. From here, we can subtract 32Ω to determine how many more ohms of resistance we need to add. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;290&lt;/span&gt; &lt;span class="pre"&gt;-&lt;/span&gt; &lt;span class="pre"&gt;32&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;258&lt;/span&gt;&lt;/code&gt;. We can then figure out how many 80.6Ω resistors are needed just with division. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;258&lt;/span&gt; &lt;span class="pre"&gt;/&lt;/span&gt; &lt;span class="pre"&gt;80.6&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;3.2&lt;/span&gt;&lt;/code&gt;. That’s 3 resistors.&lt;/p&gt;
&lt;p&gt;Oops! I only drew two additional resistors, which gives us a forward current of about 30mA - about 10mA too many. I’ll have to revisit that circuit, or simply use a third resistor. That would give this rail about 274Ω of resistance.&lt;/p&gt;
&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/RjC7de7ul3E" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;img alt="../_images/circuit-1.png" src="../_images/circuit-1.png" /&gt;
&lt;p&gt;Next up, I should have the corrected circuits drawn out and I’ll actually be able to draw them on my canvas!&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/circuit_scribe_art_project_step_number_3.html"/><category term="Circuit-Scribe"/><category term="Circuit-Scribe-Seattle"/><published>2015-01-25T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/circuit_scribe_art_project_step_number_2.html</id><title>Circuit Scribe art project step #2</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="circuit-scribe-art-project-step-2"&gt;
&lt;h1&gt;Circuit Scribe art project step #2&lt;a class="headerlink" href="#circuit-scribe-art-project-step-2" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-01-20"&gt;20 January 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/circuit-scribe.html"&gt;Circuit-Scribe&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/circuit-scribe-seattle.html"&gt;Circuit-Scribe-Seattle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I put another hour into this and started sketching out the buildings surrounding the Space Needle. The landscape is starting to take shape, but it lacks any depth. Next I need to figure out where I’m going to route my circuit, and then I’ll start drawing some of the details in the buildings.&lt;/p&gt;
&lt;p&gt;Also I really need to get my camera to pick up the pencil marks as I’m working. It looks like I’m just zipping all over a black board and doing nothing.&lt;/p&gt;
&lt;iframe width="560" height="315"
        src="https://www.youtube.com/embed/AewB6NsE-1Y"
        frameborder="0"
        allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/circuit_scribe_art_project_step_number_2.html"/><category term="Circuit-Scribe"/><category term="Circuit-Scribe-Seattle"/><published>2015-01-20T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/circuit_scribe_art_project_step_number_1.html</id><title>Circuit Scribe art project step #1</title><updated>2025-08-06T20:39:41+00:00</updated><content>&lt;section id="circuit-scribe-art-project-step-1"&gt;
&lt;h1&gt;Circuit Scribe art project step #1&lt;a class="headerlink" href="#circuit-scribe-art-project-step-1" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-01-19"&gt;19 January 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/circuit-scribe.html"&gt;Circuit-Scribe&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/circuit-scribe-seattle.html"&gt;Circuit-Scribe-Seattle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I finally started my “cityscape” project with Circuit Scribe! Here’s a quick video showing the first pencil sketches. I will be posting these as I go along under the &lt;a class="reference internal" href="../_tags/circuit-scribe-seattle.html#circuit-scribe-seattle"&gt;&lt;span class="std std-ref"&gt;Circuit-Scribe-Seattle&lt;/span&gt;&lt;/a&gt; tag, so stay tuned for more!&lt;/p&gt;
&lt;iframe width="560" height="315"
        src="https://www.youtube.com/embed/XXpSBaL36mU"
        frameborder="0"
        allowfullscreen&gt;&lt;/iframe&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/circuit_scribe_art_project_step_number_1.html"/><category term="Circuit-Scribe"/><category term="Circuit-Scribe-Seattle"/><published>2015-01-19T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2015/writing_angularjs_directives_as_typescript_classes.html</id><title>Writing AngularJS directives as TypeScript classes</title><updated>2025-08-06T20:28:01+00:00</updated><content>&lt;section id="writing-angularjs-directives-as-typescript-classes"&gt;
&lt;h1&gt;Writing AngularJS directives as TypeScript classes&lt;a class="headerlink" href="#writing-angularjs-directives-as-typescript-classes" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2015-01-12"&gt;12 January 2015&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/javascript.html"&gt;JavaScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/typescript.html"&gt;TypeScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/angularjs.html"&gt;AngularJS&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/directives.html"&gt;Directives&lt;/a&gt;&lt;/p&gt;
&lt;section id="introduction"&gt;
&lt;h2&gt;Introduction&lt;a class="headerlink" href="#introduction" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;TL;DR? Read the implementation details here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This post was written for AngularJS 1.x. Angular 2+ has different conventions that make parts of this post obsolete.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; is a fantastic language that extends JavaScript by providing static typing syntax. Writing TypeScript to utilize &lt;a class="reference external" href="https://angularjs.org/"&gt;AngularJS&lt;/a&gt; can be clunky at times, and one pain point for me was in writing &lt;a class="reference external" href="https://docs.angularjs.org/guide/directive"&gt;directives&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;AngularJS expects to be &lt;a class="reference external" href="https://docs.angularjs.org/api/ng/provider/$compileProvider#directive"&gt;fed&lt;/a&gt; a factory function that returns an object that defines parameters and functionality for your directive.&lt;/p&gt;
&lt;p&gt;In JavaScript, that looks like this.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;myDirective&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Aaron&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A direct translation of this to TypeScript looks like this. By the way, I am using the &lt;a class="reference external" href="https://github.com/borisyankov/DefinitelyTyped/blob/master/angularjs/angular.d.ts"&gt;angular.d.ts&lt;/a&gt; type definition file from &lt;a class="reference external" href="http://definitelytyped.org/"&gt;definitelytyped.org&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyModule.Directives&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IMyScope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IScope&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDirective&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IMyScope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Aaron&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The registration is then handled as follows.&lt;/p&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;module.directive('projects',&lt;/span&gt; &lt;span class="pre"&gt;MyModule.Directives.MyDirective.Factory());&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Not too different, really, but I feel this doesn’t encapsulate a directive very well, nor does it really take advantage of the utility of TypeScript.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="why-this-is-problematic"&gt;
&lt;h2&gt;Why this is problematic&lt;a class="headerlink" href="#why-this-is-problematic" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MyDirective&lt;/span&gt;&lt;/code&gt; is a base class, I would not be able to extend &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MyDirective&lt;/span&gt;&lt;/code&gt; with a subclass. Granted, because TypeScript is a superset of JavaScript, it would be possible to extend this function through prototypal inheritance, or one of a plethora of such approaches. This, however, has the disadvantage of muddying your TypeScript with syntax and code that doesn’t necessarily need to be there.&lt;/p&gt;
&lt;section id="a-real-world-example-without-a-class"&gt;
&lt;h3&gt;A real-world example without a class&lt;a class="headerlink" href="#a-real-world-example-without-a-class" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To bring my examples into the real world, here’s a previous iteration of a directive I wrote for my personal site. This uses the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;export&lt;/span&gt; &lt;span class="pre"&gt;function&lt;/span&gt;&lt;/code&gt; syntax.&lt;/p&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AaronholmesNet.Directives&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Resources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IProjectsScope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IScope&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Interfaces.IListInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// return my repositories first, and forks second.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// from there, sort by last change time.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ProjectSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;number&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ProjectsDirective&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ProjectResource&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProjectResource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$location&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ILocationService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.sanitize.ISanitizeService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ISCEService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDirective&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;templateUrl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/Views/Home/projects.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProjectsScope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;projectMap&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;ProjectResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProject&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ProjectSort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trustAsUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readme&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trustAsHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; (fork)&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; (repo)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;projectMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ne"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;// toggle which tab and tab detail is visible when a link is clicked&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$locationChangeStart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLAnchorElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^\/(\d+)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^\/(\d+)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;ProjectsDirective&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$inject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ProjectResource&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$location&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$sanitize&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$sce&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="the-issues-with-this-approach"&gt;
&lt;h3&gt;The issues with this approach&lt;a class="headerlink" href="#the-issues-with-this-approach" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Because the exported function does not utilize a class structure, it’s necessary to either use prototypal inheritance or methods exposed in the exported functions scope. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProjectSort&lt;/span&gt;&lt;/code&gt; is a function that would be better served as a private method in a class.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The link method is much larger than it needs to be and could be slimmed down by moving the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;$locationChangeStart&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Query&lt;/span&gt;&lt;/code&gt; handler methods into the outer function scope. However, this becomes cumbersome to manage with many enclosed methods outside of the link function body and when you need to expose variables like scope, and $location. You then have to manage those variables in the outer scope as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Due to the length of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProjectsDirective&lt;/span&gt;&lt;/code&gt;, the minification-safe list of dependencies (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProjectsDirective['$inject']&lt;/span&gt;&lt;/code&gt;) is quite removed from the function signature. It would be easy to forget to include this, or to update it if your dependencies change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I’ve never been a huge fan of returning an object from a function to define my directive, and I would simply like to avoid it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="what-can-be-done-instead"&gt;
&lt;h2&gt;What can be done instead&lt;a class="headerlink" href="#what-can-be-done-instead" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Thankfully, it’s possible to write directives as a class with a bit of a shift in thinking about how you would organize TypeScript, as opposed to how you would organize JavaScript.&lt;/p&gt;
&lt;p&gt;The key point to keep in mind is that AngularJS still expects a function that returns an object. It turns out it’s simple and clean to do this with a static &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Factory&lt;/span&gt;&lt;/code&gt; method on your class.&lt;/p&gt;
&lt;p&gt;That first example of a TypeScript directive looks like this as a class.&lt;/p&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyModule.Directives&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IMyScope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IScope&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IMyScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IMyScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Aaron&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$inject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="what-this-accomplishes"&gt;
&lt;h3&gt;What this accomplishes&lt;a class="headerlink" href="#what-this-accomplishes" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;We now have proper properties, fields, and methods on our class instance. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;link&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;template&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scope&lt;/span&gt;&lt;/code&gt; are exposed in JavaScript as function properties. &lt;strong&gt;If I extend this class, my subclass can override these properties and still utilize the base class functionality&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The link method is now another property on the class where its initialization can utilize the class instances scope for property access.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The factory function is very short, and so the list of dependencies is immediately in front of the developer. While not perfect, it makes it a little more obvious that the directive function and its &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;$inject&lt;/span&gt;&lt;/code&gt; property are related.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This completely avoids having to return an object from a function because your class instance is the object that &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Factory&lt;/span&gt;&lt;/code&gt; returns to angular.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="a-real-world-example-with-a-class"&gt;
&lt;h3&gt;A real-world example with a class&lt;a class="headerlink" href="#a-real-world-example-with-a-class" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now let’s take a look at how I refactored my original &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ProjectsDirective&lt;/span&gt;&lt;/code&gt; to utilize a class structure. You can see here how I take advantage of exposing public properties as the same properties the directive method would normally set in the object it returns. You can also see the private methods and properties I’ve made available to the class instance in order to avoid relying on function scoping.&lt;/p&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AaronholmesNet.Directives&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Resources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IProjectsScope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IScope&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Interfaces.IListInterface&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ProjectsDirective&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #region Angular directive properties, fields, and methods&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;templateUrl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/Views/Home/projects.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProjectsScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #endregion&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #region Initialization and destruction&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ProjectResource&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProjectResource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$location&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ILocationService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.sanitize.ISanitizeService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ISCEService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$location&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sanitize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sce&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;ProjectsDirective&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProjectsScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;ProjectResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_handleProjectQuerySuccess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_handleProjectQueryError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;// toggle which tab and tab detail is visible when a link is clicked&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$locationChangeStart&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_handleLocationChangeStart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$destroy&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destruct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ProjectResource&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProjectResource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$location&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ILocationService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.sanitize.ISanitizeService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ISCEService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ProjectsDirective&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ProjectResource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sanitize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;$sce&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$inject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ProjectResource&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$location&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$sanitize&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$sce&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;destruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_projectMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$location&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sanitize&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sce&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scope&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #endregion&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #region Private class properties, fields, and methods&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_projectMap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IProject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_$location&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ILocationService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_$sanitize&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.sanitize.ISanitizeService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_$sce&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.ISCEService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_scope&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProjectsScope&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #endregion&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #region Private event handlers&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// return my repositories first, and forks second.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// from there, sort by last change time.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_projectSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;Resources.IProject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;number&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_handleProjectQuerySuccess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProject&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_projectSort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;IProject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sanitize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trustAsUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readme&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_$sce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trustAsHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; (fork)&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; (repo)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_projectMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;activeSet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_handleProjectQueryError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ne"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;_handleLocationChangeStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAngularEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLAnchorElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^\/(\d+)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^\/(\d+)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_projectMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_projectMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;nextId&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// #endregion&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="takeaways-and-wrap-up"&gt;
&lt;h2&gt;Takeaways and wrap up&lt;a class="headerlink" href="#takeaways-and-wrap-up" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This approach is not perfect, however I feel it has real strength when focusing heavily on object-oriented programming. I don’t demonstrate it here, but the ability to extend base class directives has been very helpful in another project. I also believe the encapsulation is much more clear, and lends itself to avoiding many of the issues we’re all familiar with in regards to prototypal inheritance and JavaScript’s strange function scoping rules.&lt;/p&gt;
&lt;section id="gotchas"&gt;
&lt;h3&gt;Gotchas&lt;a class="headerlink" href="#gotchas" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;It’s important to note that you may have to bind contexts for event handlers. For example, with this call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scope.$on('$locationChangeStart',&lt;/span&gt; &lt;span class="pre"&gt;this._handleLocationChangeStart.bind(this));&lt;/span&gt;&lt;/code&gt; we must bind &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;_handleLocationChangeStart&lt;/span&gt;&lt;/code&gt; to the class instance context because scope.$on will call it within the context of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;window&lt;/span&gt;&lt;/code&gt;. If someone knows of a way to handle this in TypeScript without &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;bbid&lt;/span&gt;&lt;/code&gt;, I’d love to hear your input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;scope&lt;/span&gt;&lt;/code&gt; property is public, and is the same property that is returned from a directive function. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;_scope&lt;/span&gt;&lt;/code&gt; is private and is the actual directive’s scope object, not the isolate scope definition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It sucks that many parts of the directive function signature are duplicated in the function returned from Factory, the instantiation call, and the constructor signature. I would love to hear alternate ways to accomplish this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://disqus.com/by/bogusawskrzypkowiak/"&gt;b091&lt;/a&gt; discovered a way to avoid both the redundancies and the Factory method by using decorators. See &lt;a class="reference external" href="#comment-6748633131"&gt;this comment&lt;/a&gt; for more information.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is possible to unintentially create only a single instance of your directive by binding functions and variables in the constructor. For any data members that need to be unique between instances, ensure that they are added to the classes &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;prototype&lt;/span&gt;&lt;/code&gt; rather than the instance itself. See &lt;a class="reference external" href="#comment-2111298002"&gt;this comment&lt;/a&gt; for more information.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="back-to-the-basics"&gt;
&lt;h3&gt;Back to the basics&lt;a class="headerlink" href="#back-to-the-basics" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To summarize, here are the basic pieces you need to get this working.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A static factory method and a constructor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*list of dependencies*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A public link method that accepts the same parameters any AngularJS directive accepts, and returns void. Include any other directive properties you need, such as template and scope.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*list of dependencies*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The initialization of the link method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*list of dependencies*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// It&amp;#39;s important to add `link` to the prototype or you will end up with state issues.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// See https://aaronholmes.net/2015/writing_angularjs_directives_as_typescript_classes.html#comment-2111298002 for more information.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="cm"&gt;/*handle all your linking requirements here*/&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;The instantiation call from your Factory method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-typescript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;lt;div&amp;gt;{{name}}&amp;lt;/div&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kr"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*list of dependencies*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// It&amp;#39;s important to add `link` to the prototype or you will end up with state issues.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// See https://aaronholmes.net/2015/writing_angularjs_directives_as_typescript_classes.html#comment-2111298002 for more information.&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IScope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAugmentedJQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;ng.IAttributes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="cm"&gt;/*handle all your linking requirements here*/&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*list of dependencies*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;MyDirective&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/*list of dependencies*/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$inject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/*list of dependencies*/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;And finally, the registration of your directive with AngularJS by calling the Factory method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;It’s important to note that Factory is executed here, and its returned value (the directive) is passed to Angular’s registration function.&lt;/strong&gt; &lt;span class="underline"&gt;Be sure to include the parenthesis!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2015/writing_angularjs_directives_as_typescript_classes.html"/><category term="JavaScript"/><category term="TypeScript"/><category term="AngularJS"/><category term="Directives"/><published>2015-01-12T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2014/using_time_as_a_color_generator.html</id><title>Using Time as a Color Generator</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="using-time-as-a-color-generator"&gt;
&lt;h1&gt;Using Time as a Color Generator&lt;a class="headerlink" href="#using-time-as-a-color-generator" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2014-12-20"&gt;20 December 2014&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/javascript.html"&gt;JavaScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/css.html"&gt;CSS&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/codepen.html"&gt;Codepen&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/fiddle.html"&gt;Fiddle&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/experimental.html"&gt;Experimental&lt;/a&gt;&lt;/p&gt;
&lt;script&gt;
window.addEventListener('load', function()
{
    var rgbs =
    [
        [$('#red'),24,'rgb(#,0,0)'],
        [$('#green'),60,'rgb(0,#,0)'],
        [$('#blue'),60,'rgb(0,0,#)']
    ];

    for(var j=0;j&lt;3;j++)
    {
        var target=rgbs[j % rgbs.length];
        for(var i=0;i&lt;target[1];i++)
        {
            target[0].append($('&lt;div/&gt;').css(
            {
                display:'inline-block',
                width:'10px',
                height:'30px',
                'margin-left':'-1px',
                'background-color':target[2].replace('#',i)
            }));
        }
    }
});
&lt;/script&gt;

&lt;script&gt;
window.addEventListener('load', function()
{
    var rgbs =
    [
        [$('#red2'),24,'rgb(#,0,0)'],
        [$('#green2'),60,'rgb(0,#,0)'],
        [$('#blue2'),60,'rgb(0,0,#)']
    ];

    for(var j=0;j&lt;3;j++)
    {
        var target=rgbs[j % rgbs.length];
        for(var i=0;i&lt;target[1];i++)
        {
            target[0].append($('&lt;div/&gt;').css(
            {
                display:'inline-block',
                width:'10px',
                height:'30px',
                'margin-left':'-1px',
                'background-color':target[2].replace('#',i.toString().replace(/^(\d)$/, '0$1').split('').reverse().join(''))
            }));
        }
    }
});
&lt;/script&gt;&lt;section id="the-idea"&gt;
&lt;h2&gt;The idea&lt;a class="headerlink" href="#the-idea" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I saw the site &lt;a class="reference external" href="about:blank?site-is-defunct"&gt;What colour is it?&lt;/a&gt; and thought the concept was really cool. For whatever reason, visualization generators pique my interest. I wanted to alter the original to see a wider range of colors, and to play with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attr()&lt;/span&gt;&lt;/code&gt; function in CSS’ &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;::after&lt;/span&gt;&lt;/code&gt; psuedo-element. I also wanted to add a slider just to allow the user to tweak the generated color.&lt;/p&gt;
&lt;p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="zxBJMg" data-pen-title="Time color" data-user="aholmes" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;"&gt;
  &lt;span&gt;See the Pen &lt;a href="https://codepen.io/aholmes/pen/zxBJMg"&gt;
  Time color&lt;/a&gt; by Aaron Holmes (&lt;a href="https://codepen.io/aholmes"&gt;@aholmes&lt;/a&gt;)
  on &lt;a href="https://codepen.io"&gt;CodePen&lt;/a&gt;.&lt;/span&gt;
&lt;/p&gt;
&lt;script async src="https://public.codepenassets.com/embed/index.js"&gt;&lt;/script&gt;&lt;/section&gt;
&lt;section id="the-html-and-css"&gt;
&lt;h2&gt;The HTML and CSS&lt;a class="headerlink" href="#the-html-and-css" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First set the attribute on your element. I decided to call it &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;data-text&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;time&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;data-text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;00 : 00 : 00&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We only need two lines of CSS to get the attribute function to display.&lt;/p&gt;
&lt;div class="highlight-css notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;after&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nv"&gt;-text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Normally the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;content&lt;/span&gt;&lt;/code&gt; attribute is set to a static string, but there’s also the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attr()&lt;/span&gt;&lt;/code&gt; function that let’s you use an attribute value on your element instead.&lt;/p&gt;
&lt;p&gt;You can find more information about &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attr()&lt;/span&gt;&lt;/code&gt; on &lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/CSS/attr"&gt;MDN&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Browser compatibility is sketchy at best. There are some gotchas to be careful of too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="updating-the-content-with-javascript"&gt;
&lt;h2&gt;Updating the content with JavaScript&lt;a class="headerlink" href="#updating-the-content-with-javascript" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are no DOM API methods that let us access &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;::after&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;::before&lt;/span&gt;&lt;/code&gt; psuedo-elements with JavaScript. We can at least use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;attr()&lt;/span&gt;&lt;/code&gt; function in conjunction with the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setAttribute()&lt;/span&gt;&lt;/code&gt; method or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;dataset&lt;/span&gt;&lt;/code&gt; property to change the content of the psuedo-elements.&lt;/p&gt;
&lt;p&gt;With the HTML element above, here’s how we can change the value of the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;data-text&lt;/span&gt;&lt;/code&gt; attribute. This change will then be rendered with our CSS rules to display new text in the psuedo-element.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;time&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;15:30:25&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-text&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Theoretically that should be all we need! With a little more code to set the correct time value on a loop, the site will show a new time every second.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="a-repaint-issue-on-chrome-version-39-0-2171-95"&gt;
&lt;h2&gt;A repaint issue on Chrome version 39.0.2171.95&lt;a class="headerlink" href="#a-repaint-issue-on-chrome-version-39-0-2171-95" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My experiment didn’t go perfectly. I discovered that changing the attribute value does &lt;em&gt;not&lt;/em&gt; always trigger a repaint, and thus the new time would not display. I have not figured out exactly what caused this; it was sporadic, and I wonder if it’s partly related to how CodePen works.&lt;/p&gt;
&lt;p&gt;Thankfully there’s an easy way to trigger a repaint. It’s not exactly the prettiest solution, but it does ensure the new time is displayed each second.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offsetHeight&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;timeHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="a-little-extra"&gt;
&lt;h2&gt;A little extra&lt;a class="headerlink" href="#a-little-extra" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The original code uses the time values as the hexidecimal values for the background color. A time of 9 hours, 23 minutes, and 40 seconds give you the hex color &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;#092340&lt;/span&gt;&lt;/code&gt;.
Given that this will increment the 0th digit for each red, green, and blue hex value, we end up with a similar color for each second, minute, and hour.&lt;/p&gt;
&lt;p&gt;If the time value is 09 23 40, then our RGB values are as follows.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Hex&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Dec&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Conversion&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Red&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0x09&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;9&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(0 × 16¹) + (9 × 16⁰)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Green&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0x23&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;35&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(2 × 16¹) + (3 × 16⁰)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Blue&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0x40&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;64&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(4 × 16¹) + (0 × 16⁰)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;After 1 second, blue becomes 65, then 66, 67, 68, and so on. This is a very slow increase!&lt;/p&gt;
&lt;p&gt;Additionally, because there are only 24 hours in a day, 60 minutes to an hour, and 60 seconds to a minute, our scale of colors is limited. Red ranges from 0 - 23, green 0 - 59, and blue 0 - 59.&lt;/p&gt;
&lt;p&gt;Here’s a visualization of all possible red, green, and blue values individually.&lt;/p&gt;
&lt;div id="red"&gt;&lt;/div&gt;
&lt;div id="green"&gt;&lt;/div&gt;
&lt;div id="blue"&gt;&lt;/div&gt;&lt;p&gt;To get a wider range of colors, each hexidecimal string value can be flipped. For example, 9 is “09” as a string, and “90” flipped. Here’s what our example above looks like with the values flipped.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Hex&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Dec&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Flipped String&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Red&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0x09&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;9&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;90&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Green&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0x23&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;35&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;53&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;&lt;strong&gt;Blue&lt;/strong&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0x40&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;64&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;46&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And here’s the range of colors and the pattern in which they occur.&lt;/p&gt;
&lt;div id="red2"&gt;&lt;/div&gt;
&lt;div id="green2"&gt;&lt;/div&gt;
&lt;div id="blue2"&gt;&lt;/div&gt;&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2014/using_time_as_a_color_generator.html"/><category term="JavaScript"/><category term="CSS"/><category term="Codepen"/><category term="Fiddle"/><category term="Experimental"/><published>2014-12-20T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2014/speech_synthesis_on_windows_phone_8_1.html</id><title>Speech Synthesis on Windows Phone 8.1</title><updated>2025-08-03T01:20:00+00:00</updated><content>&lt;section id="speech-synthesis-on-windows-phone-8-1"&gt;
&lt;h1&gt;Speech Synthesis on Windows Phone 8.1&lt;a class="headerlink" href="#speech-synthesis-on-windows-phone-8-1" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2014-12-07"&gt;7 December 2014&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/c.html"&gt;C#&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/net.html"&gt;.NET&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/windows-phone.html"&gt;Windows-Phone&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/speech.html"&gt;Speech&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I recently wrote an application to make my phone report current Los Angeles traffic conditions. I used the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Windows.Media.SpeechSynthesis&lt;/span&gt;&lt;/code&gt; namespace to read in either a plain-text string, or an &lt;a class="reference external" href="http://www.w3.org/TR/speech-synthesis/"&gt;SSML&lt;/a&gt;-formatted string, and to speak it until the end. It turns out that speech synthesis with .NET libraries is incredibly simple, but some information takes a little effort to find. For me, searching for “text-to-speech windows phone 8.1” shows me a bunch of results for how to accomplish this with Silverlight! Definitely not what I want.&lt;/p&gt;
&lt;section id="the-setup"&gt;
&lt;h2&gt;The setup&lt;a class="headerlink" href="#the-setup" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because this was for a Windows Phone application, I needed a way to access a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MediaElement&lt;/span&gt;&lt;/code&gt; object to play, pause, and stop the speaking if I pressed a button to do this. I opted to create a private object on my &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;MainPage&lt;/span&gt;&lt;/code&gt; instance.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;PhoneTraffic&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sealed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;partial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MainPage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MediaElement&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MainPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InitializeComponent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NavigationCacheMode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NavigationCacheMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Required&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MediaElement&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;From here, we instantiate a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SpeechSynthesizer&lt;/span&gt;&lt;/code&gt; object.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SpeechSynthesizer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then we need to pass a &lt;em&gt;plain-text&lt;/em&gt; string into the synthesizer, and store the outputted stream so we can set it on the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;media&lt;/span&gt;&lt;/code&gt; object.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SynthesizeTextToStreamAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then set the stream source on our &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;media&lt;/span&gt;&lt;/code&gt; object.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now we’re ready to tell the phone to play, pause, or stop the speaking of our sentence. Here’s how it looks in my application.&lt;/p&gt;
&lt;section id="using-plain-text"&gt;
&lt;h3&gt;Using plain-text&lt;a class="headerlink" href="#using-plain-text" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;GetTrafficButton_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RoutedEventArgs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incidents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeserializeObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TrafficIncident&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trafficJson&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;incidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SpeechSynthesizer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SynthesizeTextToStreamAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;There are no incidents right now.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SpeechSynthesizer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;toSay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incidents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;toSay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; At &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; there was a &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Incident&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; incident at &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incident&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;toSay&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incidents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; and another &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SynthesizeTextToStreamAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;toSay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;My pause and stop methods are simpler:&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;PausedSpeechButton_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RoutedEventArgs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pause&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;StopSpeechButton_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;RoutedEventArgs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="using-ssml"&gt;
&lt;h3&gt;Using SSML&lt;a class="headerlink" href="#using-ssml" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If you want to use SSML, use the method &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SynthesizeSsmlToStreamAsync&lt;/span&gt;&lt;/code&gt; instead of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SynthesizeTextToStreamAsync&lt;/span&gt;&lt;/code&gt; and pass an SSML-formatted string to it.&lt;/p&gt;
&lt;p&gt;My application supports both modes. I create the SSML string on my API server, and the phone consumes it. Here’s what the code looks like (replaces the “else” block in the plain-text example).&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SpeechSynthesizer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;synth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SynthesizeSsmlToStreamAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ssml&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Play&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here are some resources I used.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Wikipedia &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language"&gt;Speech Synthesis Markup Language&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;W3 &lt;a class="reference external" href="http://www.w3.org/TR/speech-synthesis/"&gt;Speech Synthesis Markup Language (SSML) Version 1.0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microsoft MSDN &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/library/windows.media.speechsynthesis.aspx"&gt;Windows.Media.SpeechSynthesis namespace&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Microsoft MSDN &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/library/dd450828(v=office.13).aspx"&gt;SSML say-as Examples&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Jayway &lt;a class="reference external" href="http://www.jayway.com/2014/04/15/windows-phone-8-1-for-developers-texttospeech/"&gt;Windows Phone 8.1 for Developers - Text to speech&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2014/speech_synthesis_on_windows_phone_8_1.html"/><category term="C#"/><category term=".NET"/><category term="Windows-Phone"/><category term="Speech"/><published>2014-12-07T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2014/my_ghost_theme_casper_for_developers.html</id><title>My Ghost theme; Casper for developers</title><updated>2025-08-06T20:56:37+00:00</updated><content>&lt;section id="my-ghost-theme-casper-for-developers"&gt;
&lt;h1&gt;My Ghost theme; Casper for developers&lt;a class="headerlink" href="#my-ghost-theme-casper-for-developers" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2014-12-01"&gt;1 December 2014&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/ghost.html"&gt;Ghost&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I started using Ghost about a week ago. My (honest) first impression was that code blocks are unstyled and uneditable, which is a huge pet peeve of mine. I &lt;a class="reference internal" href="displaying_code_with_ace_on_ghost.html#displaying-code-with-ace-on-ghost"&gt;&lt;span class="std std-ref"&gt;fixed that&lt;/span&gt;&lt;/a&gt; problem by forking Casper and adding Ace editor. You can find my fork of the theme here: &lt;a class="reference external" href="https://github.com/aholmes/Casper"&gt;https://github.com/aholmes/Casper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For whatever reason, I still wasn’t satisfied with things, so I kept changing bits. Here’s a list of the changes I made, and what is available to you if you use this theme.&lt;/p&gt;
&lt;p&gt;Hope you enjoy, and I will definitely accept pull requests if you send them!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#ace-editor"&gt;Ace Editor&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#google-comments"&gt;Google+ comments&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#disqus-comments"&gt;Disqus comments&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#google-analytics"&gt;Google Analytics&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#linkable-headers"&gt;Linkable headers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference internal" href="#fixed-position-header-and-footer-across-the-site"&gt;Fixed-position header and footer across the site&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="ace-editor"&gt;
&lt;h2&gt;Ace editor&lt;a class="headerlink" href="#ace-editor" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As mentioned above, my first change was to add &lt;a class="reference external" href="http://ace.c9.io/"&gt;Ace editor&lt;/a&gt;. You can see it in action in this post, but here’s a screenshot as well.&lt;/p&gt;
&lt;a class="reference external image-reference" href="javascript_vector_animations_with_divs_or_canvas.html#the-rendering-method-itself-part-two"&gt;&lt;img alt="../_images/javascript_ace_capture.jpg" src="../_images/javascript_ace_capture.jpg" /&gt;
&lt;/a&gt;
&lt;/section&gt;
&lt;section id="google-comments"&gt;
&lt;h2&gt;Google+ comments&lt;a class="headerlink" href="#google-comments" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Casper, and Ghost in general, doesn’t have a commenting system for posts out-of-the-box. My first pass at adding them was by adding some JS and CSS to use Google+’s commenting system.&lt;/p&gt;
&lt;p&gt;This feature is optional in my theme.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/aholmes/Casper/blob/master/post.hbs#L76-L86"&gt;Code link&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Uncomment this to add Google Plus comments to your posts. --&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;!--div id=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;    (function ()&lt;/span&gt;
&lt;span class="cm"&gt;    {&lt;/span&gt;
&lt;span class="cm"&gt;        // Load G+ comments&lt;/span&gt;
&lt;span class="cm"&gt;        var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;&lt;/span&gt;
&lt;span class="cm"&gt;        po.src = &amp;#39;https://apis.google.com/js/client:plusone.js?onload=gapiOnload&amp;#39;;&lt;/span&gt;
&lt;span class="cm"&gt;        var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);&lt;/span&gt;
&lt;span class="cm"&gt;    })();&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;/script--&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="disqus-comments"&gt;
&lt;h2&gt;Disqus comments&lt;a class="headerlink" href="#disqus-comments" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I wasn’t satisfied with Google+ comments, so I added this next. In &lt;a class="reference external" href="https://github.com/aholmes/Casper/tree/aholmes"&gt;my branch&lt;/a&gt; of this theme, I have Google+ comments disabled, and Disqus enabled.&lt;/p&gt;
&lt;p&gt;This feature is optional in my theme.&lt;/p&gt;
&lt;p&gt;Here’s what the module looks like in each post’s footer.&lt;/p&gt;
&lt;img alt="../_images/footer_capture.jpg" src="../_images/footer_capture.jpg" /&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/aholmes/Casper/blob/master/post.hbs#L88-L98"&gt;Code link&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Uncomment this to add Disqus comments to your posts. --&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;!--div id=&amp;quot;disqus_thread&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;    var disqus_shortname = &amp;#39;REPLACE WITH DISQUS FORUM NAME&amp;#39;;&lt;/span&gt;
&lt;span class="cm"&gt;    (function ()&lt;/span&gt;
&lt;span class="cm"&gt;    {&lt;/span&gt;
&lt;span class="cm"&gt;        var dsq = document.createElement(&amp;#39;script&amp;#39;); dsq.type = &amp;#39;text/javascript&amp;#39;; dsq.async = true;&lt;/span&gt;
&lt;span class="cm"&gt;        dsq.src = &amp;#39;//&amp;#39; + disqus_shortname + &amp;#39;.disqus.com/embed.js&amp;#39;;&lt;/span&gt;
&lt;span class="cm"&gt;        (document.getElementsByTagName(&amp;#39;head&amp;#39;)[0] || document.getElementsByTagName(&amp;#39;body&amp;#39;)[0]).appendChild(dsq);&lt;/span&gt;
&lt;span class="cm"&gt;    })();&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;/script--&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="google-analytics"&gt;
&lt;h2&gt;Google Analytics&lt;a class="headerlink" href="#google-analytics" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I wanted to track how much traffic my blog would get, so I added Google Analytics.&lt;/p&gt;
&lt;p&gt;This feature is optional in my theme.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/aholmes/Casper/blob/master/default.hbs#L19-L32"&gt;Code link&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- Uncomment this to enable Google Analytics. --&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;!--script&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;    (function (i, s, o, g, r, a, m)&lt;/span&gt;
&lt;span class="cm"&gt;    {&lt;/span&gt;
&lt;span class="cm"&gt;        i[&amp;#39;GoogleAnalyticsObject&amp;#39;] = r; i[r] = i[r] || function ()&lt;/span&gt;
&lt;span class="cm"&gt;        {&lt;/span&gt;
&lt;span class="cm"&gt;        (i[r].q = i[r].q || []).push(arguments)&lt;/span&gt;
&lt;span class="cm"&gt;        }, i[r].l = 1 * new Date(); a = s.createElement(o),&lt;/span&gt;
&lt;span class="cm"&gt;        m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)&lt;/span&gt;
&lt;span class="cm"&gt;    })(window, document, &amp;#39;script&amp;#39;, &amp;#39;//www.google-analytics.com/analytics.js&amp;#39;, &amp;#39;ga&amp;#39;);&lt;/span&gt;
&lt;span class="cm"&gt;    ga(&amp;#39;create&amp;#39;, &amp;#39;CHANGE THIS TO YOUR KEY&amp;#39;, &amp;#39;auto&amp;#39;);&lt;/span&gt;
&lt;span class="cm"&gt;    ga(&amp;#39;send&amp;#39;, &amp;#39;pageview&amp;#39;);&lt;/span&gt;
&lt;span class="cm"&gt;&amp;lt;/script--&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="linkable-headers"&gt;
&lt;h2&gt;Linkable headers&lt;a class="headerlink" href="#linkable-headers" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Casper was lacking a way to get the direct link to any headers in my posts. This feature shows a “link” icon when the header is hovered over. When the link is clicked, the URL hash is changed, and the link becomes “active.” The currently linked-to header always displays the link until another header is clicked.&lt;/p&gt;
&lt;p&gt;Here’s what a header looks like when hovered over:&lt;/p&gt;
&lt;img alt="../_images/hovered_link_header.jpg" src="../_images/hovered_link_header.jpg" /&gt;
&lt;p&gt;Here’s what a header looks like when it’s the active link:&lt;/p&gt;
&lt;img alt="../_images/active_link_header.jpg" src="../_images/active_link_header.jpg" /&gt;
&lt;/section&gt;
&lt;section id="fixed-position-header-and-footer-across-the-site"&gt;
&lt;h2&gt;Fixed-position header and footer across the site&lt;a class="headerlink" href="#fixed-position-header-and-footer-across-the-site" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I found another theme I liked called &lt;a class="reference external" href="https://github.com/ScottSmith95/Decode-for-Ghost"&gt;Decode for Ghost&lt;/a&gt; that allowed blog content to flow over the header. It also didn’t cause the header image to take up the entire screen on the home page (another pet peeve of mine). Unfortunately, I didn’t like other parts of the theme, so I adopted the fixed header and footer idea to my fork of Casper.&lt;/p&gt;
&lt;p&gt;This one is harder to capture with screenshots, but here they are anyway.&lt;/p&gt;
&lt;p&gt;Here’s what the home page looks like when first loaded. Notice that the image doesn’t take over the entire screen.&lt;/p&gt;
&lt;img alt="../_images/home.jpg" src="../_images/home.jpg" /&gt;
&lt;p&gt;Here’s what the home page looks like when scrolled part way. Notice that the content covers the header, and the header has not moved at all.&lt;/p&gt;
&lt;img alt="../_images/home_scrolled.jpg" src="../_images/home_scrolled.jpg" /&gt;
&lt;p&gt;Lastly, here’s what the footer looks like. The content scrolls over this as well.&lt;/p&gt;
&lt;img alt="../_images/footer.jpg" src="../_images/footer.jpg" /&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2014/my_ghost_theme_casper_for_developers.html"/><category term="Ghost"/><published>2014-12-01T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2014/running_entity_framework_migrations_on_application_start.html</id><title>Running Entity Framework Migrations on Application Start</title><updated>2025-08-06T19:26:29+00:00</updated><content>&lt;section id="running-entity-framework-migrations-on-application-start"&gt;
&lt;h1&gt;Running Entity Framework Migrations on Application Start&lt;a class="headerlink" href="#running-entity-framework-migrations-on-application-start" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2014-11-28"&gt;28 November 2014&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/c.html"&gt;C#&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/entity-framework.html"&gt;Entity Framework&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/asp-net.html"&gt;ASP.NET&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/net.html"&gt;.NET&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://www.asp.net/entity-framework"&gt;Entity Framework&lt;/a&gt; is an ORM developed by Microsoft. It has a useful set of tools and conventions for automatically managing database schema changes called &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/data/jj591621.aspx"&gt;Code First Migrations&lt;/a&gt;. My only gripe is that, unless you are willing to do some digging, migrations can only be managed with the &lt;a class="reference external" href="http://microsoft.com/powershell"&gt;PowerShell&lt;/a&gt; commands &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Add-Migration&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Update-Database&lt;/span&gt;&lt;/code&gt;. Even &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/data/jj554735.aspx"&gt;automatic migrations&lt;/a&gt; require users to run &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Update-Database&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There may be many reasons you would want to have migrations automatically run, rather than managing them manually. One reason for me is that I did not want to require that other developers on my team manually run &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Update-Database&lt;/span&gt;&lt;/code&gt; any time there is a database schema change. I feel that it is disruptive to the philosophy of &lt;a class="reference external" href="https://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280"&gt;Getting Shit Done&lt;/a&gt;. On the flip side, not manually managing your databases runs the risk of things breaking and going unnoticed, so use this with care.&lt;/p&gt;
&lt;p&gt;Well, I did the digging, and here’s what I came up with to run migrations when an ASP.NET website starts.&lt;/p&gt;
&lt;section id="update-time-class-page-date-datetime-2014-11-29-2014-11-29-time"&gt;
&lt;h2&gt;Update &lt;time class="page-date" datetime="2014-11-29"&gt;2014-11-29&lt;/time&gt;&lt;a class="headerlink" href="#update-time-class-page-date-datetime-2014-11-29-2014-11-29-time" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Somehow I had forgotten that using the database initializer &lt;a class="reference external" href="http://msdn.microsoft.com/en-us/library/hh829293%28v=vs.113%29.aspx"&gt;MigrateDatabaseToLatestVersion&lt;/a&gt; is another way to accomplish this. Definitely give it a once over.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;My &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ApplicationDbContext.cs&lt;/span&gt;&lt;/code&gt; is fairly straightforward.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;MyNamespace.DAL&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IdentityDbContext&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationUser&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="cm"&gt;/* This is a static class I use to store environment settings from Web.config. */&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EnvironmentSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnectionString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;throwIfV1Schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseDatabaseNullSemantics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cp"&gt;#if DEBUG&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Diagnostics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Debug&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This is my &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Migrations/Configuration.cs&lt;/span&gt;&lt;/code&gt; file.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;MyNamespace.DAL.Migrations&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ConfigurationBase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DbMigrationsConfiguration&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ConfigurationBase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;AutomaticMigrationsEnabled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;ContextKey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;MyNamespace.DAL.ApplicationDbContext&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;protected&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt;                Do some stuff to get your database connection string(s).&lt;/span&gt;
&lt;span class="cm"&gt;                I store mine in Web.config, and initialize a static class with&lt;/span&gt;
&lt;span class="cm"&gt;                the values read from that file. This is the same class referenced&lt;/span&gt;
&lt;span class="cm"&gt;                in my ApplicationDbContext.&lt;/span&gt;
&lt;span class="cm"&gt;            */&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt;            I use a different class for each environment I need to account for.&lt;/span&gt;
&lt;span class="cm"&gt;            That includes Local, Debug, Stage, and Production.&lt;/span&gt;
&lt;span class="cm"&gt;        */&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sealed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ConfigurationBase&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Local&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;local&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And lastly, my &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Startup.cs&lt;/span&gt;&lt;/code&gt; file. This is the important bit.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;MyNamespace&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;partial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Startup&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="cp"&gt;#if DEBUG&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;MigrateDB&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;MigrateDB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EnvironmentSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;migratorConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyNamespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DAL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migrations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Local&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;migratorConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TargetDatabase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Infrastructure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DbConnectionInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnectionString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbMigrator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DbMigrator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migratorConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;dbMigrator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Let’s break it down a little bit.&lt;/p&gt;
&lt;p&gt;First, I only want to run this in my debug environments, so I wrapped the call in a preprocessor block.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#if DEBUG&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;MigrateDB&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then I pull my current environment settings from a static class. This class stores my database connection strings. You may need to find another way to pull your database connection strings in.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EnvironmentSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Armed with our migration configuration class and our connection string, we can instantiate a new “migrator config” and attach a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DbConnectionInfo&lt;/span&gt;&lt;/code&gt; instance to it.
Again, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;settings.DatabaseConnections.DatabaseConnectionString()&lt;/span&gt;&lt;/code&gt; comes from my &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EnvironmentSettings&lt;/span&gt;&lt;/code&gt; class, so this will be your own connection string.&lt;/p&gt;
&lt;p&gt;You could add some logic here to use different migration configurations instead of just &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Local&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;migratorConfig&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MyNamespace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DAL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Migrations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Local&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;migratorConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TargetDatabase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Infrastructure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DbConnectionInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnectionString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we instantiate a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;DbMigrator&lt;/span&gt;&lt;/code&gt; and call &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Update()&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight-csharp notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dbMigrator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DbMigrator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migratorConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;dbMigrator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2014/running_entity_framework_migrations_on_application_start.html"/><category term="C#"/><category term="Entity Framework"/><category term="ASP.NET"/><category term=".NET"/><published>2014-11-28T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2014/javascript_vector_animations_with_divs_or_canvas.html</id><title>JavaScript Vector Animations with Divs or Canvas</title><updated>2025-08-06T19:26:29+00:00</updated><content>&lt;section id="javascript-vector-animations-with-divs-or-canvas"&gt;
&lt;h1&gt;JavaScript Vector Animations with Divs or Canvas&lt;a class="headerlink" href="#javascript-vector-animations-with-divs-or-canvas" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2014-11-28"&gt;28 November 2014&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/javascript.html"&gt;JavaScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/canvas.html"&gt;Canvas&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/pixi-js.html"&gt;Pixi.js&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/animation.html"&gt;Animation&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/codepen.html"&gt;Codepen&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/github.html"&gt;GitHub&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/fiddle.html"&gt;Fiddle&lt;/a&gt;&lt;/p&gt;
&lt;p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="jOdYeb" data-pen-title="Vector Animations" data-user="aholmes" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;"&gt;
  &lt;span&gt;See the Pen &lt;a href="https://codepen.io/aholmes/pen/jOdYeb"&gt;
  Vector Animations&lt;/a&gt; by Aaron Holmes (&lt;a href="https://codepen.io/aholmes"&gt;@aholmes&lt;/a&gt;)
  on &lt;a href="https://codepen.io"&gt;CodePen&lt;/a&gt;.&lt;/span&gt;
&lt;/p&gt;
&lt;script async src="https://public.codepenassets.com/embed/index.js"&gt;&lt;/script&gt;&lt;section id="what-s-this-all-about"&gt;
&lt;h2&gt;What’s this all about?&lt;a class="headerlink" href="#what-s-this-all-about" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A few months ago I found the post &lt;a class="reference external" href="http://zulko.github.io/blog/2014/09/20/vector-animations-with-python/"&gt;Vector animations with Python&lt;/a&gt;. I thought the presented demos were very cool, and the code interesting, but I was disappointed with the lack of interactivity. You can’t very well change a GIF while you’re watching it!&lt;/p&gt;
&lt;p&gt;Because of that, I was inspired to recreate the &lt;a class="reference external" href="https://imgur.com/inspired-by-dave-whyte-animation-6rx7SUz"&gt;first example&lt;/a&gt;. I started with rendering the animation with a bunch of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; elements, and then I moved onto to rendering the animation with in a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; element using &lt;a class="reference external" href="http://www.pixijs.com/"&gt;Pixi.js&lt;/a&gt;. You can play with the codepen above to alter the animation’s look and behavior.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="the-html"&gt;
&lt;h2&gt;The HTML&lt;a class="headerlink" href="#the-html" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I wanted to keep the HTML for this demo simple. A single &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; exists on the page which acts as the container for either the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; element, or the list of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; elements. Some HTML exists to handle the options dialog as well.&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;&amp;lt;!-- This block is for the options dialog. --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;options&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hide-options&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hide Options&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;opacity&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; Opacity&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;inverse&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; Inverse&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;reverse&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; Reverse&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;chill&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; Chill&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;running&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;checked&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;checked&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; Running&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;colorbg&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;#FFFFFF&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; BG color&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;colorborder&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;#000000&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; Border color&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;range&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;10&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;800&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;400&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;width&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; Width&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;range&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-60&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;60&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;20&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fps&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; FPS&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;reset&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Reset&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fullscreen&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Fullscreen&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;toggle-options&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;show-options&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Show Options&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="cm"&gt;&amp;lt;!-- This is the container for the animation. It&amp;#39;s really all we need. --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;container&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="accomplishing-this-with-div"&gt;
&lt;h2&gt;Accomplishing this with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;a class="headerlink" href="#accomplishing-this-with-div" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My first approach with this was to render the animations with a bunch of div elements. I used JavaScript to recalculate their positions relative to their container on each “tick” (using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;requestAnimFrame()&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;
&lt;section id="application-loop"&gt;
&lt;h3&gt;Application loop&lt;a class="headerlink" href="#application-loop" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The script has a main application loop that is a function called run(). Because this is JavaScript, we can’t use a real while loop, or the browser would never repaint anything.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Start the application loop.&lt;/span&gt;
&lt;span class="cm"&gt; * @param {Function} make_frame The method returned from bootstrap().&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fps&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frameRate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;make_frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// continue painting new frames when not running, but don&amp;#39;t animate the disks&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// this way, chill mode, with, and opacity can be changed when the frames are &amp;quot;still.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;running&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;requestAnimFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;make_frame&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;makeFrameMethod&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The animation is bootstrapped at the very end with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;run()&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This same method is used by both the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; approach. We run &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;run.make_frame&lt;/span&gt; &lt;span class="pre"&gt;=&lt;/span&gt; &lt;span class="pre"&gt;makeFrameMethod;&lt;/span&gt;&lt;/code&gt; to generate the method we need to use based on the “mode” option, which is either “dom” or “canvas”.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="bootstrapping-the-div-rendering-method"&gt;
&lt;h2&gt;Bootstrapping the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; rendering method&lt;a class="headerlink" href="#bootstrapping-the-div-rendering-method" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Okay, here’s the fun part. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;makeFrameMethod&lt;/span&gt;&lt;/code&gt; does two things when running in “dom” mode.&lt;/p&gt;
&lt;p&gt;First, we set up some run-time parameters. These parameters are used in “canvas” mode as well.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;delay_between_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ndisks_per_cycle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ndisks_per_cycle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then we create a bunch of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; elements and store them in an array. This we, we avoid creating a bunch of elements during each animation frame, and we don’t have to make calls to the DOM to get properties of the existing elements. This is different from the GIF rendering method, which creates a blank frame and draws new circles for each frame.&lt;/p&gt;
&lt;p&gt;We create two circles here to act as the containers for the whole animation. If the site background is not black, you would see a black stroke around the inner circle.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;container&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;circle1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.65&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;circle1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;circle1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;circle2&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;circle1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;circle1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;circle1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we can push new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; elements into an array and add them to the DOM.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;disks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You may have noticed the code is calling &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;new&lt;/span&gt; &lt;span class="pre"&gt;Disk(...)&lt;/span&gt;&lt;/code&gt;. Disk is a helper method to create a new DOM element. The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setParams&lt;/span&gt;&lt;/code&gt; method ensures that the disk will be positioned correctly.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * The object container for the disks that animate&lt;/span&gt;
&lt;span class="cm"&gt; * @param {Number} radius Radius of disk&lt;/span&gt;
&lt;span class="cm"&gt; * @param {[Number, Number]} xy cartesian coords of disk&lt;/span&gt;
&lt;span class="cm"&gt; * @constructor&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;div&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;disk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Set the radius and cartesian coords of the disk&lt;/span&gt;
&lt;span class="cm"&gt; * @param {Number} radius&lt;/span&gt;
&lt;span class="cm"&gt; * @param {Number} xy&lt;/span&gt;
&lt;span class="cm"&gt; * @returns {Disk}&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setParams&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;px&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;px&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;px&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;px&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="the-rendering-method-itself"&gt;
&lt;h3&gt;The rendering method itself&lt;a class="headerlink" href="#the-rendering-method-itself" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Once &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;makeFrameMethod&lt;/span&gt;&lt;/code&gt; finishes initializing the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; elements that are actually animated, it then creates and returns the method that will handle positioning each &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; on every frame.&lt;/p&gt;
&lt;p&gt;I am not particularly skilled at math, and will do a terrible job explaining how this works. However, you can read up on &lt;a class="reference external" href="http://www.mathsisfun.com/polar-cartesian-coordinates.html"&gt;calculating polar coordinates&lt;/a&gt; to better understand the code below.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;color&lt;/span&gt;&lt;/code&gt; variable is just for some extra fun to variably change the opacity of a few circles along the horizontal plane of the animation.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;make_frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ndisks_per_cycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;delay_between_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;polar2cart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;circle2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ndisks_per_cycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;circle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;disks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;setParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now whenever &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;requestAnimFrame(run)&lt;/span&gt;&lt;/code&gt; succeeds, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;make_frame(t)&lt;/span&gt;&lt;/code&gt; will iterate over every circle and reposition them. The end result is a very cool animation looking like an endless circle of circles flowing out of the center of the container.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="accomplishing-this-with-canvas"&gt;
&lt;h2&gt;Accomplishing this with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;a class="headerlink" href="#accomplishing-this-with-canvas" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;While the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; method works, it’s unfortunately very inefficient. Even when using GPU rendering with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;.disk&lt;/span&gt; &lt;span class="pre"&gt;{&lt;/span&gt; &lt;span class="pre"&gt;transform&lt;/span&gt; &lt;span class="pre"&gt;:&lt;/span&gt; &lt;span class="pre"&gt;translate3d(0,&lt;/span&gt; &lt;span class="pre"&gt;0,&lt;/span&gt; &lt;span class="pre"&gt;0);&lt;/span&gt; &lt;span class="pre"&gt;}&lt;/span&gt;&lt;/code&gt;, it’s just too expensive and chugs along. Canvas, on the other hand, is perfect for animations. Previously, I worked with the raw DOM API when toying around with an &lt;a class="reference external" href="https://github.com/aholmes/Ascension"&gt;online Ascension clone&lt;/a&gt;. I didn’t want to do that this time, so I used &lt;a class="reference external" href="http://www.pixijs.com/"&gt;Pixi.js&lt;/a&gt;, which saved me hours of work.&lt;/p&gt;
&lt;p&gt;All the methods for the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; approach to this project have the same name as the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; approach. Only the inner-workings have changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="bootstrapping-the-canvas-rendering-method"&gt;
&lt;h2&gt;Bootstrapping the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; rendering method&lt;a class="headerlink" href="#bootstrapping-the-canvas-rendering-method" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We have to do a little more work to get set up using &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Both of these variables are meant to store objects and functions for rendering with Pixi.js. This was, we don’t need to constantly recreate things.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;getGraphics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;getGraphics()&lt;/span&gt;&lt;/code&gt; returns the shape-drawing object in Pixi.js.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;getGraphics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PIXI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginFill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hex2Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Hex2Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;getGraphics&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Reset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;getGraphics&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PIXI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Disk&lt;/span&gt;&lt;/code&gt; class has changed as well. It now creates a new circle object from the Pixi.js Graphics object. &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Disk.prototype.setParams&lt;/span&gt;&lt;/code&gt; is now a NOOP.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;drawCircle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;xy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we create the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; element and add it to the DOM.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PIXI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoDetectRenderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mf"&gt;0.42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mf"&gt;0.42&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// view&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// transparent&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// antialias&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;canvas&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="the-rendering-method-itself-part-two"&gt;
&lt;h3&gt;The rendering method itself (part two)&lt;a class="headerlink" href="#the-rendering-method-itself-part-two" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;canvas&amp;gt;&lt;/span&gt;&lt;/code&gt; method, the rendering method is very similar to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/code&gt; methods. New positions are calculated, and circle are drawn. What’s different, however, is that each frame is cleared before redrawing, similar to how the GIF method renders each frame.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;make_frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Reset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ndisks_per_cycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;delay_between_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;total_number_of_disks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;polar2cart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;angle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;runOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ndisks_per_cycle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Graphics&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;endFill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginFill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hex2Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Hex2Num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diskStyles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;diskOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cartCoords&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runModeHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="wrap-up"&gt;
&lt;h2&gt;Wrap up&lt;a class="headerlink" href="#wrap-up" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;That’s just about the end of the interesting bits of this demo. It all boils down to drawing circle in the correct place, and porting the concept to JavaScript. The dialog on the page allows the user to change colors, the size of the circles, the rate at which frames are renered, and so on. The code is available on &lt;a class="reference external" href="https://github.com/aholmes/vectoranimations"&gt;GitHub&lt;/a&gt; if you’d like to see how the rest works.&lt;/p&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;
&lt;p&gt;-&lt;em&gt;Aaron Holmes&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2014/javascript_vector_animations_with_divs_or_canvas.html"/><category term="JavaScript"/><category term="Canvas"/><category term="Pixi.js"/><category term="Animation"/><category term="Codepen"/><category term="GitHub"/><category term="Fiddle"/><published>2014-11-28T00:00:00+00:00</published></entry><entry><id>https://aaronholmes.net/2014/displaying_code_with_ace_on_ghost.html</id><title>Displaying code with Ace on Ghost</title><updated>2025-08-06T19:26:29+00:00</updated><content>&lt;section id="displaying-code-with-ace-on-ghost"&gt;
&lt;h1&gt;Displaying code with Ace on Ghost&lt;a class="headerlink" href="#displaying-code-with-ace-on-ghost" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;&lt;time class="page-date" datetime="2014-11-28"&gt;28 November 2014&lt;/time&gt;&lt;/p&gt;
&lt;p class="tags"&gt;&lt;span&gt; &lt;/span&gt;&lt;a class="reference external" href="/_tags/ghost.html"&gt;Ghost&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/ace.html"&gt;Ace&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/theme.html"&gt;Theme&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/javascript.html"&gt;JavaScript&lt;/a&gt;&lt;span&gt;, &lt;/span&gt;&lt;a class="reference external" href="/_tags/css.html"&gt;CSS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After getting Ghost set up, I was disappointed to see the lack of syntax highlighting in Casper’s codeblocks. Additionally, code posted on sites where I can’t copy, edit, or scroll around is a huge pet peeve of mine. I wanted to provide a usable codeblock for any readers of my site. Having used &lt;a class="reference external" href="http://ace.c9.io/"&gt;Ace&lt;/a&gt; before, I knew it did exactly what I was looking for. After some quick Googling and not finding a solution for this already, I decided to do it myself.&lt;/p&gt;
&lt;section id="update-time-class-page-date-datetime-2014-11-30-2014-11-30-time"&gt;
&lt;h2&gt;Update &lt;time class="page-date" datetime="2014-11-30"&gt;2014-11-30&lt;/time&gt;&lt;a class="headerlink" href="#update-time-class-page-date-datetime-2014-11-30-2014-11-30-time" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You can skip all the work below and use my &lt;a class="reference external" href="https://github.com/aholmes/Casper"&gt;theme&lt;/a&gt;, which includes these changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="adding-ace-to-your-blog"&gt;
&lt;h2&gt;Adding Ace to your blog&lt;a class="headerlink" href="#adding-ace-to-your-blog" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First I copied the Casper theme to a new directory and created “my own” theme.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;content/themes/

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog/content/themes&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;cp&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;casper/&lt;span class="w"&gt; &lt;/span&gt;casper-aholmes
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Edit your “new” theme’s package.json to give it a new name and version number.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog/content/themes&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;vi&lt;span class="w"&gt; &lt;/span&gt;casper-aholmes/package.json
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-json notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Casper-aholmes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;quot;version&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Change back to the root directory for your blog.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog/content/themes&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add Ace as a Git &lt;a class="reference external" href="http://git-scm.com/book/en/v2/Git-Tools-Submodules"&gt;submodule&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;submodule&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;https://github.com/ajaxorg/ace-builds.git&lt;span class="w"&gt; &lt;/span&gt;./content/themes/casper-aholmes/assets/js/ace-builds
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then check out the latest &lt;a class="reference external" href="http://git-scm.com/book/en/v2/Git-Basics-Tagging"&gt;tagged&lt;/a&gt; version:&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;content/themes/casper-aholmes/assets/js/ace-builds/

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog/content/themes/casper-aholmes/assets/js/ace-builds&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;tag
v1.0.0
v1.1.01
v1.1.1
v1.1.2
v1.1.3
v1.1.4
v1.1.5
v1.1.6
v1.1.7
v1.1.8

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog/content/themes/casper-aholmes/assets/js/ace-builds&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;-b&lt;span class="w"&gt; &lt;/span&gt;tags/v1.1.8&lt;span class="w"&gt; &lt;/span&gt;tags/v1.1.8
Checking&lt;span class="w"&gt; &lt;/span&gt;out&lt;span class="w"&gt; &lt;/span&gt;files:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;100&lt;/span&gt;%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1744&lt;/span&gt;/1744&lt;span class="o"&gt;)&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;.
Switched&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;branch&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tags/v1.1.8&amp;#39;&lt;/span&gt;

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog/content/themes/casper-aholmes/assets/js/ace-builds&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;tags/v1.1.8&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Then we need to add the checked out tag to our repository.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;status
&lt;span class="c1"&gt;# On branch master&lt;/span&gt;
&lt;span class="c1"&gt;# Changes not staged for commit:&lt;/span&gt;
&lt;span class="c1"&gt;#   (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)&lt;/span&gt;
&lt;span class="c1"&gt;#   (use &amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#       modified:   content/themes/casper-aholmes/assets/js/ace-builds (new commits)&lt;/span&gt;

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;content/themes/casper-aholmes/assets/js/ace-builds

Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Checked out v1.1.8 from ace-build repository.&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="including-ace-on-your-blog"&gt;
&lt;h2&gt;Including Ace on your blog&lt;a class="headerlink" href="#including-ace-on-your-blog" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that we have Ace available to us, we need to edit the default.hbs file to include ace.js on the page.&lt;/p&gt;
&lt;div class="highlight-bash notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Aaron@PINGU&lt;span class="w"&gt; &lt;/span&gt;~/Source/Repos/aholmes&lt;span class="w"&gt; &lt;/span&gt;blog&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;vi&lt;span class="w"&gt; &lt;/span&gt;content/themes/casper-aholmes/default.hbs
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Add this line after the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;index.js&lt;/span&gt;&lt;/code&gt; inclusion.&lt;/p&gt;
&lt;div class="highlight-html notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;{{asset &amp;quot;js/ace-builds/src-min/ace.js&amp;quot;}}&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rendering-code-blocks-with-ace"&gt;
&lt;h2&gt;Rendering code blocks with Ace&lt;a class="headerlink" href="#rendering-code-blocks-with-ace" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I added this code in a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;/code&gt; block immediately following the ace.js inclusion, but you may want to add it to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;content/themes/casper-aholmes/assets/js/index.js&lt;/span&gt;&lt;/code&gt; instead.&lt;/p&gt;
&lt;div class="highlight-javascript notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pre code&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;newEl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;CODE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;newEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ace-editor&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;newEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// the three-backticks syntax for code blocks in markdown allows you to specify the language name, which Ghost gets set as a class on the code element.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;newEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-language&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/language-([^ ]+)/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;c_cpp&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;edit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newEl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setOptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;minLines&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;maxLines&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;20&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// el.dataset only works in IE11. :(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// c_cpp is a safe bet for most languages I work with.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ace/mode/&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;newEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-language&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// Who needs &amp;lt;pre&amp;gt; when you have Ace? Replace the pre element with the newEl &amp;lt;code&amp;gt; element.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;replaceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This code replaces any instances of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/span&gt;&lt;/code&gt; with a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;&amp;lt;code&amp;gt;&lt;/span&gt;&lt;/code&gt; element that has been initialized with Ace after your site renders. It also supports using different syntax definitions, which you can control for your code blocks by using three backticks instead of tabs when writing your post. Of course, the options in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;setOptions()&lt;/span&gt;&lt;/code&gt; can be changed as well.&lt;/p&gt;
&lt;img alt="../_images/three-backticks.jpg" src="../_images/three-backticks.jpg" /&gt;
&lt;/section&gt;
&lt;section id="css-tweaks"&gt;
&lt;h2&gt;CSS Tweaks&lt;a class="headerlink" href="#css-tweaks" title="Link to this heading"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To override some CSS from Ghost, I needed to use the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ace-editor&lt;/span&gt;&lt;/code&gt; class the JavaScript above adds for us. Open your &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;content/themes/casper-aholmes/assets/css/screen.css&lt;/span&gt;&lt;/code&gt; file and add the following.&lt;/p&gt;
&lt;div class="highlight-css notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;white-space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;pre-wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kp"&gt;-ms-&lt;/span&gt;&lt;span class="k"&gt;word-break&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;break-all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;word-break&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;break-all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I didn’t like that my paragraphs following a code block would “stick” to the bottom of each code block, so I added this CSS to make each paragraph “stick” to the top of each code block following a paragraph. The same holds true for headers, but the margin is smaller.&lt;/p&gt;
&lt;div class="highlight-css notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;margin-top&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.75&lt;/span&gt;&lt;span class="kt"&gt;em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h5&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h6&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="kt"&gt;em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ace-editor&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;-1.75&lt;/span&gt;&lt;span class="kt"&gt;em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;h5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;h6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;-0.4&lt;/span&gt;&lt;span class="kt"&gt;em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;hr class="docutils"&gt;
&lt;div id="disqus_thread"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
    var disqus_shortname = 'aholmes';
    (function ()
    {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
&lt;/script&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</content><link href="https://aaronholmes.net/2014/displaying_code_with_ace_on_ghost.html"/><category term="Ghost"/><category term="Ace"/><category term="Theme"/><category term="JavaScript"/><category term="CSS"/><published>2014-11-28T00:00:00+00:00</published></entry></feed>