<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Technology on not quite an expert</title><link>/tags/technology/</link><description>Recent content in Technology on not quite an expert</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 17 May 2026 01:55:00 -0400</lastBuildDate><atom:link href="/tags/technology/index.xml" rel="self" type="application/rss+xml"/><item><title>The Art of Doing Science and Engineering: Luck Favors the Lucky</title><link>/posts/art_doing_science_and_engineering_luck_favors_lucky/</link><pubDate>Sat, 16 May 2026 00:00:00 +0000</pubDate><guid>/posts/art_doing_science_and_engineering_luck_favors_lucky/</guid><description>&lt;p>In &lt;a href="https://www.amazon.com/dp/1732265178">&lt;em>The Art of Doing Science and Engineering&lt;/em>&lt;/a>, &lt;a href="https://en.wikipedia.org/wiki/Richard_Hamming">Richard Hamming&lt;/a> repeats &lt;a href="https://en.wikipedia.org/wiki/Louis_Pasteur">Louis Pasteur&lt;/a>&amp;rsquo;s remark: &lt;a href="https://www.pasteurbrewing.com/louis-pasteur-chance-favors-the-prepared-mind">&amp;ldquo;Luck favors the prepared mind&amp;rdquo;&lt;/a>, emphasizing personal responsibility in success. However, if we examine it through the book, the prepared mind itself depends on luck.&lt;/p>
&lt;p>Hamming&amp;rsquo;s prepared mind can think and understand fundamental concepts like &lt;em>n&lt;/em>-dimensional spaces. By his observation, few minds can do so. By my observation, &lt;em>lucky&lt;/em> minds can do so.&lt;/p>
&lt;p>Hamming also describes through various anecdotes the problems and resources he had access to at Bell Labs. Throughout the stories, the rise of digital computers which few predicted frames many of Hamming&amp;rsquo;s successes. These too resemble luck.&lt;/p></description></item><item><title>The Art of Doing Science and Engineering: Eat Sh*t and Die</title><link>/posts/art_doing_science_and_engineering_eat_sh_t_and_die/</link><pubDate>Sat, 09 May 2026 00:00:00 +0000</pubDate><guid>/posts/art_doing_science_and_engineering_eat_sh_t_and_die/</guid><description>&lt;p>I originally started reading &lt;a href="https://www.amazon.com/dp/1732265178">&lt;em>The Art of Doing Science and Engineering&lt;/em>&lt;/a> by &lt;a href="https://en.wikipedia.org/wiki/Richard_Hamming">Richard Hamming&lt;/a> a few years ago. Though I got distracted by more easily digestible books, so I dropped it a few chapters in. Now &lt;a href="/posts/untethered_again/">untethered&lt;/a>, I finally finished the book. If you think you&amp;rsquo;re getting a proper summary, you&amp;rsquo;ve got another think coming: I&amp;rsquo;m here to blather on about a tangentially related topic!&lt;/p>
&lt;p>In his chapters about artificial intelligence (AI), Hamming asks: to what extent can machines think? Before that, to what extent can people think?&lt;/p></description></item><item><title>Ramping down III: what is happening now?</title><link>/posts/ramping_down_iii/</link><pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate><guid>/posts/ramping_down_iii/</guid><description>&lt;p>We covered &lt;a href="/posts/ramping_down_ii/">what happened (with me)&lt;/a>, now let&amp;rsquo;s cover what is happening (with me) now.&lt;/p>
&lt;hr>
&lt;p>It happened so suddenly my friends worried how I was doing. I&amp;rsquo;m doing good. I put my WHOLE ASS (both cheeks! I did not half ass it!) into turning the situation around, and I have the post-midnight (&lt;em>la madrugada&lt;/em>) Loom demo threads and the sleep diary to prove it. Even some extra shit - I called the managers from my previous team, and they couldn&amp;rsquo;t bail me out. I traded whatever embarrassment to have minimal regret.&lt;/p></description></item><item><title>Ramping down II: what happened?</title><link>/posts/ramping_down_ii/</link><pubDate>Sat, 21 Feb 2026 00:00:00 +0000</pubDate><guid>/posts/ramping_down_ii/</guid><description>&lt;p>We covered &lt;a href="/posts/ramping_down_i/">what was happening (with the company)&lt;/a>, now let&amp;rsquo;s cover what happened (with me).&lt;/p>
&lt;hr>
&lt;p>One of my favorite professors said &amp;ldquo;people join good companies, and leave bad managers&amp;rdquo;.&lt;/p>
&lt;p>I joined my new team under a director whom my coworker friend (and ex-roommate) vouched for. That director soon left the company, citing toxic leadership. I can&amp;rsquo;t say I disagree.&lt;/p>
&lt;p>So I got a new manager and skip manager (manager&amp;rsquo;s manager) whom I mixed poorly with. My manager and I mixed poorly on scope - a first-time manager, they optimistically accepted scope, while I tried to push back on scope. I couldn&amp;rsquo;t effectively negotiate scope without their support, so I laid out multiple times that I considered pushing back on scope a key part of my role. However, we never had a full discussion about our differences handling scope, and the issue festered. My skip manager clearly prioritized optics,&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> while &lt;a href="/posts/hwyl_optics/">I find myself mildly allergic to optics&lt;/a>.&lt;/p></description></item><item><title>Ramping down I: what was happening?</title><link>/posts/ramping_down_i/</link><pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate><guid>/posts/ramping_down_i/</guid><description>&lt;p>Upon leaving my company, I want to answer 3 questions:&lt;/p>
&lt;ol>
&lt;li>What was happening (with the company)?&lt;/li>
&lt;li>What happened (with me)?&lt;/li>
&lt;li>What is happening (with me) now?
This post covers the first question.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;p>As a company grows, people have less visibility into each other&amp;rsquo;s work, so &lt;em>optics&lt;/em> becomes more and more important. &lt;a href="/posts/hwyl_optics/">Previously I&amp;rsquo;ve defined optics in contrast to substance.&lt;/a> While some optics can create value for the group, e.g. providing public project updates can keep the group on track, I find optics generally creates value for the individual over the group, e.g.&lt;/p></description></item><item><title>Wright iterations</title><link>/posts/wright_iterations/</link><pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate><guid>/posts/wright_iterations/</guid><description>&lt;p>The Smithsonian National Air and Space Museum has an exhibit about the Wright brothers investigating how they, with relatively little formal training, became the first to achieve controlled, sustained, and powered flight.&lt;/p>
&lt;p>The exhibit explains how the Wright brothers, starting from existing research, built multiple iterations of flying machines for realistic testing in Kitty Hawk, North Carolina.&lt;/p>
&lt;p>However, in addition to those big iterations, the Wright brothers also conducted many more small iterations, using a wind tunnel to test hundreds of wing designs to optimize the forces operating on the wings.&lt;/p></description></item><item><title>Getting steamed</title><link>/posts/getting_steamed/</link><pubDate>Sat, 27 Sep 2025 00:00:00 +0000</pubDate><guid>/posts/getting_steamed/</guid><description>&lt;p>I got excited about buying my first good belt,&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> so I bought some nice button-down and button-up shirts. They came out of the dryer &lt;em>embarrassingly&lt;/em> wrinkled. Like I tried playing it cool wearing one the next day, and a coworker &lt;em>explicitly&lt;/em> noted how wrinkled my shirt looked!&lt;/p>
&lt;p>To avoid owning too much stuff, like an iron, an ironing board, and all that, I researched a steamer to remove the wrinkles. Fortunately, I found the right model &lt;a href="/posts/used_on_ebay/">like new on eBay&lt;/a>, so I ordered it, excited to steam away my problems.&lt;/p></description></item><item><title>Staying off social media</title><link>/posts/staying_off_social_media/</link><pubDate>Sat, 16 Aug 2025 00:00:00 +0000</pubDate><guid>/posts/staying_off_social_media/</guid><description>&lt;p>Though I&amp;rsquo;ve only seen light evidence that it undermines &lt;a href="https://asteriskmag.com/issues/11/scapegoating-the-algorithm">epistemics&lt;/a> and &lt;a href="https://podcasts.apple.com/us/podcast/the-anxious-generation/id1651876897?i=1000664706439">mental health&lt;/a>, I think social media moves faster than research and policy. I deliberately stay off social media: I don&amp;rsquo;t have an X (previously Twitter), Instagram, or TikTok account, and I don&amp;rsquo;t have the YouTube app on my phone.&lt;/p>
&lt;p>I don&amp;rsquo;t see myself as a better person than other people because of this (as my friend accused). However, I do see myself as better than the counterfactual version of myself on social media. I remember my time on Facebook (before I deleted that account) as mostly rotting, similar to &lt;a href="https://helenaaeberli.substack.com/p/phone-noise">this description&lt;/a>, and I can&amp;rsquo;t really point to anything meaningful I got out of it.&lt;/p></description></item><item><title>Markdown everywhere</title><link>/posts/markdown_everywhere/</link><pubDate>Sat, 09 Aug 2025 00:00:00 +0000</pubDate><guid>/posts/markdown_everywhere/</guid><description>&lt;p>I&amp;rsquo;ve been using &lt;a href="https://www.markdownguide.org/basic-syntax">Markdown&lt;/a> more and more, not just for writing posts here, also for writing messages in Slack and writing documents in Notion.&lt;/p>
&lt;p>As detailed in &lt;a href="https://ia.net/topics/markdown-and-the-slow-fade-of-the-formatting-fetish">this article&lt;/a>, Markdown emphasizes structure over presentation, which works well for my job in which I prioritize &lt;a href="/posts/hwyl_optics/">substance over optics&lt;/a>. I consider the simple structure of Markdown a feature rather than a bug, since it takes effort to extract the substance and express something simply.&lt;/p></description></item><item><title>3 points about copying keys</title><link>/posts/copy_keys_points/</link><pubDate>Sat, 02 Aug 2025 00:00:00 +0000</pubDate><guid>/posts/copy_keys_points/</guid><description>&lt;p>I got a surprising amount out of copying my friend&amp;rsquo;s keys while staying at their apartment. My friend has pointed out how I often structure my thoughts into 3 points:&lt;/p>
&lt;h1 id="1-ease">1. ease&lt;/h1>
&lt;p>I didn&amp;rsquo;t even need to talk to someone to copy the keys. I just scanned the keys at a machine and that machine cut the key copies within minutes. As noted in &lt;a href="https://www.youtube.com/watch?v=VPBH1eW28mo">this video&lt;/a>, you can more easily &amp;ldquo;break&amp;rdquo; a physical key than a digital key, though you can less easily use a broken physical key than a broken digital key. However, &lt;a href="https://xkcd.com/538">you can get around digital keys in other ways&lt;/a>.&lt;/p></description></item><item><title>Monaspace</title><link>/posts/monaspace/</link><pubDate>Sat, 12 Jul 2025 00:00:00 +0000</pubDate><guid>/posts/monaspace/</guid><description>&lt;p>From &lt;a href="https://robhorning.substack.com/p/font-activations">&amp;ldquo;Font activations&amp;rdquo;&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>[N]ow words are everywhere treated as data, as numbers, and they are rarely printed at all. &amp;hellip; Fonts perhaps become more salient as they become the only thing that people are expected to play with when it comes to words, once it is drilled into everyone that it is required for efficiency and political conformity to let machines do all the writing and the editing and the &amp;ldquo;thinking.&amp;rdquo;&lt;/p></description></item><item><title>My keyboard stand (2025)</title><link>/posts/keyboard_stand_2025/</link><pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate><guid>/posts/keyboard_stand_2025/</guid><description>&lt;p>Sure, &lt;a href="/posts/ergo_keyboards/">a sit-stand desk serves as the best &amp;ldquo;ergonomic keyboard&amp;rdquo;&lt;/a>. Though what if I want to sport ergonomically limp wrists at my sit-stand desk?&lt;/p>
&lt;p>Exploring the wider possibilities of keyboard stands, I found inspiration leveraging other existing systems for electronics, with &lt;a href="https://www.youtube.com/watch?v=jyqRtHL9M7Y">tripod clamps&lt;/a> and &lt;a href="https://evantravers.com/articles/2023/04/06/magsafe-tenting-and-wearable-keyboards">MagSafe connections&lt;/a>.&lt;/p>
&lt;p>Sure, clamping my split keyboard to my desk makes me look a lil crazy, like either a 0.5x or a 2x engineer. However, based on my calculations (0.5 * 0.5 + 0.5 * 2.0 = 1.25), I&amp;rsquo;ve become a 1.25x engineer in expectation.&lt;/p></description></item><item><title>Please just remove the feature flag</title><link>/posts/remove_feature_flag/</link><pubDate>Sat, 22 Mar 2025 00:00:00 +0000</pubDate><guid>/posts/remove_feature_flag/</guid><description>&lt;p>Artificial intelligence (✨AI✨) philosophers think about artificial general intelligence (✨AGI✨), when ✨AI✨ becomes ✨super duper✨ capable, and ✨super duper✨ wild changes occur in society. Some credible philosophers think ✨AGI✨ will come in a few short years.&lt;/p>
&lt;p>The last time I used ✨AI✨ to remove a fully enabled feature flag, it made 3 attempts:&lt;/p>
&lt;ol>
&lt;li>In the first attempt, it replaced the feature flag enumeration value with a bunch of comment delimiters - I&amp;rsquo;d rather it delete the value, though fine - &amp;ldquo;oops, let me try again&amp;rdquo;&lt;/li>
&lt;li>In the second attempt, it replaced the bunch of comment delimiters with a single comment delimiter - again I&amp;rsquo;d rather it delete the value, though fine - &amp;ldquo;oops, let me try again&amp;rdquo;&lt;/li>
&lt;li>In the third attempt, it didn&amp;rsquo;t even show me what it did, it just gave up - &amp;ldquo;you&amp;rsquo;ll just have to do it yourself&amp;rdquo;&lt;/li>
&lt;/ol>
&lt;p>So I guess I&amp;rsquo;m still waiting for ✨AGI✨. Maybe it&amp;rsquo;ll come after mass self-driving cars.&lt;/p></description></item><item><title>Surprise Cybertruck</title><link>/posts/surprise_cybertruck/</link><pubDate>Sat, 28 Dec 2024 00:00:00 +0000</pubDate><guid>/posts/surprise_cybertruck/</guid><description>&lt;p>While on vacation, our family got a rideshare in a surprise Cybertruck!&lt;/p>
&lt;p>My mom speculated &amp;ldquo;must be expensive&amp;rdquo;, to which to driver replied &amp;ldquo;yeah, a little expensive&amp;rdquo;. Then with some real big mom energy, my mom hit him with &amp;ldquo;well, maybe just a little expensive for you&amp;rdquo;! The driver tried to recover by spouting some financial justifications, though by then I had already relayed the conversation to my friends.&lt;/p>
&lt;p>My mom commented on the driver&amp;rsquo;s shyness afterward. Based on this anecdotal evidence, I&amp;rsquo;d read the buyer of a Cybertruck as trying to become less self-conscious;&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> &lt;a href="https://youtu.be/_S7GU9lDpq8?t=1181">the truck itself seems to perform worse than other trucks.&lt;/a> So getting read as a passenger as trying to become less self-conscious made me very self-conscious. I spent the ride trying to focus inward rather than outward.&lt;/p></description></item><item><title>Inappropriate linorobot</title><link>/posts/inappropriate_linorobot/</link><pubDate>Sat, 07 Dec 2024 00:00:00 +0000</pubDate><guid>/posts/inappropriate_linorobot/</guid><description>&lt;p>To end 2021, my friend U wanted us to build an easy, simple self-driving vehicle. After settling on the &lt;a href="https://github.com/linorobot/linorobot">linorobot&lt;/a>, we just needed to procure parts:&lt;/p>
&lt;ol>
&lt;li>Raspberry Pi&lt;/li>
&lt;li>(Xbox) Kinect sensor&lt;/li>
&lt;li>Some sort of chassis&lt;/li>
&lt;li>Other parts&lt;/li>
&lt;/ol>
&lt;p>After days of planning and execution, we ended up with:
&lt;img src="/inappropriate-linorobot.jpg" alt="An inappropriate linorobot">&lt;/p>
&lt;p>Look at it! Obscene!! It looks like a dildo!!!&lt;/p>
&lt;p>U called it &amp;ldquo;scuffed&amp;rdquo;. However, I call it &amp;ldquo;fuck-ass&amp;rdquo;,&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> as in &amp;ldquo;WHY DID WE MAKE THIS FUCK-ASS DILDO BOT??!!&amp;rdquo;&lt;/p></description></item><item><title>Journey of the airplane magazine</title><link>/posts/journey_airplane_magazine/</link><pubDate>Sat, 26 Oct 2024 00:00:00 +0000</pubDate><guid>/posts/journey_airplane_magazine/</guid><description>&lt;p>I have fond memories of the airplane magazine. In my most distinct memory of it, my sister and I actually brought a copy off of the plane, to browse in bed. Blowing past the articles, we admired and gawked at the fancy and quirky merchandise advertised inside. To us, those advertisements served as low fantasy, a conduit to imagine a lifestyle where not only did we &lt;em>need&lt;/em> a multi-color pool light with different modes, we bought one &lt;em>on a plane&lt;/em>!&lt;/p></description></item><item><title>Your code editor doesn't need notifications</title><link>/posts/editor_notifications/</link><pubDate>Sat, 07 Sep 2024 00:00:00 +0000</pubDate><guid>/posts/editor_notifications/</guid><description>&lt;p>As a full-stack programmer, I&amp;rsquo;d like to use VS Code for my backend (Python) and frontend (TypeScript React).&lt;/p>
&lt;p>I&amp;rsquo;d like to, if VS Code didn&amp;rsquo;t take &lt;em>seconds&lt;/em> and a &lt;em>loading bar&lt;/em> to follow code definitions in Python. My desire to depend on fewer tools takes a back seat to my desire to get the job done efficiently, &lt;a href="/posts/vs_code/">hence why I moved from Spacemacs (Emacs) to VSpaceCode (VS Code) in the first place&lt;/a>.&lt;/p></description></item><item><title>Set up wall shelf, set up ssh</title><link>/posts/set_up_wall_shelf_ssh/</link><pubDate>Sat, 10 Aug 2024 00:00:00 +0000</pubDate><guid>/posts/set_up_wall_shelf_ssh/</guid><description>&lt;p>I run a music server on my spare &lt;a href="https://en.wikipedia.org/wiki/Next_Unit_of_Computing">headless computer&lt;/a>. However, after running for a few hours, especially after I &lt;a href="https://wiki.archlinux.org/title/Power_management/Suspend_and_hibernate">suspend to disk&lt;/a>, the music server needs to restart.&lt;/p>
&lt;p>Previously, I would connect my headless computer to my projector and keyboard to run some commands. However, with my wall shelf up, and my projector up on it, that takes too much effort now.&lt;/p>
&lt;p>So I set up &lt;a href="https://wiki.archlinux.org/title/OpenSSH">ssh&lt;/a> into my headless computer to run those same commands. Even seemingly unrelated projects influence each other in a shared space.&lt;/p></description></item><item><title>Third person singular simple present</title><link>/posts/tpssp/</link><pubDate>Sat, 30 Dec 2023 00:00:00 +0000</pubDate><guid>/posts/tpssp/</guid><description>&lt;p>The product summary for my new electric shaver stand declares:&lt;/p>
&lt;blockquote>
&lt;p>Select cleaning intensity to keep for optimal performance every day.&lt;/p>
&lt;/blockquote>
&lt;p>Ok, so do I have to select the cleaning intensity? Or does the stand select the cleaning intensity?&lt;/p>
&lt;p>I thought I did, so I spent a while searching how I should select the cleaning intensity. Upon reading multiple product manuals, it turns out the stand does.&lt;/p>
&lt;p>To clarify subject-less descriptions, you should use third person singular simple present:&lt;/p></description></item><item><title>$0.10 Fix Vs. $300 Fix</title><link>/posts/ten_cent_fix/</link><pubDate>Sat, 09 Dec 2023 00:00:00 +0000</pubDate><guid>/posts/ten_cent_fix/</guid><description>&lt;p>(titled like a BuzzFeed video)&lt;/p>
&lt;p>&lt;em>Just ask the basic questions, and act on the basic answers, and you&amp;rsquo;ll get surprisingly good results.&lt;/em>&lt;/p>
&lt;p>My AirPods Max were suffering terrible connectivity. Half of the time, when you put them on, they wouldn&amp;rsquo;t connect; and when you took them off, they wouldn&amp;rsquo;t re-connect. I had to keep resetting them.&lt;/p>
&lt;p>When I took them to the Apple Store, the Genius told me it would cost $300 to repair them, with no warranty afterward. She straight up suggested to instead buy another one.&lt;/p></description></item><item><title>Smart plug hammer</title><link>/posts/smart_plug_hammer/</link><pubDate>Sat, 06 May 2023 00:00:00 +0000</pubDate><guid>/posts/smart_plug_hammer/</guid><description>&lt;p>You can turn any &amp;ldquo;dumb&amp;rdquo; electrical device into a &amp;ldquo;smart&amp;rdquo; one by plugging it into a smart plug. Then you can automatically schedule turning it on and off.&lt;/p>
&lt;p>However, to a person with a hammer, everything starts to look like a nail. Instead of solving the problem with my noisy refrigerator, I just set the refrigerator to turn off around when I expect to sleep and wake up. And now, stuck with a &amp;ldquo;smart&amp;rdquo; half-solution, I end up trying to ignore the noisy refrigerator during the day.&lt;/p></description></item><item><title>Indignant biking</title><link>/posts/indignant_biking/</link><pubDate>Sat, 11 Feb 2023 00:00:00 +0000</pubDate><guid>/posts/indignant_biking/</guid><description>&lt;p>To bike regularly in San Francisco, you must glance at death.&lt;/p>
&lt;p>Last weekend, I learned that &lt;a href="https://slate.com/technology/2023/01/bike-helmets-cyclist-deaths-do-you-need-to-wear.html">helmets don&amp;rsquo;t really help bikers if they seriously crash with a car&lt;/a>. I also almost crashed twice, while in the bike lane.&lt;/p>
&lt;p>The first time, a car swung open its door into my bike lane. I braked quickly enough to avoid a serious collision. Yet I still bumped my hand against the door. The driver and I checked with each other, found nothing concerning, and both brushed it off.&lt;/p></description></item><item><title>How to read today</title><link>/posts/how_to_read/</link><pubDate>Sat, 24 Dec 2022 00:00:00 +0000</pubDate><guid>/posts/how_to_read/</guid><description>&lt;p>I just finished reading &lt;em>How to Read a Book&lt;/em> by Mortimer J. Adler and Charles Van Doren. Originally published in 1940, the book has aged surprisingly well, save for a few antiquated passages.&lt;/p>
&lt;p>Since 1940, the Internet has radically changed how we read. Websites and search engines have largely replaced physical media. And against this unprecedentedly large collection of digital media, their advice, that different pieces deserve different amounts/levels of your time and effort, rings even more true.&lt;/p></description></item><item><title>Sidegrading your audio</title><link>/posts/record_player/</link><pubDate>Sat, 03 Dec 2022 00:00:00 +0000</pubDate><guid>/posts/record_player/</guid><description>&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/e-EKLbcNM1I?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video">&lt;/iframe>
 &lt;/div>

