<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Simple-Suboptimal-Solutions on Andrew Quinn&#39;s TILs</title>
    <link>https://til.andrew-quinn.me/tags/simple-suboptimal-solutions/</link>
    <description>Recent content in Simple-Suboptimal-Solutions on Andrew Quinn&#39;s TILs</description>
    <image>
      <title>Andrew Quinn&#39;s TILs</title>
      <url>https://til.andrew-quinn.me/papermod-cover.png</url>
      <link>https://til.andrew-quinn.me/papermod-cover.png</link>
    </image>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 20 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://til.andrew-quinn.me/tags/simple-suboptimal-solutions/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Back up your TOTP codes by just printing them</title>
      <link>https://til.andrew-quinn.me/posts/back-up-your-totp-codes-by-just-printing-them/</link>
      <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/back-up-your-totp-codes-by-just-printing-them/</guid>
      <description>&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://til.andrew-quinn.me/img/totp-example-01.png&#34; alt=&#34;PNG of the TOTP code for JBSWY3DPEHPK3PXP.&#34;  /&gt;
&lt;/p&gt;
&lt;p&gt;Scan the Quick Response (QR) code above with your favorite Two-Factor Authentication (2FA) app.
You should get a six digit number, rotating every
30 seconds, that looks something like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;237601
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# as of Wed May 20 09:44:53 AM EEST 2026
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;If you then take the secret key that QR code maps to,
say&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Replacing a 3 GB SQLite database with a 10 MB FST (finite state transducer) binary</title>
      <link>https://til.andrew-quinn.me/posts/replacing-a-3-gb-sqlite-database-with-a-7-mb-fst-finite-state-trandsucer-binary/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/replacing-a-3-gb-sqlite-database-with-a-7-mb-fst-finite-state-trandsucer-binary/</guid>
      <description>&lt;p&gt;&lt;em&gt;Note for
&lt;a href=&#34;https://www.youtube.com/watch?v=aOJOfh2_4PE&#34;&gt;numberphiles&lt;/a&gt;:
all numbers have been rounded to their first significant
digit, because I&amp;rsquo;m a fan of Rob Eastaway&amp;rsquo;s
&lt;a href=&#34;https://robeastaway.com/blog/introducing-zequals&#34;&gt;&amp;ldquo;zequals&amp;rdquo; method&lt;/a&gt;
of getting to the point when it comes to estimation. It&amp;rsquo;s much
more valuable to walk away with the heuristic &amp;ldquo;some dude got
a 300x memory reduction by swapping out a database he hacked
together for a tiny, static, specialized data structure that
does exactly what he needs it to and no more.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>The long death of programming languages</title>
      <link>https://til.andrew-quinn.me/posts/the-long-death-of-programming-languages/</link>
      <pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/the-long-death-of-programming-languages/</guid>
      <description>&lt;p&gt;I wrote my first Clojure program in anger a few months ago.
Only, it&amp;rsquo;s not accurate to
say that I wrote it; AI did most of the writing, and I directed it on what my
design goals were and why.
Architecturally, you could call it was a stateless
&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/architecture/patterns/anti-corruption-layer&#34;&gt;anti-corruption layer&lt;/a&gt;,
yapping between some REST endpoints and some ancient proprietary serialization.&lt;/p&gt;
&lt;p&gt;I had never written a Clojure program of nontrivial size before. Indeed I had
barely touched any Lisp at all
since working through &lt;a href=&#34;https://mitp-content-server.mit.edu/books/content/sectbyfn/books_pres_0/6515/sicp.zip/index.html&#34;&gt;SICP&lt;/a&gt;
during a high school summer vacation, over a decade ago.
That didn&amp;rsquo;t matter. Much more important was emphasizing certain invariants from
the start, like the aforementioned statelessness, which made it very easy to
unit and integration test, which was the true challenge.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Claude Code disproportionately benefits those who touch type</title>
      <link>https://til.andrew-quinn.me/posts/claude-code-disproportionately-benefits-those-who-touch-type/</link>
      <pubDate>Sat, 24 Jan 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/claude-code-disproportionately-benefits-those-who-touch-type/</guid>
      <description>&lt;p&gt;I use Claude Code. I like Claude Code. According to
&lt;a href=&#34;https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04&#34;&gt;Steve Yegge&amp;rsquo;s&lt;/a&gt;
&lt;a href=&#34;http://www.timothyleary.info/8circuit.html&#34;&gt;Eight-Circuit Model of Claudesciousness&lt;/a&gt;,
I&amp;rsquo;m a pretty solid Stage 6, edging into 7 on heavy days.
I think most engineers, most of the time, can get most of
their work done faster with one of these tools than not,
although the force multiplier of that speedup is probably
not as extreme as it is in my case. Why is that?&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Lua is a pretty good config language</title>
      <link>https://til.andrew-quinn.me/posts/lua-is-a-pretty-good-config-language/</link>
      <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/lua-is-a-pretty-good-config-language/</guid>
      <description>&lt;p&gt;Lua and Scheme occupy curiously similar places in my noggin, becuase my
primary use case for both has been as scripting languages embedded into other,
larger projects. Lua of course is basically designed for this job, but it&amp;rsquo;s
a solid intermediate format to target even if you have no immediate intentions
to use the programming language parts at all. A TSV file like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10.0.0.5  192.168.1.1 80  tcp
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10.0.0.6  192.168.1l.1  443 tcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;can be given a lot more structure on the cheap
by writing a small transpiler of sorts to turn it into&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Save your disk, write files directly into RAM with /dev/shm</title>
      <link>https://til.andrew-quinn.me/posts/save-your-disk-write-files-directly-into-ram-with-dev-shm/</link>
      <pubDate>Thu, 26 Jun 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/save-your-disk-write-files-directly-into-ram-with-dev-shm/</guid>
      <description>&lt;p&gt;Given my interest in extending the life of my SD cards and hard drives
as much as possible,
I&amp;rsquo;m surprised I haven&amp;rsquo;t come across &lt;code&gt;/dev/shm&lt;/code&gt; before.
In a word
it&amp;rsquo;s a world-accessible RAM scratchpad, which seems baked right into POSIX,
so that virtually every &lt;del&gt;Unix&lt;/del&gt; EDIT: &lt;em&gt;Linux&lt;/em&gt;
system already has it mounted as a
&lt;code&gt;tmpfs&lt;/code&gt; by default:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;
&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-1&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-1&#34;&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34; id=&#34;hl-0-2&#34;&gt;&lt;a style=&#34;outline:none;text-decoration:none;color:inherit&#34; href=&#34;#hl-0-2&#34;&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;
&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;❯ mount | grep &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;/dev/shm&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmpfs on /dev/shm type tmpfs &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;rw,nosuid,nodev,inode64&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://xkcd.com/1053/&#34;&gt;Today&amp;rsquo;s lucky 10,000, indeed&lt;/a&gt;.
It gets mentioned often in Hacker News comments, but surprisingly I couldn&amp;rsquo;t
find any actual articles talking about it.
The existence of &lt;code&gt;/dev/shm&lt;/code&gt; is a boon for me mostly because it means I never
have to worry about whether &lt;code&gt;/tmp&lt;/code&gt; is &lt;em&gt;really&lt;/em&gt; RAM-based again.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>LLM, JavaScript, GitHub Pages, localStorage: A recipe for free apps anyone can use</title>
      <link>https://til.andrew-quinn.me/posts/llm-javascript-github-pages-localstorage-a-recipe-for-free-apps-anyone-can-use/</link>
      <pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/llm-javascript-github-pages-localstorage-a-recipe-for-free-apps-anyone-can-use/</guid>
      <description>&lt;p&gt;Earlier today on Hacker News