&lt;p>I watch Steve Guttenberg for the crustiness. The lack of polish suggests an authenticity, an honesty. If audio equipment ever did have a past golden age, Steve embodies it.&lt;/p>
&lt;p>As with every Black Friday, I considered buying new audio equipment. In the video above, Steve recommends getting something drastically different. Rather than spending progressively more upgrading the same type of setup, try a different setup. In my case, instead of upgrading my bookshelf speakers, I got an entry-level record player.&lt;/p></description></item><item><title>From Emacs to VS Code</title><link>/posts/vs_code/</link><pubDate>Sat, 05 Nov 2022 00:00:00 +0000</pubDate><guid>/posts/vs_code/</guid><description>&lt;p>Recently, I switched from Emacs to VS Code as my primary text editor. For those who knew me well, this represents a significant change.&lt;/p>
&lt;h1 id="i-eclipse-eclipsed">I: Eclipse eclipsed&lt;/h1>
&lt;p>For my first in-person&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> programming course, I used Eclipse. Slow and mangled by a maze of menus, Eclipse made my laptop scream and boil. I asked &lt;a href="/posts/taquito/">my friend U&lt;/a> for another editor to use.&lt;/p>
&lt;h1 id="ii-vim-then-emacs-then-emacs-vim">II: Vim, then Emacs, then Emacs-Vim&lt;/h1>
&lt;p>U suggested I use Vim. To make sure I &lt;em>properly&lt;/em> used Vim, U disabled the arrow keys in favor or hjkl, the Vim convention for moving around. Instead of learning to use hjkl, I learned to dislike Vim, and asked U for yet another option.&lt;/p></description></item><item><title>Yoga at 1.1x speed</title><link>/posts/yoga_1.1/</link><pubDate>Sat, 24 Sep 2022 00:00:00 +0000</pubDate><guid>/posts/yoga_1.1/</guid><description>&lt;p>Recently, as a &lt;a href="/posts/mindful_mommy/">mindful mommy&lt;/a>, I&amp;rsquo;ve been going on my 30-day Yoga Journey, a free yoga video series on YouTube. Those who remember I used to listen to music &lt;a href="/posts/music_speed/">at 1.4x speed&lt;/a> will suspect I don&amp;rsquo;t follow along at regular speed. Indeed, I&amp;rsquo;m sprinting along the path of my journey at 1.1x speed.&lt;/p>
&lt;p>Yes, at first it felt almost sacrilegious to me too. I want you to cast aside your initial judgement, though, and re-consider the arguments I presented in &lt;a href="/posts/music_speed/">my post about music at 1.4x speed&lt;/a>. As consumers of media, we have the power of interpretation - to reproduce the media in our own way. That includes on a TV or on a phone, in a quiet apartment or in a noisy bar, and yes, at a slower or at a faster speed than 1.0x.&lt;/p></description></item><item><title>Computing sequential games: solution</title><link>/posts/game_solution/</link><pubDate>Sat, 16 Apr 2022 00:00:00 +0000</pubDate><guid>/posts/game_solution/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In &lt;a href="/posts/game_representation/">my last post&lt;/a>, we represented a sequential game of complete and perfect information as a trie. In this post, let&amp;rsquo;s solve that game!&lt;/p>
&lt;h1 id="setup">Setup&lt;/h1>
&lt;p>Let&amp;rsquo;s assume the following:&lt;/p>
&lt;ol>
&lt;li>The players act economically rational; they care only to maximize their own utility/payoff.&lt;/li>
&lt;li>No two possible combinations of moves yield the same exact utility/payoff for the same player.&lt;/li>
&lt;/ol>
&lt;p>With these assumptions, our sequential game of complete and perfect information must have a single deterministic outcome. To reach this outcome, we can use &lt;a href="https://en.wikipedia.org/wiki/Backward_induction">backward induction&lt;/a>, from game theory.&lt;/p></description></item><item><title>Computing sequential games: representation</title><link>/posts/game_representation/</link><pubDate>Sat, 09 Apr 2022 00:00:00 +0000</pubDate><guid>/posts/game_representation/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Let&amp;rsquo;s solve a sequential game of complete and perfect information with computers! First, let&amp;rsquo;s define such a game. Then, let&amp;rsquo;s describe how to represent such a game with computers. Later, we&amp;rsquo;ll describe an algorithm to solve such a game.&lt;/p>
&lt;h1 id="defining-the-game">Defining the game&lt;/h1>
&lt;p>A sequential game of complete and perfect information has 3 obvious features:&lt;/p>
&lt;ol>
&lt;li>Sequential means players make moves separately in order&lt;/li>
&lt;li>Complete information means players know everyone&amp;rsquo;s outcomes&lt;/li>
&lt;li>Perfect information means players know everyone&amp;rsquo;s (possible and played) moves&lt;/li>
&lt;/ol>
&lt;h1 id="representing-the-game">Representing the game&lt;/h1>
&lt;p>In mathematical notation, say we have &lt;em>n&lt;/em> players. Player &lt;em>i&lt;/em> (&lt;em>i&lt;/em> between 1 and n, inclusive) plays &lt;em>i&lt;/em>-th in the sequence and has &lt;em>c_i&lt;/em> choices, i.e. possible moves. We can represent all possible combinations of moves as &lt;em>n&lt;/em>-tuples of the form (&lt;em>m_0&lt;/em>, &lt;em>m_1&lt;/em>, &amp;hellip;, &lt;em>m_n&lt;/em>), where &lt;em>m_i&lt;/em> denotes the move the &lt;em>i&lt;/em>-th player made and falls between 1 and &lt;em>c_i&lt;/em>, inclusive.&lt;/p></description></item><item><title>Trie-d chords</title><link>/posts/trie/</link><pubDate>Sat, 02 Apr 2022 00:00:00 +0000</pubDate><guid>/posts/trie/</guid><description>&lt;p>In my &lt;a href="/posts/chords/">last post&lt;/a>, I explained the notion of &amp;ldquo;chords.&amp;rdquo; English words analogize to &amp;ldquo;chords&amp;rdquo; of Latin letters. And as it turns out, thinking of English words as &amp;ldquo;chords&amp;rdquo; gives us a useful way to approach common problems involving English words.&lt;/p>
&lt;p>Suppose you wanted to check if a &amp;ldquo;word&amp;rdquo; (sequence of Latin letters) exists in a dictionary. Naively, you could go through every entry in the dictionary. Clearly, this would take unpleasantly long for extremely large dictionaries.&lt;/p></description></item><item><title>Stenotype</title><link>/posts/stenotype/</link><pubDate>Sat, 26 Feb 2022 00:00:00 +0000</pubDate><guid>/posts/stenotype/</guid><description>&lt;p>When building a keyboard, you make a lot of choices.&lt;/p>
&lt;p>Organizationally, how many keys,&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> and do we align&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup> or stagger them?&lt;/p>
&lt;p>Structurally, does the keyboard split (one side per hand), and do we need a wire?&lt;/p>
&lt;p>Compositionally, what can we take apart (and replace), and what materials do the parts contain?&lt;/p>
&lt;p>However, perhaps the most meaningful choice we can make centers around function. &lt;em>What happens when we press keys?&lt;/em>&lt;/p>
&lt;p>You know &lt;a href="/posts/qwerty/">the QWERTY layout&lt;/a>; you may even know &lt;a href="/posts/dvorak/">the Dvorak layout&lt;/a>. However, your keyboard does more than just send characters. It also handles &amp;ldquo;modifiers&amp;rdquo;: shift, control, alt/option, super/windows/command. Your keyboard can interpret and send combinations of keys, e.g. shift+f = F or control+C.&lt;/p></description></item><item><title>Bottlehead Crack</title><link>/posts/bottlehead_crack/</link><pubDate>Sat, 18 Dec 2021 00:00:00 +0000</pubDate><guid>/posts/bottlehead_crack/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>For Cyber Monday, I ended up purchasing the Bottlehead Crack, a DIY headphones amplifier targeted at high impedance headphones like the Sennheiser HD 6XX I already owned. In this post, I&amp;rsquo;d like to break down why.&lt;/p>
&lt;h1 id="optimizing-seller-perspective">Optimizing seller perspective&lt;/h1>
&lt;p>I think of price from the seller&amp;rsquo;s perspective as the sum of&lt;/p>
&lt;pre tabindex="0">&lt;code>cost of inputs + cost of logistics + value of performance + value of marketing + value of usability 
&lt;/code>&lt;/pre>&lt;p>Assuming, I cannot control the cost of inputs nor logistics, if I hold the price constant and want to maximize the value of performance, I would &amp;ldquo;diminish&amp;rdquo; the value of marketing and usability.&lt;/p></description></item><item><title>Comparing audio equipment</title><link>/posts/audio_equipment/</link><pubDate>Sat, 04 Dec 2021 00:00:00 +0000</pubDate><guid>/posts/audio_equipment/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>This week, while &lt;a href="/posts/product_spaces/">shopping for a new headphones amp&lt;/a>, I&amp;rsquo;ve been looking for &amp;ldquo;best&amp;rdquo; headphones amps. This begs the question: how do we best compare audio equipment?&lt;/p>
&lt;h1 id="resolution-vs-profile">Resolution vs. profile&lt;/h1>
&lt;p>Okay, so obviously on a high level the &amp;ldquo;best&amp;rdquo; audio equipment produces the &amp;ldquo;best&amp;rdquo; audio. However, what constitutes &amp;ldquo;best&amp;rdquo; audio turns out much more challenging than you might expect.&lt;/p>
&lt;p>An easy (and in my not-quite-an-expert opinion, bad) definition of &amp;ldquo;best&amp;rdquo; audio relates to resolution. You could say the &amp;ldquo;best&amp;rdquo; audio equipment setup utilizes the most and loses the least music &amp;ldquo;information&amp;rdquo; in producing audio. However, as I covered in &lt;a href="/posts/resolution_profile/">a previous post&lt;/a>:&lt;/p></description></item><item><title>Why do you play (games)?</title><link>/posts/play_games/</link><pubDate>Sat, 23 Oct 2021 00:00:00 +0000</pubDate><guid>/posts/play_games/</guid><description>&lt;p>During the Inside Times, I spent a lot of time in my small hometown. To pass the time, to cope, I played a lot of Warframe, roughly 1000 hours over the past year, in fact. That averages out to around &lt;em>3 hours per day&lt;/em>. Wow.&lt;/p>
&lt;p>Warframe doesn&amp;rsquo;t have much difficulty. I would characterize the gameplay as just satisfying enough, and certainly plentiful enough, to capture your attention in loop for a long while (roughly 1000 hours, apparently). When I wanted to flow through boredom and trouble without really straining, I would load up Warframe.&lt;/p></description></item><item><title>CJK segmentation</title><link>/posts/cjk_segmentation/</link><pubDate>Sat, 02 Oct 2021 00:00:00 +0000</pubDate><guid>/posts/cjk_segmentation/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Let&amp;rsquo;s return to &lt;a href="https://www.unicode.org/versions/Unicode14.0.0/ch18.pdf">the Unicode Standard&lt;/a> from the last post:&lt;/p>
&lt;blockquote>
&lt;p>Programmers do not expect the characters c, h, a, and t alone to tell us whether chat is a French word for cat or an English word meaning informal talk. &amp;hellip; Similarly, the Han characters are often combined to &amp;ldquo;spell&amp;rdquo; words whose meaning may not be evident from the constituent characters. For example, the two characters &amp;ldquo;to cut&amp;rdquo; and &amp;ldquo;hand&amp;rdquo; mean &amp;ldquo;postage stamp&amp;rdquo;&amp;quot; in Japanese, but the compound may appear to be nonsense to a speaker of Chinese or Korean.
&lt;img src="/han-spelling.jpg" alt="Han spelling">&lt;/p></description></item><item><title>CJK fonts</title><link>/posts/cjk_fonts/</link><pubDate>Sat, 25 Sep 2021 00:00:00 +0000</pubDate><guid>/posts/cjk_fonts/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>You may wonder, based on my &lt;a href="/posts/language_history/">previous post&lt;/a>, how Unicode handles when the same Han character gets written differently in different languages. Writing evolves over time, so can we represent the same Han character with the same Unicode code point across languages? &lt;a href="https://www.unicode.org/faq/han_cjk.html#3">Unicode&lt;/a> answers:&lt;/p>
&lt;blockquote>
&lt;p>Even where there are substantial variations in the standard way of writing a character from locale to locale, if the fundamental identity of the character is not in question, then a single character is encoded in Unicode. &amp;hellip; It is well-recognized that the Han characters involved are the same, even when used in different countries to write different languages. &amp;hellip; There are occasional instances of unified characters whose typical Chinese glyph and typical Japanese glyph are distinct enough that the Chinese glyph will be unfamiliar to the typical Japanese reader, e.g., 直 U+76F4. &amp;hellip; Where a distinction in style needs to be made (for example, Chinese-style vs. Japanese-style glyphs in the same document), appropriate fonts should be applied to the specific text as needed.&lt;/p></description></item><item><title>Language carries history</title><link>/posts/language_history/</link><pubDate>Sat, 18 Sep 2021 00:00:00 +0000</pubDate><guid>/posts/language_history/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>To demonstrate language carries history, I&amp;rsquo;ll use Unicode.&lt;/p>
&lt;h1 id="unicode">Unicode&lt;/h1>
&lt;p>First, what &amp;ldquo;Unicode&amp;rdquo;? Unicode defines encoding characters (formally, &lt;a href="https://unicode.org/glossary/#grapheme">graphemes&lt;/a>, a minimally distinctive unit of writing), including letters, symbols, and emoji 😮. Unicode covers most of the world&amp;rsquo;s writing systems, and nearly all web pages use Unicode (UTF-8).&lt;/p>
&lt;p>Unicode provides a unique code point, a number, for each character. For example, the (decimal) number 75, 0b01001011 in binary, represents the uppercase K. Computers represent data in binary, so essentially Unicode provides a mapping from binary data to characters.&lt;/p></description></item><item><title>QWERTY again</title><link>/posts/qwerty_again/</link><pubDate>Sat, 21 Aug 2021 00:00:00 +0000</pubDate><guid>/posts/qwerty_again/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>&lt;a href="/posts/qwerty/">Last time I posted about QWERTY&lt;/a>, I alluded to the ubiquity of the QWERTY layout. By default, laptop and phone keyboards come in the QWERTY layout, which they inherit from the typewriter. How, then, did the QWERTY layout become the standard for typewriters, and later keyboards? The answer comes down to business and education.&lt;/p>
&lt;h1 id="business">Business&lt;/h1>
&lt;p>&lt;a href="https://americanhistory.si.edu/collections/search/object/nmah_850053">In 1886, three former Remington employees purchased the typewriter business from Remington&lt;/a>. Then &lt;a href="https://www.vox.com/2017/9/27/16369508/qwerty-keyboards-history">in 1893, Seamans&amp;rsquo; company merged with four other typewriter manufacturers to form the trust Union Typewriter Company&lt;/a>. &lt;a href="http://www.willdavis.org/Union.html">With the manufacturer of the Remington Standard machine biggest among the trust, and the trust biggest among the typewriters market&lt;/a>, &lt;a href="https://www.vox.com/2017/9/27/16369508/qwerty-keyboards-history">QWERTY, the layout of the Remington Standard machine, became the standard layout for typewriters&lt;/a>.&lt;/p></description></item><item><title>Dvorak</title><link>/posts/dvorak/</link><pubDate>Sat, 14 Aug 2021 00:00:00 +0000</pubDate><guid>/posts/dvorak/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In my last post, I noted &lt;a href="/posts/qwerty/">&amp;ldquo;the QWERTY layout does NOT prioritize the comfort of the human hand.&amp;rdquo;&lt;/a> This did not escape the attention of August Dvorak, who in the 1930s created the Dvorak layout:
&lt;img src="https://upload.wikimedia.org/wikipedia/commons/2/25/KB_United_States_Dvorak.svg" alt="Dvorak layout">&lt;/p>
&lt;p>Dvorak designed the layout to overcome the awkwardness perceived of the QWERTY layout, specifically that common letter combinations require too much movement, especially by the left hand and weaker fingers, in the QWERTY layout. Dvorak claimed the new layout would lead to faster typing with less stress on the hands and wrists. Let&amp;rsquo;s investigate.&lt;/p></description></item><item><title>QWERTY</title><link>/posts/qwerty/</link><pubDate>Sat, 07 Aug 2021 00:00:00 +0000</pubDate><guid>/posts/qwerty/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Unless you&amp;rsquo;ve explicitly chosen NOT to, you&amp;rsquo;re probably typing on a QWERTY keyboard. Starting from the Q key, read each right-adjacent letter: Q W E R T Y, a QWERTY keyboard.&lt;/p>
&lt;p>Why does the QWERTY layout arrange letters as it does?&lt;/p>
&lt;h1 id="history">History&lt;/h1>
&lt;p>Christopher Latham Sholes first filed for &lt;a href="https://patents.google.com/patent/US79265A/en">a typewriting patent in 1867&lt;/a>. The first model built by Sholes had &lt;a href="https://patents.google.com/patent/US79868A/en">alphabetically arranged keys&lt;/a>:&lt;/p>
&lt;pre tabindex="0">&lt;code>- 3 5 7 9 N O P Q R S T U V W X Y Z
 2 4 6 8 . A B C D E F G H I J K L M