&lt;a href=&#34;https://pontus.granstrom.me/scrappy/&#34;&gt;Scrappy made the rounds&lt;/a&gt;,
with the explicit tagline &amp;ldquo;make little apps for you and your friends&amp;rdquo;.
I always like to see new projects in this vein.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I&amp;rsquo;d like to outline my alternative approach, which&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Works cross-platform and on mobile devices by default,&lt;/li&gt;
&lt;li&gt;Doesn&amp;rsquo;t require any app store tomfoolery,&lt;/li&gt;
&lt;li&gt;Has great uptime built in,&lt;/li&gt;
&lt;li&gt;Gives you just enough data persistence to not get in your way, and&lt;/li&gt;
&lt;li&gt;Is owned by you, forever.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the stack I used to build
&lt;a href=&#34;https://hiandrewquinn.github.io/diet-checklist/&#34;&gt;my diet checklist&lt;/a&gt;,
which I keep as a little icon on my phone&amp;rsquo;s home page.
Here it is:&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Consider the cronslave</title>
      <link>https://til.andrew-quinn.me/posts/consider-the-cronslave/</link>
      <pubDate>Fri, 30 May 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/consider-the-cronslave/</guid>
      <description>&lt;p&gt;As a nerdy, working-class kid who grew up in the 1990s, knowing what time it
actually was was a luxury I rarely had access to before I was 12 or so and my
parents finally got an Internet connection with its attendant link to the
Network Time Protocol. If you had told me I could have not just a watch but an
entire &lt;em&gt;machine&lt;/em&gt; that&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Never lost the time,&lt;/li&gt;
&lt;li&gt;Did what I wanted, how I wanted it, and&lt;/li&gt;
&lt;li&gt;Could be programmed to do what I want, how I want it &lt;em&gt;on a schedule&lt;/em&gt;,&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I would have had to substantially revise my Christmas wishlist.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>LLMs make Perl great again</title>
      <link>https://til.andrew-quinn.me/posts/llms-make-perl-great-again/</link>
      <pubDate>Sat, 24 May 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/llms-make-perl-great-again/</guid>
      <description>&lt;p&gt;Perl 5 went through a long nadir of unpopularity due in large part to its
deserved &amp;ldquo;Write Once, Read Never&amp;rdquo; reputation. So I was surprised to find out
not only is it
&lt;a href=&#34;https://til.andrew-quinn.me/posts/what-programming-languages-come-out-of-the-box-on-debian-12/&#34;&gt;installed by default on Debian&lt;/a&gt;,
it&amp;rsquo;s installed nearly &lt;em&gt;everywhere&lt;/em&gt; by default.
It&amp;rsquo;s even the non-shell scripting language of choice on
&lt;a href=&#34;https://marc.info/?l=openbsd-misc&amp;amp;m=159041121804486&amp;amp;w=2&#34;&gt;OpenBSD&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Perhaps the only thing more impressive than Perl&amp;rsquo;s utter ubiquity is its
longevity. The latest major version of Perl was first released in
&lt;a href=&#34;https://en.wikipedia.org/wiki/Perl_5_version_history&#34;&gt;&lt;em&gt;1994&lt;/em&gt;&lt;/a&gt;. It came into
existence on this planet less than a year after I did. It&amp;rsquo;s even arguably more
portable than the median shell script - different Unices might use Bash, Zsh,
Ksh, or even something newfangled like
&lt;a href=&#34;https://fishshell.com/&#34;&gt;Fish&lt;/a&gt;,
but for the most part a Perl 5 program is a Perl 5 program is a Perl 5 program.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Cross-platform TUIs are easier than cross-platform GUIs</title>
      <link>https://til.andrew-quinn.me/posts/cross-platform-tuis-are-easier-than-cross-platform-guis/</link>
      <pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/cross-platform-tuis-are-easier-than-cross-platform-guis/</guid>
      <description>&lt;p&gt;Below is a GIF of
&lt;a href=&#34;https://github.com/hiAndrewQuinn/tsk&#34;&gt;&lt;code&gt;tsk&lt;/code&gt;, my pocket Finnish-to-English dictionary&lt;/a&gt;,
running in my terminal emulator of choice under Linux.
It&amp;rsquo;s what the kids call a
&lt;a href=&#34;https://github.com/rothgar/awesome-tuis&#34;&gt;TUI&lt;/a&gt;,
a graphical program that just happens to drive its graphics
using terminal graphics instead of graphics-graphics.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Insert GIF here.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You can probably tell that this program fits neatly into the
&lt;a href=&#34;https://bradfrost.com/blog/link/an-app-can-be-a-home-cooked-meal/&#34;&gt;&amp;ldquo;home-cooked meal&amp;rdquo;&lt;/a&gt;
clade of programs. There is a very straightforward problem I want solved -
fast, single-executable-portable dictionary lookup, with a few conveniences
for the busy language learner layered on top. I am quite happy with &lt;code&gt;tsk&lt;/code&gt; in
its current iteration and don&amp;rsquo;t plan to add much more to it anytime soon.
It would still save me a lot of time and hassle if I were the only person who
could use it.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Vibe coding and complementary goods</title>
      <link>https://til.andrew-quinn.me/posts/vibe-coding-and-complementary-goods/</link>
      <pubDate>Wed, 12 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/vibe-coding-and-complementary-goods/</guid>
      <description>&lt;p&gt;Peanut butter and jelly are