&lt;/code>&lt;/pre>&lt;p>Over the next few years, Sholes iterated on the arrangement of keys. &lt;a href="https://www.smithsonianmag.com/arts-culture/fact-of-fiction-the-legend-of-the-qwerty-keyboard-49863249">For example, an 1873 prototype has an almost-QWERTY layout&lt;/a>, from what I can tell in the picture, roughly:&lt;/p></description></item><item><title>Ergonomic keyboards</title><link>/posts/ergo_keyboards/</link><pubDate>Sat, 03 Jul 2021 00:00:00 +0000</pubDate><guid>/posts/ergo_keyboards/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>I want you to sit or stand. Now, hold your left arm up with your right arm (like you&amp;rsquo;re aiming an arm cannon on your left arm), and relax your left arm as much as possible.&lt;/p>
&lt;p>If you followed the instructions correctly, your left hand should hang limp, slightly downward. In order to raise your left hand, you have to strain your left wrist just a little bit. In ergonomics, you call this &lt;a href="http://www.ergovancouver.net/wrist_movements.htm">extension&lt;/a>.&lt;/p></description></item><item><title>Audiophilia: resolution vs. profile</title><link>/posts/resolution_profile/</link><pubDate>Sat, 19 Jun 2021 00:00:00 +0000</pubDate><guid>/posts/resolution_profile/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Take these two side-by-side images of &lt;em>The Great Wave off Kanagawa&lt;/em>:
&lt;img src="/side-by-side-resolution.jpg" alt="Resolution side-by-side">
One of them has the resolution 3858x2592 pixels, the other 1929x1296 pixels (scaled back up to 3858x2592 for comparison). Can you tell them apart?&lt;/p>
&lt;p>I can&amp;rsquo;t. If you can, I bet you have to look really close to notice a difference. If I take a 12x12 sample of each&amp;rsquo;s bottom-left corner (and scale it up), you cal tell the difference:
&lt;img src="/side-by-side-sample.jpg" alt="Resolution side-by-side sample">
The left side has the lower resolution.&lt;/p></description></item><item><title>Configuring my new Mac III: zsh / kitty</title><link>/posts/mac_zsh/</link><pubDate>Sat, 27 Mar 2021 00:00:00 +0000</pubDate><guid>/posts/mac_zsh/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>A command-line interface (CLI) lets you run lower-level operations (&amp;ldquo;commands&amp;rdquo;) quickly and flexibly. For example, suppose I have 1000 .txt files that I wanted to rename only if they contain the word &amp;ldquo;banana&amp;rdquo; or &amp;ldquo;onion&amp;rdquo; (ignoring case, so &amp;ldquo;Onion&amp;rdquo; and &amp;ldquo;Banana&amp;rdquo; included). I can simply run&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-zsh" data-lang="zsh">&lt;span style="display:flex;">&lt;span>$ grep -l -i &lt;span style="color:#e6db74">&amp;#34;banana|onion&amp;#34;&lt;/span> | rename -s &lt;span style="color:#e6db74">&amp;#34;.txt&amp;#34;&lt;/span> &lt;span style="color:#e6db74">&amp;#34;_with_food.txt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you do deep computer-y stuff often, you could probably benefit from learning to use CLI.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p></description></item><item><title>The auto industry</title><link>/posts/auto_industry/</link><pubDate>Sat, 06 Mar 2021 00:00:00 +0000</pubDate><guid>/posts/auto_industry/</guid><description>&lt;h1 id="i">I&lt;/h1>
&lt;p>The auto industry has employed my mom for most of her career. For as long as I can remember, she&amp;rsquo;s worked for General Motors.&lt;/p>
&lt;p>My junior year, the CEO of General Motors spoke to my class. As I thanked Mary Barra, I thought of how hard my mom worked to give me these opportunities. Then I called my mom to thank her for &amp;hellip; everything. I stayed through the tears until I could find all the words for her.&lt;/p></description></item><item><title>Configuring my new Mac II: Firefox</title><link>/posts/mac_firefox/</link><pubDate>Sat, 30 Jan 2021 00:00:00 +0000</pubDate><guid>/posts/mac_firefox/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>For most users, the web browser connects the computer to &lt;em>everything else&lt;/em>. For compatibility, availability, and reliability, more and more apps are moving into the web browser. You, or at least I, send messages, edit documents, and watch videos from a browser.&lt;/p>
&lt;h1 id="choosing-a-browser">Choosing a browser&lt;/h1>
&lt;p>Unless you have a niche use case, most browsers will work well enough. In practical terms, it suffices to only consider switching browsers when you notice something wrong with your browser. Otherwise, you might switch browsers if you discover some features you didn&amp;rsquo;t know about before. For the latter,&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> I&amp;rsquo;ve compiled a list of features/extensions not built into browsers.&lt;/p></description></item><item><title>(Technical) language nudges thought</title><link>/posts/language_nudges/</link><pubDate>Sat, 23 Jan 2021 00:00:00 +0000</pubDate><guid>/posts/language_nudges/</guid><description>&lt;p>&lt;a href="/posts/medium_nudges/">Continued in this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>The Sapir-Whorf hypothesis states that the structure of a language influences the cognition of its speaker. Now, before we proceed, I caution that &lt;a href="https://languagelog.ldc.upenn.edu/nll/?p=2592">&amp;ldquo;there is probably no single linguistic idea that is more prone to exaggeration and mis-application than the &amp;lsquo;Sapir-Whorf hypothesis.&amp;rsquo;&amp;rdquo;&lt;/a> Let&amp;rsquo;s see an example.&lt;/p>
&lt;h1 id="whodunit">Whodunit?&lt;/h1>
&lt;p>In English, you would tend to say &amp;ldquo;They broke the vase,&amp;rdquo; whereas in Spanish you would more tend to say &amp;ldquo;El jarrón se rompió&amp;rdquo; (&lt;a href="https://elperiodico.com.gt/opinion/opiniones-de-hoy/2020/05/14/el-jarron-se-rompio/">example&lt;/a>), which literally translates to &amp;ldquo;the vase broke itself&amp;rdquo; (&lt;a href="https://www.wsj.com/articles/SB10001424052748703467304575383131592767868">paywall&lt;/a>).&lt;/p></description></item><item><title>Configuring my new (new) Mac I: Homebrew</title><link>/posts/mac_homebrew/</link><pubDate>Sat, 16 Jan 2021 00:00:00 +0000</pubDate><guid>/posts/mac_homebrew/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In this series of posts I&amp;rsquo;d like to walk through the process of configuring my new Mac to&lt;/p>
&lt;ol>
&lt;li>help out anyone else configuring their Mac&lt;/li>
&lt;li>interrogate and reflect on the decisions I make during configuration&lt;/li>
&lt;li>provide a stable reference to conveniently come back to if needed&lt;/li>
&lt;/ol>
&lt;h1 id="package-managers">Package managers&lt;/h1>
&lt;p>Like mobile app stores, package managers provide a single place to manage installing, updating, and removing programs. Package managers, however, tend to have more of a open-source, power user connotation. Coming from Arch Linux, I like and prefer to use a package manager.&lt;/p></description></item><item><title>JANK™</title><link>/posts/jank/</link><pubDate>Sat, 09 Jan 2021 00:00:00 +0000</pubDate><guid>/posts/jank/</guid><description>&lt;p>The laws of nature dictate that whenever I, your beloved not-quite-an-expert, get a new computer JANK™ ensues.&lt;/p>
&lt;p>As I mentioned recently, my previous laptop stopped charging. Before you ask, I would like to know why it stopped charging as well. I didn&amp;rsquo;t dunk it into a swimming pool; it just suddenly stopped charging.&lt;/p>
&lt;p>To replace it, I bought an HP Envy x360. And within the first week, the Wi-Fi stopped working. Not as in it had trouble connecting from time to time. This new laptop straight up would not even scan for networks.&lt;/p></description></item><item><title>Confessions of a recent Mac convert</title><link>/posts/mac_convert/</link><pubDate>Sat, 26 Dec 2020 00:00:00 +0000</pubDate><guid>/posts/mac_convert/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In high school. I wanted to become a &lt;em>computer person&lt;/em>. Sure, I had dabbled with HTML/CSS before. However, in my mind a &lt;em>computer person&lt;/em> had 3 things:&lt;/p>
&lt;ol>
&lt;li>proficiency in a &lt;em>real&lt;/em> programming language&lt;/li>
&lt;li>a powerful laptop&lt;/li>
&lt;li>strong opinions&lt;/li>
&lt;/ol>
&lt;p>Already a Holder of Strong Opinions, I eagerly pulled up an online Python class on Udacity. Armed with the free time of spring and summer break, I charged through the class at a pace of one day per one week&amp;rsquo;s worth of material. Soon enough, I could write cool (i.e. badly structured, generally useless, really just all-around non-Pythonic) Python programs!&lt;/p></description></item><item><title>The smoking backup</title><link>/posts/smoking_backup/</link><pubDate>Sat, 17 Oct 2020 00:00:00 +0000</pubDate><guid>/posts/smoking_backup/</guid><description>&lt;p>Story time, buckos.&lt;/p>
&lt;p>Flashback to freshman year, a time when people could go out without weighing the risk toward public health. Remember outside?&lt;/p>
&lt;p>I had entered the Nesbitt Room, a public study room where you pretended to get work done while listening to math students complain. On one hand, &amp;ldquo;my math classes have too much work!&amp;rdquo; On the other hand, &amp;ldquo;my non-math classes have too little math!&amp;rdquo;&lt;/p>
&lt;p>Hoping to make progress on my EECS project, I busted out my trusty laptop and started to &amp;ldquo;work.&amp;rdquo; My laptop had been bothering me for the past week. The bottom case had came loose, and the resistance to pushing it back into place indicated something had bent or shifted inside. However, &amp;ldquo;don&amp;rsquo;t fix what ain&amp;rsquo;t broke,&amp;rdquo; I reasoned, since I could still use my laptop without issue. Oh how wrong, this excuse!&lt;/p></description></item><item><title>Context managers in Python classes</title><link>/posts/context_manager_classes/</link><pubDate>Sat, 03 Oct 2020 00:00:00 +0000</pubDate><guid>/posts/context_manager_classes/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>&lt;a href="/posts/context_managers/">Context managers in Python allow us to easily manage opening and closing resources&lt;/a>. However, sometimes we want to define classes that use these context managers, in which case the &lt;code>with&lt;/code> statement construct will not work.&lt;/p>
&lt;h1 id="synchronous-example">Synchronous example&lt;/h1>
&lt;p>Consider a class that manages data from multiple files:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Python" data-lang="Python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">DataManager&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">def&lt;/span> __init__(self, input_file_names, output_file_name):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> self&lt;span style="color:#f92672">.&lt;/span>inputs &lt;span style="color:#f92672">=&lt;/span> list(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> map(&lt;span style="color:#66d9ef">lambda&lt;/span> input_file_name: open(input_file_name, &lt;span style="color:#e6db74">&amp;#34;r&amp;#34;&lt;/span>),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> input_file_names))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> self&lt;span style="color:#f92672">.&lt;/span>output &lt;span style="color:#f92672">=&lt;/span> open(output_file_name, &lt;span style="color:#e6db74">&amp;#34;w&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In this form, we open and fail to close the files. See &lt;a href="/posts/context_managers/">&amp;ldquo;Why do we need to close, anyway?&amp;rdquo; from this post&lt;/a> for reasons we should always close opened resources like files.&lt;/p></description></item><item><title>Four views on Microwave Cooking for One</title><link>/posts/microwave_one/</link><pubDate>Sat, 12 Sep 2020 00:00:00 +0000</pubDate><guid>/posts/microwave_one/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>&lt;a href="https://www.amazon.com/Microwave-Cooking-One-Marie-Smith/dp/1565546660">From the Amazon listing&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>Fast, easy, and economical, the recipes in Microwave Cooking for One are ideal for individuals, whether they live alone or share busy modern households. From breakfast through dinner, fresh, delicious meals can be prepared to satisfy personal tastes without wasted food, overheated kitchens, or messy clean-up.&lt;/p>
&lt;/blockquote>
&lt;h1 id="view-i">View I&lt;/h1>
&lt;p>&lt;em>Microwave Cooking for One&lt;/em> represents the height of laziness! You can&amp;rsquo;t bother yourself with preparing a proper meal; you can&amp;rsquo;t even bring yourself to talk to the delivery driver. You filth! You, utter, utter, &lt;em>filth&lt;/em>! For &lt;em>once&lt;/em>, get out of your bed or off of your couch. For &lt;em>once&lt;/em>, stop binging your favorite show for the tenth time and do &lt;em>something&lt;/em>! No, shoving three things into the microwave doesn&amp;rsquo;t count. Did you do the thing I asked you to do two days ago? No? &lt;em>Of course you didnt&lt;/em>.&lt;/p></description></item><item><title>async Python tips</title><link>/posts/async_tips/</link><pubDate>Sat, 22 Aug 2020 00:00:00 +0000</pubDate><guid>/posts/async_tips/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>When you live on the edge, you get cut! &lt;code>async&lt;/code> came to Python rather recently, so I&amp;rsquo;ve been &amp;ldquo;cut&amp;rdquo; using it quite a few times. If you want to get started with &lt;code>async&lt;/code> Python, I have a few tips:&lt;/p>
&lt;ol>
&lt;li>&lt;code>await&lt;/code> every &lt;code>async&lt;/code>, except one.&lt;/li>
&lt;li>&lt;code>async&lt;/code> can include non-&lt;code>async&lt;/code>. Non-&lt;code>async&lt;/code> cannot include &lt;code>async&lt;/code>.&lt;/li>
&lt;li>You cannot interchange &lt;code>async&lt;/code> and non-&lt;code>async&lt;/code> constructs.&lt;/li>
&lt;/ol>
&lt;h1 id="tip-1">Tip 1&lt;/h1>
&lt;p>An &lt;code>async def&lt;/code> function actually returns something known as a coroutine. To run a coroutine, you must either:&lt;/p></description></item><item><title>async Python</title><link>/posts/async_python/</link><pubDate>Sat, 15 Aug 2020 00:00:00 +0000</pubDate><guid>/posts/async_python/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Often, hardware I/O bottlenecks a program&amp;rsquo;s latency, thoroughput, and/or run time. That is, file and network actions slow down the program most significantly. A program often consists of many independent file and network actions. In those cases, Python gives us the &lt;code>async&lt;/code> construct for running the actions asynchronously.&lt;/p>
&lt;h1 id="syntax">Syntax&lt;/h1>
&lt;p>In general, &lt;code>async&lt;/code> Python programming involves adding the keyword &lt;code>async&lt;/code> in front of the non-asynchronous version. Instead of &lt;code>def&lt;/code>, use &lt;code>async def&lt;/code>. Instead of &lt;code>with&lt;/code>, use &lt;code>async with&lt;/code>. Finally, instead of &lt;code>for&lt;/code>, use &lt;code>async for&lt;/code>.&lt;/p></description></item><item><title>Context managers in Python</title><link>/posts/context_managers/</link><pubDate>Sat, 08 Aug 2020 00:00:00 +0000</pubDate><guid>/posts/context_managers/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In programming, we often need to manage resources that &amp;ldquo;open&amp;rdquo; and &amp;ldquo;close.&amp;rdquo; As a simple example, you might open a file, read its contents, then close it.&lt;/p>
&lt;p>However, when dealing with complicated paths of logic, we may find it difficult to reason about manually closing every open resource. Consider:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Python" data-lang="Python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> json
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">get_json_data&lt;/span>(json_file_name):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># we must eventually close this opened file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file &lt;span style="color:#f92672">=&lt;/span> open(json_file_name, &lt;span style="color:#e6db74">&amp;#34;r+&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">try&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_data &lt;span style="color:#f92672">=&lt;/span> json&lt;span style="color:#f92672">.&lt;/span>load(json_file)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">except&lt;/span> json&lt;span style="color:#f92672">.&lt;/span>JSONDecodeError &lt;span style="color:#66d9ef">as&lt;/span> decode_err:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># close here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>close()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">raise&lt;/span> &lt;span style="color:#a6e22e">ValueError&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>json_file_name&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74"> does not contain valid JSON: &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>str(decode_err)&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#e6db74">&amp;#34;error&amp;#34;&lt;/span> &lt;span style="color:#f92672">in&lt;/span> json_data:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># close here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>close()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">raise&lt;/span> &lt;span style="color:#a6e22e">KeyError&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;JSON data contains &lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">error&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74"> key with value &lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>json_data[&lt;span style="color:#e6db74">&amp;#39;error&amp;#39;&lt;/span>]&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#e6db74">&amp;#34;status&amp;#34;&lt;/span> &lt;span style="color:#f92672">in&lt;/span> json_data:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> status &lt;span style="color:#f92672">=&lt;/span> json_data[&lt;span style="color:#e6db74">&amp;#34;status&amp;#34;&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> status &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;new&amp;#34;&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># close here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>close()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">raise&lt;/span> &lt;span style="color:#a6e22e">ValueError&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;JSON data contains &lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">status&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74"> key with value &amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">{&lt;/span>json_data[&lt;span style="color:#e6db74">&amp;#39;status&amp;#39;&lt;/span>]&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">, while value &lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">new&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74"> expected&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">try&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> validate(json_data)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_data[&lt;span style="color:#e6db74">&amp;#34;status&amp;#34;&lt;/span>] &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;old&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># overwrite json_file contents with status &amp;#34;old&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>seek(&lt;span style="color:#ae81ff">0&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>truncate()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json&lt;span style="color:#f92672">.&lt;/span>dump(json_data, json_file)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># close here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>close()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> json_data
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">except&lt;/span> &lt;span style="color:#a6e22e">KeyError&lt;/span> &lt;span style="color:#66d9ef">as&lt;/span> validation_error:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># close here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>close()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">raise&lt;/span> &lt;span style="color:#a6e22e">KeyError&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">f&lt;/span>&lt;span style="color:#e6db74">&amp;#34;JSON data validation failed on key &lt;/span>&lt;span style="color:#e6db74">{&lt;/span>str(validation_error)&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># close here&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> json_file&lt;span style="color:#f92672">.&lt;/span>close()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">raise&lt;/span> &lt;span style="color:#a6e22e">KeyError&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;JSON data does not contain &lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74">status&lt;/span>&lt;span style="color:#ae81ff">\&amp;#34;&lt;/span>&lt;span style="color:#e6db74"> key&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Viewing this example code from just a high level, we can notice that properly dealing with the complicated paths of logic involves many calls to close the opened file.&lt;/p></description></item><item><title>Partial reinforcement and addictive games</title><link>/posts/game_reinforcement/</link><pubDate>Sat, 27 Jun 2020 00:00:00 +0000</pubDate><guid>/posts/game_reinforcement/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>I&amp;rsquo;ve been gaming a lot recently, so this has been on my mind.&lt;/p>
&lt;h1 id="reinforcement-and-punishment">Reinforcement and punishment&lt;/h1>
&lt;p>In operant conditioning, behavior is modified with reinforcement and punishment. Reinforcement and punishment are defined pretty much exactly as you would intuit:&lt;/p>
&lt;ol>
&lt;li>Reinforcement uses a pleasant result to encourage behavior.&lt;/li>
&lt;li>Punishment uses an unpleasant result to discourage behavior.&lt;/li>
&lt;/ol>
&lt;p>In formal terms, both reinforcement and punishment can be &amp;ldquo;positive&amp;rdquo; or &amp;ldquo;negative.&amp;rdquo; Note &amp;ldquo;positive&amp;rdquo; and &amp;ldquo;negative&amp;rdquo; do &lt;strong>not&lt;/strong> refer to goodness. Here, by &amp;ldquo;positive&amp;rdquo; we mean &amp;ldquo;giving,&amp;rdquo; and by &amp;ldquo;negative&amp;rdquo; we mean &amp;ldquo;taking away.&amp;rdquo; Positive reinforcement gives a pleasant stimulus; negative reinforcement takes away an unpleasant stimulus.&lt;/p></description></item><item><title>So, you wanna get into mechanical keyboards, eh?</title><link>/posts/mech_keyboards/</link><pubDate>Sat, 20 Jun 2020 00:00:00 +0000</pubDate><guid>/posts/mech_keyboards/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Well, do you? Because I&amp;rsquo;ve got a guide from someone who&amp;rsquo;s not quite an expert: me!&lt;/p>
&lt;h1 id="step-1-reconsider">Step 1: Reconsider&lt;/h1>
&lt;p>Like most hobbies, mechanical keyboards take time and money. A nice mechanical keyboard could cost you a few hundred dollars. And with the time it takes you to form an opinion on mechanical keyboards, you could instead form an opinion on folding origami, or painting, or &lt;a href="/posts/onions_cont/">cooking with onions&lt;/a>.&lt;/p>
&lt;p>Mechanical keyboards are probably most useful for people in technology or technology-adjacent careers.&lt;/p></description></item><item><title>A very, very light introduction to security continued for a final time</title><link>/posts/crypt_final/</link><pubDate>Sat, 06 Jun 2020 00:00:00 +0000</pubDate><guid>/posts/crypt_final/</guid><description>&lt;p>&lt;a href="/posts/crypt_cont_again/">A continuation of this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In &lt;a href="/posts/crypt_cont_again/">the previous post&lt;/a> we described how to make the process of establishing confidentiality, authenticity, and integrity more efficient. Now let&amp;rsquo;s put in some finishing touches.&lt;/p>
&lt;h1 id="primer-you-gotta-trust-someone">Primer: &amp;ldquo;you gotta&amp;rsquo; trust someone&amp;rdquo;&lt;/h1>
&lt;p>In any system, you have to trust someone. When paying with a credit card, you trust the payment provider. When sending mail, you trust the postal service. When cooking food, you trust the grocer. The list goes on.&lt;/p></description></item><item><title>A very, very light introduction to security continued again</title><link>/posts/crypt_cont_again/</link><pubDate>Sat, 30 May 2020 00:00:00 +0000</pubDate><guid>/posts/crypt_cont_again/</guid><description>&lt;p>&lt;a href="/posts/crypt_cont/">A continuation of this post&lt;/a>&lt;/p>
&lt;p>&lt;a href="/posts/crypt_final/">Continued in this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In &lt;a href="/posts/crypt_cont/">the previous post&lt;/a> we described the basic process of how to achieve the 3 desired outcomes of security:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Confidentiality: only the sender(s) and the receiver(s) can understand the message.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Authenticity: the receiver(s) can verify the identity of the sender(s).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Integrity: the receiver(s) can verify the message was not altered from its original content.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>Now let&amp;rsquo;s add efficiency considerations.&lt;/p>
&lt;h1 id="primer-security-trade-offs">Primer: security trade-offs&lt;/h1>
&lt;p>A good rule of thumb is increasing security decreases usability. For example, putting your favorite pants into a locked safe with an unknown code makes them very secure against theft, and very hard to wear.&lt;/p></description></item><item><title>A very, very light introduction to security continued</title><link>/posts/crypt_cont/</link><pubDate>Sat, 23 May 2020 00:00:00 +0000</pubDate><guid>/posts/crypt_cont/</guid><description>&lt;p>&lt;a href="/posts/crypt/">A continuation of this post&lt;/a>&lt;/p>
&lt;p>&lt;a href="/posts/crypt_cont_again/">Continued in this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In &lt;a href="/posts/crypt/">a previous post&lt;/a> we defined 3 desired outcomes of security:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Confidentiality: only the sender(s) and the receiver(s) can understand the message.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Authenticity: the receiver(s) can verify the identity of the sender(s).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Integrity: the receiver(s) can verify the message was not altered from its original content.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;p>That post covered how to achieve confidentiality. In this post, we&amp;rsquo;ll cover authenticity and integrity.&lt;/p></description></item><item><title>Let's actually build a random Spotify album selector!</title><link>/posts/spotify_selector_cont/</link><pubDate>Sat, 16 May 2020 00:00:00 +0000</pubDate><guid>/posts/spotify_selector_cont/</guid><description>&lt;p>&lt;a href="/posts/spotify_selector/">A continuation of this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Okay, for real this time. I&amp;rsquo;m going to do it in Rust because I like Rust. &lt;a href="https://github.com/jgjin/random_album">Code is available in a GitHub repo for reference&lt;/a>, and I&amp;rsquo;ll be linking files where I can.&lt;/p>
&lt;p>We&amp;rsquo;re going to cover a lot of technologies (including a pretty large tour of Rust), so get ready! Here&amp;rsquo;s a preview of what we&amp;rsquo;ll end up covering:&lt;/p>
&lt;ol>
&lt;li>Installing Rust&lt;/li>
&lt;li>Cargo&lt;/li>
&lt;li>Rocket&lt;/li>
&lt;li>OAuth&lt;/li>
&lt;li>Rust types (&lt;code>enum&lt;/code>s, &lt;code>struct&lt;/code>s, and &lt;code>trait&lt;/code>s)&lt;/li>
&lt;li>Environment variables (&lt;code>.env&lt;/code>)&lt;/li>
&lt;li>&lt;code>serde&lt;/code>&lt;/li>
&lt;li>Pagination APIs&lt;/li>
&lt;li>Caches&lt;/li>
&lt;li>Concurrency (for HTTP asynchronousness)&lt;/li>
&lt;li>&lt;code>Option&lt;/code>s and &lt;code>Result&lt;/code>s&lt;/li>
&lt;li>HTML, CSS, and JavaScript&lt;/li>
&lt;li>Dynamic web content&lt;/li>
&lt;li>HTML templating&lt;/li>
&lt;li>Deployment&lt;/li>
&lt;li>Debugging&lt;/li>
&lt;li>Optimizing web content&lt;/li>
&lt;/ol>
&lt;h1 id="installing-rust">Installing Rust&lt;/h1>
&lt;p>Installing Rust is easy (on non-Windows systems). In terminal, run:&lt;/p></description></item><item><title>Let's build a random Spotify album selector!</title><link>/posts/spotify_selector/</link><pubDate>Sat, 09 May 2020 00:00:00 +0000</pubDate><guid>/posts/spotify_selector/</guid><description>&lt;p>&lt;a href="/posts/spotify_selector_cont/">Continued in this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>You read the title; let&amp;rsquo;s do it!&lt;/p>
&lt;h1 id="meta-goals">Meta-goals&lt;/h1>
&lt;p>I have 2 main goals for this post:&lt;/p>
&lt;ol>
&lt;li>Describe the process of making something.&lt;/li>
&lt;li>Write some code! I&amp;rsquo;ve been itching to code for a while.&lt;/li>
&lt;/ol>
&lt;h1 id="so-how-do-should1-we-make-something">So how do (should&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>) we make something?&lt;/h1>
&lt;h2 id="audience">Audience&lt;/h2>
&lt;p>Let&amp;rsquo;s start with the most basic, perhaps most important question:&lt;/p>
&lt;blockquote>
&lt;p>Who&amp;rsquo;s this for, anyway?&lt;/p>
&lt;/blockquote>
&lt;p>How you answer this question strongly influences every step of making something. Different audiences have wildly different needs, behaviors, and environments. For example, making food for newborn babies is vastly different than making food for 30-something adults. A newborn baby needs food that can be digested without chewing; the 30-something makes their own decisions on where and when to consume food.&lt;/p></description></item><item><title>A very, very light introduction to security</title><link>/posts/crypt/</link><pubDate>Sat, 02 May 2020 00:00:00 +0000</pubDate><guid>/posts/crypt/</guid><description>&lt;p>&lt;a href="/posts/crypt_cont/">Continued in this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>&lt;a href="https://getpocket.com/explore/item/the-feynman-technique-the-best-way-to-learn-anything">They say the best way to learn something is to explain it to a 5-year-old (or some other beginner).&lt;/a> So let&amp;rsquo;s explain security!&lt;/p>
&lt;h1 id="desired-outcomes">Desired outcomes&lt;/h1>
&lt;p>In security, we want to create 3 outcomes:&lt;/p>
&lt;ol>
&lt;li>Confidentiality&lt;/li>
&lt;/ol>
&lt;p>Only the sender(s) and the receiver(s) can understand the message. For example, if you sent your coworker an invite to lunch, neither your boss nor the government could see the invite.&lt;/p></description></item><item><title>Jupyter, and collaborative filtering continued</title><link>/posts/jupyter_collab_filter/</link><pubDate>Sat, 25 Apr 2020 00:00:00 +0000</pubDate><guid>/posts/jupyter_collab_filter/</guid><description>&lt;p>&lt;a href="/posts/collab_filter/">A continuation of this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>I came across &lt;a href="https://www.theatlantic.com/science/archive/2018/04/the-scientific-paper-is-obsolete/556676/">an interesting &lt;em>Atlantic&lt;/em> article&lt;/a> recently.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> tl;dr: Wolfram and Jupyter notebooks allow us to express research, especially research involving programming, more precisely and reproducibly than traditional paper papers. Of course, durability is a concern with Wolfram and Jupyter notebooks. However, I wanted to make an honest effort of Jupyter notebooks in this post.&lt;/p>
&lt;h1 id="the-jupyter-bazaar">The Jupyter bazaar&lt;/h1>
&lt;p>In his famous 1997 essay, &lt;em>The Cathedral and the Bazaar: Musings on Linux and Open Source by an Accidental Revolutionary&lt;/em>, Eric Steven Raymond contrasts two development models:&lt;/p></description></item><item><title>Hand-over-hand locking with the RAII pattern</title><link>/posts/raii_hoh_locking/</link><pubDate>Sat, 18 Apr 2020 00:00:00 +0000</pubDate><guid>/posts/raii_hoh_locking/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Let&amp;rsquo;s start by explaining locks (mutexes), hand-over-hand locking, and RAII. Then we&amp;rsquo;ll provide some sample code to accomplish hand-over-hand locking with the RAII pattern.&lt;/p>
&lt;h1 id="mutexes-aka-locks">Mutexes, a.k.a. locks&lt;/h1>
&lt;p>In concurrent programming, a common method for protecting shared resources between threads is using a mutex&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>, or lock. For everyday concurrent programming, there are 2 types of mutexes we care about:&lt;/p>
&lt;ol>
&lt;li>Regular mutexes&lt;/li>
&lt;/ol>
&lt;p>The regular mutex supports two main operations: &lt;code>lock&lt;/code> and &lt;code>unlock&lt;/code>. Once a thread &lt;code>lock&lt;/code>s the mutex, any other call to &lt;code>lock&lt;/code> the mutex is blocked until that thread calls &lt;code>unlock&lt;/code>. This way, threads can prevent other threads from accessing or modifying a shared resource until the first-locking thread is done with the shared resource.&lt;/p></description></item><item><title>Collaborative filtering</title><link>/posts/collab_filter/</link><pubDate>Sat, 11 Apr 2020 00:00:00 +0000</pubDate><guid>/posts/collab_filter/</guid><description>&lt;p>&lt;a href="/posts/jupyter_collab_filter/">Continued in this post&lt;/a>&lt;/p>
&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Collaborative filtering is an important problem in recommender systems. These recommender systems form the basis of some of the largest products today: search (Google), marketplace (Amazon), and content (Netflix, YouTube) products all rely on some form of recommender system.&lt;/p>
&lt;h1 id="collaborative-filtering-types">Collaborative filtering types&lt;/h1>
&lt;p>Collaborative filtering comes in 2 main types: memory-based and model-based. Memory-based models employ user and item data, described in detail in the next section, to form recommendations. Model-based techniques, outside the scope of this post, encompass all other deep (neural network) and shallow models used to form recommendations.&lt;/p></description></item><item><title>Voting continued</title><link>/posts/voting_cont/</link><pubDate>Sat, 04 Apr 2020 00:00:00 +0000</pubDate><guid>/posts/voting_cont/</guid><description>&lt;p>&lt;a href="/posts/voting/">A continuation of this post&lt;/a>&lt;/p>
&lt;p>Because I wanted to combine the themes of people and programming, I wrote a short Python script to calculate and visualize outcomes of &lt;a href="/posts/voting/">the different voting schemes described in my last post&lt;/a>.&lt;/p>
&lt;p>&lt;a href="https://github.com/jgjin/voting">This script is available in this public Github repo&lt;/a>. It provides a detailed example of how different voting schemes can lead to different outcomes &lt;a href="https://github.com/jgjin/voting/tree/master/example">in the &lt;code>example&lt;/code> directory&lt;/a>.&lt;/p></description></item><item><title>Generators in Python: "good lazy"</title><link>/posts/generators/</link><pubDate>Sat, 01 Feb 2020 00:00:00 +0000</pubDate><guid>/posts/generators/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Generators are functions that behave like iterators. They allow us to evaluate values only as we need them (&amp;ldquo;lazily evaluate&amp;rdquo;, or &amp;ldquo;lazy evaluation&amp;rdquo;).&lt;/p>
&lt;h1 id="a-basic-generator">A basic generator&lt;/h1>
&lt;p>Your basic generator has the following structure:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Python" data-lang="Python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">generator_name&lt;/span>(args&lt;span style="color:#f92672">...&lt;/span>):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">while&lt;/span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>we can still generate values&lt;span style="color:#f92672">&amp;gt;&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">yield&lt;/span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>next value&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">...&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s look at a basic generator:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-Python" data-lang="Python">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">def&lt;/span> &lt;span style="color:#a6e22e">jumping_integers&lt;/span>(start, end, jump&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>):
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&amp;#34;Starting at given value, return jumped integers until end, exclusive.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> integer &lt;span style="color:#f92672">=&lt;/span> start
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">while&lt;/span> integer &lt;span style="color:#f92672">&amp;lt;&lt;/span> end:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">yield&lt;/span> integer
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> integer &lt;span style="color:#f92672">+=&lt;/span> jump
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Attentive programmers will notice this looks a lot like &lt;code>range&lt;/code>, particularly &lt;code>xrange&lt;/code> in Python 2 and &lt;code>range&lt;/code> in Python 3. Indeed, if we test the generator we just wrote:&lt;/p></description></item><item><title>Elm, or my first time with pure functional</title><link>/posts/elm/</link><pubDate>Sat, 28 Dec 2019 00:00:00 +0000</pubDate><guid>/posts/elm/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>&lt;a href="https://en.wikipedia.org/wiki/Pomodoro_Technique/">The Pomodoro Technique&lt;/a> employs roughly 30-minute cycles, 25 minutes working on a task then 5 minutes taking a break, to get work done. Unfortunately, some tasks, particularly programming, involve &lt;a href="https://en.wikipedia.org/wiki/Flow_(psychology/)">a state of flow&lt;/a> which would get interrupted by 30-minute cycles. The simpler Flow Time Technique allows for flow by relaxing the 25-/5-minute constraint in favor of deciding on your own when to take breaks.&lt;/p>
&lt;p>I wanted to create a tool to help me practice the Flow Time Technique. I also wanted to learn a new programming language. So I wrote an Elm application to help me practice the Flow Time Technique. In case you&amp;rsquo;re interested, the Flow Time Technique tool I wrote is available at &lt;a href="https://flow-time.xyz/">flow-time.xyz&lt;/a>, with code on &lt;a href="https://github.com/jgjin/flow-time-elm/">Github&lt;/a>.&lt;/p></description></item></channel></rss>