&lt;a href=&#34;https://en.wikipedia.org/wiki/Complementary_good&#34;&gt;complementary goods&lt;/a&gt;,
as are cars and gasoline,
newer cars and electricity,
electricity and basically everything else.&lt;/p&gt;
&lt;p&gt;We don&amp;rsquo;t normally think of, say,
Docker and Kubernetes as
complementary goods in software engineering,
because you can get both for the low price
of free. Or can you? You still have to
invest &lt;em&gt;time&lt;/em&gt; in learning both, and
as the famous saying goes&amp;hellip;&lt;/p&gt;
&lt;p&gt;Say it takes X hours to learn Docker
adequately. If Docker suddenly becomes
easier to learn, such that it now takes
only X / 2 hours, it&amp;rsquo;s reasonable to assume
Kubernetes will become more popular in tandem,
because one of its complements now costs
less and is hence supplied in greater
quantities anyway. You don&amp;rsquo;t
want a peanut butter only sandwich, do you?&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Things you should never do: Use Expect to autotype SSH passwords in scripts</title>
      <link>https://til.andrew-quinn.me/posts/things-you-should-never-do-use-tcl-expect-to-type-in-ssh-passwords/</link>
      <pubDate>Wed, 26 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/things-you-should-never-do-use-tcl-expect-to-type-in-ssh-passwords/</guid>
      <description>&lt;p&gt;Before I moved to Finland, I spent some time in the
Hobbesian war of all against all that is
&lt;a href=&#34;https://gutenberg.org/cache/epub/1156/pg1156-images.html#CHAPTER_I&#34;&gt;Wisconsin&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.
Men were &lt;em&gt;men&lt;/em&gt; back in that less civilized age,
and &amp;ldquo;cybersecurity&amp;rdquo; a ninny-word dreamt up by
social harmony types who honestly
thought they had anything worth stealing in their
servers. For those of us doing &lt;em&gt;real&lt;/em&gt; work, which
I must emphasize &lt;em&gt;you should never do&lt;/em&gt;,
we had
&lt;a href=&#34;https://core.tcl-lang.org/expect/index&#34;&gt;Expect&lt;/a&gt;.
And to SSH automatically into servers
where we didn&amp;rsquo;t have fancy accoutrements like
&amp;ldquo;keys&amp;rdquo; or &amp;ldquo;audit requirements&amp;rdquo;, we did stuff like&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>SQLite is learnable</title>
      <link>https://til.andrew-quinn.me/posts/the-learnability-of-sqlite/</link>
      <pubDate>Tue, 18 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/the-learnability-of-sqlite/</guid>
      <description>&lt;p&gt;This is a response to
&lt;a href=&#34;https://pid1.dev/posts/siren-call-of-sqlite-on-the-server/&#34;&gt;pid1.call&amp;rsquo;s &amp;ldquo;Siren Call of SQlite on the Server&amp;rdquo;&lt;/a&gt;,
which itself is a response to articles like
&lt;a href=&#34;https://blog.wesleyac.com/posts/consider-sqlite&#34;&gt;Wesley Aptekar-Cassels&amp;rsquo;s &amp;ldquo;Consider SQLite&amp;rdquo;&lt;/a&gt;
espousing SQLite as a server-side technology.
Cards on the table, I both love SQLite &lt;em&gt;and&lt;/em&gt;
think pid1 has the more correct take here.&lt;/p&gt;
&lt;p&gt;When I decided on a dime after college to move countries
and be with my wife, part of the package deal was that
I had to throw away my dreams of easing into the software
industry by resting on the laurels of my
&lt;a href=&#34;https://www.northwestern.edu/&#34;&gt;strong, but not MIT-level-known-worldwide-strong, alma mater&lt;/a&gt;
(sorry Wildcats).
Electrical engineering was just not going to be
feasible for a then-monolingual
English speaker in Finland, and besides,
I majored in it 90% out of curiosity anyway. I always intended
to return to my once and future home, the shell, after my
&lt;a href=&#34;https://en.wikipedia.org/wiki/Rumspringa&#34;&gt;Rumspringa with electrons&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Common-sense security for SSH on a new Debian server</title>
      <link>https://til.andrew-quinn.me/posts/common-sense-security-for-ssh-on-a-new-debian-server/</link>
      <pubDate>Tue, 24 Sep 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/common-sense-security-for-ssh-on-a-new-debian-server/</guid>
      <description>&lt;p&gt;Last night I went to DigitalOcean and spun up a tiny new, $4/month droplet &amp;ndash;
on my own dime! It sounds crazy, but I&amp;rsquo;ve never actually wanted to pay for
hosting myself before. But I have a fun little web app cooking up, one that
might eventually pay that $4/month back with interests, and I decided, why not,
it&amp;rsquo;s time to finally put some of my &lt;em&gt;own&lt;/em&gt; skin in the game with this whole
sysadmin thing.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>PHP, Go, and Braindead Deployment</title>
      <link>https://til.andrew-quinn.me/posts/php-go-and-braindead-deployment/</link>
      <pubDate>Mon, 16 Sep 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/php-go-and-braindead-deployment/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve been
&lt;a href=&#34;,./php-is-web-shell/&#34;&gt;following my posts&lt;/a&gt;
recently, you might have noticed that I&amp;rsquo;ve been working more and more with PHP
lately. As someone who was curiously allergic to
web dev as a teenager, it has been
&lt;a href=&#34;../php-and-web-dev-phobia/&#34;&gt;a strangely healing experience&lt;/a&gt;
for me.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d like to say it&amp;rsquo;s because my experiments with
&lt;a href=&#34;https://laravel.com/&#34;&gt;Laravel&lt;/a&gt;,
the only OSS work of which I can point to is testing
&lt;a href=&#34;https://github.com/hiAndrewQuinn/shell-bling-ubuntu?tab=readme-ov-file#where-else-does-this-work&#34;&gt;the Homestead VM&amp;rsquo;s compatibility for Shell Bling Ubuntu&lt;/a&gt;,
convinced me. But no &amp;ndash; Laravel is &lt;em&gt;pretty sweet&lt;/em&gt;, but so is
&lt;a href=&#34;https://www.djangoproject.com/&#34;&gt;Django&lt;/a&gt;, but Django
has the advantage of using an underlying language that&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>How I ask GPT-4 to make tiny Python scripts in practice</title>
      <link>https://til.andrew-quinn.me/posts/how-i-ask-gpt-4-to-make-tiny-python-scripts-in-practice/</link>
      <pubDate>Thu, 22 Aug 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/how-i-ask-gpt-4-to-make-tiny-python-scripts-in-practice/</guid>
      <description>&lt;ol&gt;
&lt;li&gt;First get a working script. &amp;ldquo;Hey GPT-4, write me a ChatGPT script that does &lt;X&gt;.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Manually check over the script and iterate until it&amp;rsquo;s giving me what I want.&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Now wrap the script into a &lt;a href=&#34;https://click.palletsprojects.com/en/8.1.x/&#34;&gt;&lt;code&gt;click&lt;/code&gt;&lt;/a&gt; command-line interface.&amp;rdquo; I almost always specify to use an &lt;code&gt;--input&lt;/code&gt; flag and an &lt;code&gt;--output&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;If the data it&amp;rsquo;s working with is human-readable, &amp;ldquo;Make it so that if &lt;code&gt;--input&lt;/code&gt; is not specified, it reads data from stdin.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;If the data it&amp;rsquo;s writing is human-readable, &amp;ldquo;Make it so that if &lt;code&gt;--output&lt;/code&gt; is not specified, it emits data to stdout.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;If the script is complicated enough that error logging is warranted: &amp;ldquo;Add logging and &lt;a href=&#34;https://pypi.org/project/colorlog/&#34;&gt;&lt;code&gt;colorlog&lt;/code&gt;&lt;/a&gt;. Ensure all error messages are written to &lt;code&gt;stderr&lt;/code&gt; so that it does not clash with output.&amp;rdquo;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This advice is optimized for &lt;strong&gt;small&lt;/strong&gt; Python scripts, usually under 200 lines in total,
for automating semi-mundane tasks like&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Valuable software is about letting people do new things</title>
      <link>https://til.andrew-quinn.me/posts/valuable-software-is-about-doing-new-things/</link>
      <pubDate>Fri, 21 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/valuable-software-is-about-doing-new-things/</guid>
      <description>&lt;p&gt;Today I released a dump of
&lt;a href=&#34;https://github.com/Selkouutiset-Archive/selkokortti/releases/tag/summer-2024&#34;&gt;six months of flashcards&lt;/a&gt;
I autogenerated from
&lt;a href=&#34;../lessons-learned-from-6-months-of-operating-a-teensy-tiny-news-archive/&#34;&gt;my tiny Finnish news archive&lt;/a&gt;
to make the lives of my fellow language learners easier.
The actual code which generates this archive is
&lt;a href=&#34;https://github.com/Selkouutiset-Archive/selkokortti/blob/main/main.py&#34;&gt;about 300 lines of Python&lt;/a&gt;
.
The basic value add for the user:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;What you want&lt;/strong&gt;: Better fluency in Finnish.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What you need&lt;/strong&gt;: Practice. Lots of it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What this gives you&lt;/strong&gt;: GOTO 2.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is emphatically &lt;em&gt;not&lt;/em&gt; the kind of product, or use case,
I would stumble upon as a brain-in-the-vat developer. It is
a niche offering, one I only found because I actually
got out into the world and tried to &lt;em&gt;do something hard&lt;/em&gt;.
In so doing, I recognized the possibility of building a tool
that could help me in this &lt;em&gt;non-programming&lt;/em&gt; endeavour.
So I built it. And I&amp;rsquo;m proud of it.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Layers of abstraction for me, not for thee</title>
      <link>https://til.andrew-quinn.me/posts/layers-of-abstraction-for-me-not-for-thee/</link>
      <pubDate>Tue, 18 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/layers-of-abstraction-for-me-not-for-thee/</guid>
      <description>&lt;p&gt;Consider the problem of &amp;ldquo;how do I run more than 1 terminal at a time&amp;rdquo;.
At this moment, I have at least 5 different ways I can effectively
solve this issue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I can, from a different physical computer, SSH in to a new session.&lt;/li&gt;
&lt;li&gt;I can, from the same physical computer, switch to a different &lt;code&gt;tty&lt;/code&gt;
session with &amp;hellip; &lt;code&gt;C-S-F2&lt;/code&gt; through &lt;code&gt;6&lt;/code&gt; or something. (Rare, but
sometimes it comes in really handy.)&lt;/li&gt;
&lt;li&gt;I can, in the same user session, open 2 separate windows of a terminal
emulator.&lt;/li&gt;
&lt;li&gt;I can, in the same terminal emulator, open a new tab.&lt;/li&gt;
&lt;li&gt;I can, in the same emulated terminal, run &lt;code&gt;tmux&lt;/code&gt; and open a new
pane.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are yet more exotic options like
&lt;a href=&#34;https://en.wikipedia.org/wiki/Serial_over_LAN&#34;&gt;Serial over LAN&lt;/a&gt;
that I&amp;rsquo;m only theoretically aware of.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>OpenBSD, the computer appliance maker&#39;s secret weapon</title>
      <link>https://til.andrew-quinn.me/posts/openbsd-the-computer-appliance-maker-s-secret-weapon/</link>
      <pubDate>Wed, 05 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/openbsd-the-computer-appliance-maker-s-secret-weapon/</guid>
      <description>&lt;p&gt;Between our ESP32 prokaryotic organisms and our 24/7 Internet-enabled
megafauna servers, there exists a vast and loosely-defined ecosystem of things
the
B2B world likes to call &lt;strong&gt;computer appliances&lt;/strong&gt;. Picture a bespoke Pi 4 packaged
up neatly with some Python scripts, a little fancy plastic embossing, and maybe
a well-guarded &lt;code&gt;id_ed25519.pub&lt;/code&gt; in case you end up in hot water during the
(long - very long, stable cash flow for generations long) maintenance contract,
and you&amp;rsquo;re in the ballpark.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Quickstarts and Slowstarts</title>
      <link>https://til.andrew-quinn.me/posts/quickstarts-and-slowstarts/</link>
      <pubDate>Tue, 04 Jun 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/quickstarts-and-slowstarts/</guid>
      <description>&lt;p&gt;A while back I stirred up some controversy on Hacker News
by talking about why I liked it when
&lt;a href=&#34;https://news.ycombinator.com/item?id=39882810&#34;&gt;tutorials take you from clean VM to working, installed software&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve since taken to calling this the &amp;ldquo;tutorial-in-a-box&amp;rdquo; method.
When I write them myself, I usually put them under the
header &lt;strong&gt;Slowstart&lt;/strong&gt;, a riff on the proverbial Quickstart.
Two examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://andrew-quinn.me/reposurgeon&#34;&gt;A gentle introduction to &lt;code&gt;reposurgeon&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&#34;https://github.com/Selkouutiset-Archive/selkokortti?tab=readme-ov-file#slowstart&#34;&gt;Slowstart&lt;/a&gt; for &lt;code&gt;selkokortti&lt;/code&gt;, some flashcard generating software based around &lt;a href=&#34;https://hiandrewquinn.github.io/selkouutiset-archive/&#34;&gt;my Finnish language news archive&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The point of a Slowstart is to make it so that &lt;em&gt;even absolute beginners&lt;/em&gt;
can start to pick up some pointers about how people &amp;ldquo;in the know&amp;rdquo; of
your chosen software ecosystem actually get things done. Instead of a
Dockerfile or a shell script, you take them by the hand, spin up a
&lt;em&gt;totally fresh&lt;/em&gt; virtual machine from the ground up using something like
&lt;a href=&#34;https://www.vagrantup.com/&#34;&gt;Vagrant&lt;/a&gt;
or
&lt;a href=&#34;https://developer.fedoraproject.org/tools/virt-builder/about.html&#34;&gt;virt-builder&lt;/a&gt;,
and walk them through &lt;strong&gt;each and every command&lt;/strong&gt; they need to execute
in order to get to a working install.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>I&#39;m turning 30 so naturally I&#39;m switching to OpenBSD</title>
      <link>https://til.andrew-quinn.me/posts/i-m-turning-30-so-i-m-switching-to-openbsd/</link>
      <pubDate>Sat, 04 May 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/i-m-turning-30-so-i-m-switching-to-openbsd/</guid>
      <description>&lt;p&gt;&lt;em&gt;I&amp;rsquo;m kidding&lt;/em&gt;, I&amp;rsquo;m switching to OpenBSD because I like security or code
quality or something.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s totally not because the inexorable march of aging is starting to show its
effects on my ability to down necessary-evil trivia like me and my friends
used to down forties in &lt;a href=&#34;https://arboretum.harvard.edu/&#34;&gt;the Ahhhnald&lt;/a&gt; after dark,
and so I&amp;rsquo;d like to settle down with a software ecosystem I can study in real
depth &lt;em&gt;once&lt;/em&gt; without feeling like 20% of what I absorb in year X will be
deprecated by year X+10.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Language learning treated as breadth-first search</title>
      <link>https://til.andrew-quinn.me/posts/language-learning-treated-as-breadth-first-search/</link>
      <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
      
      <guid>https://til.andrew-quinn.me/posts/language-learning-treated-as-breadth-first-search/</guid>
      <description>&lt;p&gt;I am, emphatically, &lt;em&gt;not&lt;/em&gt; the language learning type. I&amp;rsquo;ve done enough of it over my life to know this. It&amp;rsquo;s certainly one of the better hobbies out there: You can do it for free (in principle), you can sink as many hours as you care to into it, and if you get good enough at it you get to reap some unique cultural and economic&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; benefits. But there&amp;rsquo;s a reason I picked up Python when 14 year old me decided he wanted to get ahead in life instead of (say) German.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
