<?xml version='1.0' encoding='UTF-8'?>
<rss version="2.0">
  <channel>
    <title>Mind Matters HQ</title>
    <link>https://www.mmhq.me</link>
    <description>Home of my thoughts and observations</description>
    <pubDate>Tue, 31 Mar 2026 06:10:12 -0700</pubDate>
    <image>
      <title>Mind Matters HQ</title>
      <link>https://www.mmhq.me</link>
      <url>https://www.mmhq.me/static/icons/favicon-192x192.png</url>
    </image>
    <item>
      <title>E don happen</title>
      <link>https://www.mmhq.me/posts/e-don-happen</link>
      <description><![CDATA[<p><picture><img alt="A person looking at their phone with a laptop, a tab, air pods, and a water bottle on the table" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/work.webp" srcset="/static/data/images/360w/work.webp 360w, /static/data/images/640w/work.webp 640w, /static/data/images/1080w/work.webp 1080w, /static/data/images/1280w/work.webp 1280w" title="Work"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Job-3-25/">
    <p>For the thing which I greatly feared is come upon me, and that which I was afraid of is come unto me.</p>
    <cite>Job 3:25, The Bible</cite>
</blockquote>

<p>I knew it has brewing for a while, but I never thought it would actually come. This whole time I thought I would be able to make an escape from it before it happened, but boy was I wrong and completely blindsided.</p>
<p>Like I said, e don happen<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup> 😔.</p>
<p>Earlier this month, I was laid off from my job. I went through various stages through this period — sadness, fear, uncertainty. But one feeling I haven't felt — regret. I wouldn't change a thing if I could.</p>
<p>I enjoyed the job I had. I worked as a software engineer and I love to code. I liked the coworkers I worked with. I had a good time. And before you say "AI took my job", it wasn't that. I would say it was a subjective decision from the company; <a href="https://www.youtube.com/watch?v=fv8zpYI9n6s" title="How to survive Tech Layoffs in 2026">it's not always your fault.</a></p>
<p>I'm not the type of person whose life revolves around his job. I believe life is way bigger than that and to think of life in that way is to belittle yourself. I still get to code on my own and as long as that can't be taken from me, I'm happy.</p>
<p>This whole period of unemployment has taught me one thing: family and friends would forever be more important that a paycheck. And that's what a job is at the end, a paycheck. It's not fulfillment. It's not a form of "family". It's a paycheck. And that's okay.</p>
<p>For me, I will be okay. With all the emotions I went through, one that came right from the same day it happened, was relief. I leave everything in God's hands. I know there's a greater future ahead of me. Right now, I'm using the time off to connect with family and friends and just rest. After all, that is what Jesus came to do, <a href="https://www.kingjamesbibleonline.org/Matthew-11-28/" title="Matthew 11:28">give me rest</a>.</p>
<p>For all who are going through the same thing in this recession, I want to encourage you. The storm would soon end and the sun will shine again. Don't lose hope, no matter what you are experiencing right now. The promised land comes after the wilderness.</p>
<p>One thing that I can remember from my late father is, <a href="https://www.kingjamesbibleonline.org/John-12-24/" title="John 12:24">"For a seed to grow, it must first die"</a>. And this is my period of "death" — <em>death</em> to my pride in my occupation, and <em>life</em> to a new world of opportunities.</p>
<p>Keep your head above the water; tomorrow is a new day.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p><em>E don happen</em> in Nigerian Pidgin English means "It has happened". <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Mon, 30 Mar 2026 23:57:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/e-don-happen</guid>
    </item>
    <item>
      <title>OOP is a mindset</title>
      <link>https://www.mmhq.me/posts/oop-is-a-mindset</link>
      <description><![CDATA[<p><picture><img alt="Mac computer glowing in a dark room" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/glowing-mac-computer.webp" srcset="/static/data/images/360w/glowing-mac-computer.webp 360w, /static/data/images/640w/glowing-mac-computer.webp 640w, /static/data/images/1080w/glowing-mac-computer.webp 1080w, /static/data/images/1280w/glowing-mac-computer.webp 1280w" title="OOP"></picture></p>
<blockquote class="quote" cite="https://www.quora.com/What-does-Alan-Kay-mean-when-he-said-OOP-to-me-means-only-messaging-local-retention-and-protection-and-hiding-of-state-process-and-extreme-late-binding-of-all-things-It-can-be-done-in-Smalltalk-and-in-LISP">
    <p>OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.</p>
    <cite>Alan Kay, the father of OOP</cite>
</blockquote>

<details>
    <summary>Poem: <em>Objects everywhere</em></summary>
<pre class="poem">
My <em>adapter</em> needs a <em>service</em>
To adapt to any purpose,
And that <em>service</em> kinda <em>functions</em>
As a <em>helper</em> at the junction
Between <em>builders</em>; the conception
Is to <em>model</em> <em>raised</em> <em>exceptions</em>,
Causing tension, also leaving me in dread —
My mind's crowded with code <em>objects</em> in my head. 😵‍💫 😖
</pre>
</details>

<p>Object-oriented programming (<a href="https://en.wikipedia.org/wiki/Object_oriented_programming" title="Object-oriented programming - Wikipedia">OOP</a>) is talked about so much in the software development space. It's a tried-and-true method of creating applications, and many developers swear by it. But what is OOP?</p>
<p>According to <a href="https://en.wikipedia.org/wiki/Alan_Kay" title="Alan Kay - Wikipedia">Alan Kay</a>, the inventor of OOP, the whole idea was based on biology. Kay (who <a href="https://en.wikipedia.org/wiki/Alan_Kay#Early_life_and_work" title="Early life and work - Alan Kay - Wikipedia">majored in biology in college</a>) likened objects to <strong>biological cells</strong>; <strong>each cell has its own "data" (DNA) and "logic", and they communicate via chemical "messages"</strong>. No single cell is in charge of the whole body; the complexity changes from their interactions.</p>
<p>I agree completely with Alan Kay in theory; I only disagree in application. Alan Kay (and a lot of developers) believe that this can be accomplished with a programming language (like his language, <a href="https://en.wikipedia.org/wiki/Smalltalk" title="Smalltalk - Wikipedia">Smalltalk</a>). I believe that it's all a mindset and programming languages are only tools we can use to implement OOP.</p>
<p>I'm not saying the programming language does not matter; I'm just saying that the language is not responsible for making your code object-oriented — the developer is.</p>
<p>In other words, there is <a href="https://www.cs.unc.edu/techreports/86-020.pdf" title="No Silver Bullet: Essence and Accidents of Software Engineering">no silver bullet</a> in software<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>, but there's misplaced effort.</p>
<h2 id="misplaced-effort">Misplaced effort</h2>
<p>The abuse of OOP reminds me of the abuse of <a href="https://en.wikipedia.org/wiki/Declarative_programming" title="Declarative programming - Wikipedia">declarative programming</a> languages by developers who are used to <a href="https://en.wikipedia.org/wiki/Imperative_programming" title="Imperative programming - Wikipedia">imperative programming</a> languages.</p>
<p>I used to work as a software engineer in in-flight entertainment, and our language of choice for the UI was QML. <a href="https://doc.qt.io/qt-6/qmlreference.html" title="The QML Reference - qt.io">QML</a> is a <a href="https://en.wikipedia.org/wiki/Declarative_programming" title="Declarative programming - Wikipedia">declarative language</a>, which means you have to describe what you want to achieve as opposed to listing the step-by-step instructions on how to achieve it.</p>
<p>However, what I noticed with amateur QML developers<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup> is that they would use the language <a href="https://en.wikipedia.org/wiki/Imperative_programming" title="Imperative programming - Wikipedia">imperatively</a> as opposed to <a href="https://en.wikipedia.org/wiki/Declarative_programming" title="Declarative programming - Wikipedia">declaratively</a>.</p>
<p>For example, let's say we wanted to animate a side panel in and out of the UI using QML. We could write it declaratively like this:</p>
<div class="codehilite"><pre><span></span><code><span class="kr">import</span> <span class="nx">QtQuick</span>

<span class="nx">Item</span> <span class="p">{</span>
    <span class="k">width:</span> <span class="mi">400</span>
    <span class="k">height:</span> <span class="mi">400</span>

    <span class="nx">Rectangle</span> <span class="p">{</span>
        <span class="kd">id: sidePanel</span>
        <span class="k">width:</span> <span class="mi">200</span>
        <span class="k">height:</span> <span class="nx">parent</span><span class="p">.</span><span class="nx">height</span>
        <span class="k">color:</span> <span class="s2">"#2c3e50"</span>
        <span class="k">state:</span> <span class="s2">"hidden"</span> <span class="c1">// DECLARATIVE: Start by being "hidden"</span>

        <span class="k">states:</span> <span class="p">[</span>
            <span class="nx">State</span> <span class="p">{</span>
                <span class="k">name:</span> <span class="s2">"visible"</span>

                <span class="nx">PropertyChanges</span> <span class="p">{</span>
                    <span class="k">target:</span> <span class="nx">sidePanel</span>
                    <span class="k">x:</span> <span class="mi">0</span>
                <span class="p">}</span>
            <span class="p">},</span>
            <span class="nx">State</span> <span class="p">{</span>
                <span class="k">name:</span> <span class="s2">"hidden"</span>

                <span class="nx">PropertyChanges</span> <span class="p">{</span>
                    <span class="k">target:</span> <span class="nx">sidePanel</span>
                    <span class="k">x:</span> <span class="o">-</span><span class="nx">sidePanel</span><span class="p">.</span><span class="nx">width</span>
                <span class="p">}</span>
            <span class="p">}</span>
        <span class="p">]</span>

        <span class="c1">// DECLARATIVE: Transition from "hidden" to "visible" (and vice versa) is handled automagically</span>
        <span class="k">transitions:</span> <span class="nx">Transition</span> <span class="p">{</span>
            <span class="k">from:</span> <span class="s2">"hidden"</span>
            <span class="k">to:</span> <span class="s2">"visible"</span>
            <span class="k">reversible:</span> <span class="kc">true</span>

            <span class="nx">NumberAnimation</span> <span class="p">{</span>
                <span class="k">property:</span> <span class="s2">"x"</span>
                <span class="k">duration:</span> <span class="mi">500</span>
                <span class="k">easing.type:</span> <span class="nx">Easing</span><span class="p">.</span><span class="nx">OutQuint</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="nx">MouseArea</span> <span class="p">{</span>
        <span class="k">anchors.fill:</span> <span class="nx">parent</span>
        <span class="k">onClicked:</span> <span class="nx">sidePanel</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="p">(</span><span class="nx">sidePanel</span><span class="p">.</span><span class="nx">state</span> <span class="o">===</span> <span class="s2">"visible"</span> <span class="o">?</span> <span class="s2">"hidden"</span> <span class="o">:</span> <span class="s2">"visible"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>Notice since the code is set up declaratively, animating the side panel is a matter of switching its state from <code>"hidden"</code> to <code>"visible"</code>. The intent is very obvious.</p>
<p>However, we could go against the QML "declarative" philosophy and write it imperatively, like this:</p>
<div class="codehilite"><pre><span></span><code><span class="kr">import</span> <span class="nx">QtQuick</span>

<span class="nx">Rectangle</span> <span class="p">{</span>
    <span class="kd">id: badPanel</span>
    <span class="k">width:</span> <span class="mi">200</span>
    <span class="k">height:</span> <span class="mi">400</span>
    <span class="k">x:</span> <span class="o">-</span><span class="mi">200</span>
    <span class="k">color:</span> <span class="s2">"red"</span>

    <span class="nx">PropertyAnimation</span> <span class="p">{</span>
        <span class="kd">id: slideIn</span>
        <span class="k">target:</span> <span class="nx">badPanel</span>
        <span class="k">property:</span> <span class="s2">"x"</span>
        <span class="k">to:</span> <span class="mi">0</span>
        <span class="k">duration:</span> <span class="mi">500</span>
    <span class="p">}</span>

    <span class="nx">PropertyAnimation</span> <span class="p">{</span>
        <span class="kd">id: slideOut</span>
        <span class="k">target:</span> <span class="nx">badPanel</span>
        <span class="k">property:</span> <span class="s2">"x"</span>
        <span class="k">to:</span> <span class="o">-</span><span class="mi">200</span>
        <span class="k">duration:</span> <span class="mi">500</span>
    <span class="p">}</span>

    <span class="nx">MouseArea</span> <span class="p">{</span>
        <span class="k">anchors.fill:</span> <span class="nx">parent</span>
        <span class="k">onClicked:</span> <span class="p">{</span>
            <span class="c1">// IMPERATIVE: Manually checking values and firing commands</span>
            <span class="k">if</span> <span class="p">(</span><span class="nx">badPanel</span><span class="p">.</span><span class="nx">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                <span class="nx">slideIn</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
                <span class="c1">// Now you have to write a second animation for sliding out!</span>
                <span class="nx">slideOut</span><span class="p">.</span><span class="nx">start</span><span class="p">();</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>Here, the developer has to explicitly check values and start the animations.</p>
<p>Both snippets of code work, but only one <em>embodies</em> the principles of declarative programming.</p>
<p>As I've illustrated, QML, a declarative language, can <em>still</em> be written in an imperative way. The language does not prevent it completely — it only makes it awkward and more difficult to do incorrectly (i.e. the imperative way)<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>.</p>
<h2 id="oop-is-great">OOP is great...</h2>
<p>I use OOP (a lot 🙈) because it works:</p>
<ul>
<li>
<strong>It keeps my code maintainable.</strong> It's nice to reason each class/module etc. as an "object" that is independent of all other objects. Then I get to route messages between them like a <a href="https://en.wikipedia.org/wiki/Patch_panel" title="Patch panel - Wikipedia">patchbay</a>.</li>
<li>In my experience, <strong>OOP works better for software that is developed for people that don't know how to code (i.e. the masses).</strong> This is because we all intuitively think in objects, and mapping human problems to objects (i.e. modelling the domain) becomes easier. In that way, OOP <em>democratized</em> computer programs.</li>
<li>
<strong>OOP helps me to reason about architecture better</strong>, for both my own code and others.</li>
<li>
<strong>There is no other way to make large <a href="https://en.wikipedia.org/wiki/Graphical_user_interface" title="Graphical user interface - Wikipedia">GUI</a> applications.</strong> Well, at least for now.<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup>
</li>
</ul>
<h2 id="but-oop-is-not-always-the-answer">...but OOP is not always the answer</h2>
<p>Just because I use OOP, it doesn't mean I shun other <a href="https://en.wikipedia.org/wiki/Programming_paradigm" title="Programming paradigm - Wikipedia">paradigms</a>. There are times that I write code <a href="https://en.wikipedia.org/wiki/Procedural_programming" title="Procedural programming - Wikipedia">procedurally</a> and there are times that I write code using <a href="https://en.wikipedia.org/wiki/Functional_programming" title="Functional programming - Wikipedia">functional programming</a> principles. <strong>Use the right philosophy for the right task.</strong> It's perfectly legal to mix and match to your taste.</p>
<p>Experienced game developers seem to hate OOP, and I get it. In game programming, performance and speed is very important, so I can understand people taking a more data-oriented approach (also known as <em>Data-Oriented Design</em> or <a href="https://en.wikipedia.org/wiki/Data-oriented_design" title="Data-oriented design - Wikipedia"><em>DOD</em></a>). This is sometimes more efficient, because the programmer writes code with knowledge of the low-level architecture and workings of the computer, and therefore could optimize better. However, a lot of software development doesn't require this. In those cases, OOP <em>may</em> suffice.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<blockquote>
<p>OOP is not a programming language; it's a mindset.</p>
</blockquote>
<p>We should use programming languages to teach the principles of OOP (and other paradigms) as opposed to relying on them to govern us. The more we understand the philosophy (by reading about it and writing code), the more effectively we can apply it in our favor and most importantly, correctly.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>In the software world, we have this weird idea that we can shield the developer from all issues he/she can encounter. An example of this is frontend developers' obsession with static types. But no matter what we do, we can't shield other developers from all problems; the developer must assume the responsibility bestowed upon him/her. Don't leave it to a machine. This also leads to developers relying on frameworks to make their code "clean". Frameworks don't have that power, developers do. Okay, rant over, for now 😆! <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>I was one at one point 🙈. I was experienced in Java and C++, but those languages are <a href="https://en.wikipedia.org/wiki/Imperative_programming" title="Imperative programming - Wikipedia">imperative</a> so the philosophy is different. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>It may be worth saying that being bad at declarative programming doesn't mean you're a bad developer; it just mean you don't understand the <a href="https://en.wikipedia.org/wiki/Programming_paradigm" title="Programming paradigm - Wikipedia">paradigm</a>. <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>Oh there is? Go ahead, I'll wait 🤨... <a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sun, 08 Feb 2026 21:20:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/oop-is-a-mindset</guid>
    </item>
    <item>
      <title>As seen on the web</title>
      <link>https://www.mmhq.me/posts/as-seen-on-the-web</link>
      <description><![CDATA[<p><picture><img alt="Spider web displayed in front of blurred background" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/spider-web.webp" srcset="/static/data/images/360w/spider-web.webp 360w, /static/data/images/640w/spider-web.webp 640w, /static/data/images/1080w/spider-web.webp 1080w, /static/data/images/1280w/spider-web.webp 1280w" title="The web"></picture></p>
<p>Here are a lists of blog posts I've enjoyed reading recently on the web 🕸️:</p>
<ul>
<li>
<a href="https://zerosleeps.com/blog/2026/1/28/doing-the-thing-is-doing-the-thing/" title="Doing the thing is doing the thing - zerosleeps.com">Doing the thing is doing the thing</a> by zerosleeps</li>
<li>
<a href="https://nelson.cloud/what-i-actually-want-to-say-in-tech-interviews/?ref=rss" title="What I actually want to say in tech interviews - nelson.cloud">What I actually want to say in tech interviews</a> by Nelson</li>
<li>
<a href="https://www.qt.io/blog/qtwidgets-to-qtquick-application-journey-part1" title="Qt Widgets to Qt Quick, An Application Journey Part 1 - qt.io">Qt Widgets to Qt Quick, An Application Journey Part 1</a> by the Qt company</li>
<li>
<a href="https://drewdevault.com/2026/01/29/2026-01-29-Cult-of-TDD-and-LLMs.html" title="The cults of TDD and GenAI - drewdevault.com">The cults of TDD and GenAI</a> by Drew DeVault</li>
<li>
<a href="https://dev.to/m-asif-ansari/emmet-for-html-30e2" title="Emmet for HTML - dev.to">Emmet for HTML</a> by Asif Ansari</li>
<li>
<a href="https://dev.to/uponthesky/opiniontodays-frontend-is-easy-to-be-messed-up-and-we-need-to-organize-it-17hl" title="Frontend is easy to be messed up and we need to organize it - dev.to">Frontend is easy to be messed up and we need to organize it</a> by Upon The Sky</li>
<li>
<a href="https://cassidoo.co/post/finished-apps/" title="Finished apps - cassidoo.co">I like when apps are "finished"</a> by Cassidy Williams</li>
<li>
<a href="https://www.htmhell.dev/adventcalendar/2025/13/" title="Hell is other people's markup - htmhell.dev">Hell is other people's markup</a> by HTMHell</li>
<li>
<a href="https://www.markpitblado.me/blog/dont-forget-how-far-youve-come/" title="Don't forget how far you've come - markpitblado.me">Don't forget how far you've come</a> by Mark Pitblado</li>
<li>
<a href="https://afranca.com.br/why-i-write-in-public" title="Why I write in public - afranca.com.br">Why I write in public</a> by Andre Franca</li>
<li>
<a href="https://world.hey.com/jason/quality-the-concept2-rowerg-7f7bb027" title="Quality: The Concept2 RowErg">Quality: The Concept2 RowErg</a> by Jason Fried from HEY</li>
<li>
<a href="https://principles.adactio.com/" title="Design Principles - Adactio">Design Principles</a> by Adactio</li>
</ul>
<p>I asked ChatGPT:</p>
<p>Humans code better than machines, yes or no? <a href="https://chatgpt.com/share/6930de37-9688-800c-81b5-3bb7d913f60d" title="Humans code better than machines, yes or no?">Its response</a></p>]]></description>
      <pubDate>Tue, 03 Feb 2026 00:49:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/as-seen-on-the-web</guid>
    </item>
    <item>
      <title>Record Rack in a nutshell</title>
      <link>https://www.mmhq.me/posts/record-rack-in-a-nutshell</link>
      <description><![CDATA[<p><picture><img alt="Record Rack official logo" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-banner.webp" srcset="/static/data/images/360w/rr-banner.webp 360w, /static/data/images/640w/rr-banner.webp 640w, /static/data/images/1080w/rr-banner.webp 1080w, /static/data/images/1280w/rr-banner.webp 1280w" title="Record Rack"></picture></p>
<blockquote class="scripture" cite="https://www.forbes.com/sites/allbusiness/2014/02/10/50-inspirational-quotes-for-startups-and-entrepreneurs/">
    <p>Chase the vision, not the money; the money will end up following you.</p>
    <cite>Tony Hsieh, Zappos CEO</cite>
</blockquote>

<details>
    <summary>Poem: <em>Rack to the rescue</em></summary>
<pre class="poem">
Inventory tracking by the books is such a pain;
For every sale I make, I have to calculate the gain.
But apps like Record Rack have saved the day, it's such a hack;
It solved my tracking issues and have shown me where I lack.
Even on vacation, I can keep up with my business,
Track goods with precision and know my profit any instant!
</pre>
</details>

<p><strong>Record Rack is the first "big" project I've ever worked on.</strong> It would be the first application tailored towards solving <em>actual</em> (paying) customer needs. Before then, I just coded for a hobby and to solve my own problems. The Record Rack project would change all of that.</p>
<p>In this post, I'd like to talk about Record Rack: its purpose, its history, and its evolution.</p>
<h2 id="the-problem">The problem</h2>
<p><strong>Meet Jane Doe.</strong></p>
<p><strong>Jane owns a retail shop in Nigeria.</strong> She sells rice, beans, noodles, can tomatoes, pasta, flour, oil, garri, and a lot of other raw ingredients you would find in your kitchen.</p>
<p>From Monday to Saturday, <strong>Jane would drive to her shop to monitor all operations that took place</strong>. She paid a staff of 5 to sell goods, attend to customers and ensure that the items she had in stock were well accounted for.</p>
<p>As the years went by, the shop only got bigger and more profitable. She tried to open multiple shops in various locations but had to close them down because of theft from her very own staff in those shops. <strong>She had seemingly reached an impasse.</strong></p>
<p>And though her business seemed to be at its peak since she's started, it was <strong>plagued with unspoken problems</strong>:</p>
<ul>
<li>All transactions were written on paper, making transactions error-prone and slow. Customers also had to wait long times, leading to some leaving for other nearby shops.</li>
<li>Receipts were written by hand by her staff, making each transaction take longer. The copy of receipts were done by literal <a href="https://en.wikipedia.org/wiki/Carbon_copy" title="Carbon copy - Wikipedia"><em>carbon copy</em></a>.</li>
<li>At the end of the day, all money made and stock sold (or purchased by the business) had to be <em>balanced</em>. Balancing the accounts involved counting the stock to make sure the quantity is correct and ensuring the money made equals the money documented. Since this was done at the end of the day, workers had to leave late on days where miscalculations happened or a lot of money was made<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>.</li>
<li>Jane was unaware when stock items were low or sold out, making it harder to satisfy customers reliably.</li>
<li>Jane had no way to measure what stock items sold well or which ones she made the most profit from without measuring it herself from the books.</li>
<li>Jane had to rely on staff to report the right numbers.</li>
<li>If any of the books used for taking records was lost, there was no backup.</li>
<li>Debtors and creditors were loosely tracked in a book. Looking up old records was hard.</li>
<li>Recurring customers were not tracked. If they were, the business can decide to offer discounts.</li>
</ul>
<h2 id="record-rack-to-the-rescue">Record Rack to the rescue!</h2>
<p>Out of all the pain mentioned above, Record Rack wore its cape and offered to save the day 🦸!</p>
<p>From hearing all these issues faced by Jane, my business partner and I rose to the challenge. We were laser-focused on making a software that could solve Jane's problems and the many local retailers that face similar issues.</p>
<p>This ultimately led to the creation of Record Rack.</p>
<p><strong>Record Rack is an inventory management software made with the pain of the Nigerian retail entrepreneur in mind</strong>:</p>
<ul>
<li>It tracked all the stock items sold and purchased.</li>
<li>Jane was kept up-to-date on all inventory changes and transactions through a mobile app we provided; she no longer was required to visit her shop to monitor operations.</li>
<li>Sale transactions were much faster and all receipts were printed by the software. <strong>Jane's revenue increased.</strong>
</li>
<li>It tracked other income (i.e. income that was not made from stock items).</li>
<li>It tracked all business expenses.</li>
<li>It notified the user when a product was low in stock or sold out.</li>
<li>It allowed users to edit created transactions (useful for customers who needed changes).</li>
<li>It tracked debtors and creditors, along with each payment made, the deadline for payment and how much was left to pay.</li>
<li>It supported subunits, allowing users to track goods with multiple units. For example, a carton of noodles can be sold by the sachet instead of the full carton.</li>
<li>Recurring customers could be tracked and therefore rewarded.</li>
<li>It used a simple interface. This was important in getting her staff up to speed quickly.</li>
</ul>
<p><a href="/posts/about-business#you-need-a-passion-for-pain" title="About business - Mind Matters HQ">If <em>business</em> is all about relieving pain</a> 🤕, <strong>Record Rack was definitely the Tylenol</strong> 💊.</p>
<h3 id="rr-og-gallery">Gallery</h3>
<p>The official Record Rack logo:
<picture><img alt="Record Rack official logo" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-banner.webp" srcset="/static/data/images/360w/rr-banner.webp 360w, /static/data/images/640w/rr-banner.webp 640w, /static/data/images/1080w/rr-banner.webp 1080w, /static/data/images/1280w/rr-banner.webp 1280w" title="Record Rack OG"></picture></p>
<p>Background used in the main Record Rack application:
<picture><img alt="The Record Rack application's background" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-base.webp" srcset="/static/data/images/360w/rr-og-base.webp 360w, /static/data/images/640w/rr-og-base.webp 640w, /static/data/images/1080w/rr-og-base.webp 1080w, /static/data/images/1280w/rr-og-base.webp 1280w" title="Record Rack OG"></picture></p>
<p>Notifications showing items low in stock:
<picture><img alt="The Record Rack application showing items that are low in stock" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-low-in-stock.webp" srcset="/static/data/images/360w/rr-og-low-in-stock.webp 360w, /static/data/images/640w/rr-og-low-in-stock.webp 640w, /static/data/images/1080w/rr-og-low-in-stock.webp 1080w, /static/data/images/1280w/rr-og-low-in-stock.webp 1280w" title="Record Rack OG"></picture></p>
<p>Newer version of the notifications showing items low in stock in red:
<picture><img alt="The Record Rack application showing items low in stock in red" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-low-qty-notifications.webp" srcset="/static/data/images/360w/rr-og-low-qty-notifications.webp 360w, /static/data/images/640w/rr-og-low-qty-notifications.webp 640w, /static/data/images/1080w/rr-og-low-qty-notifications.webp 1080w, /static/data/images/1280w/rr-og-low-qty-notifications.webp 1280w" title="Record Rack OG"></picture></p>
<p>"Manage debtors/creditors" window:
<picture><img alt='The "Manage debtors/creditors" window in the Record Rack application' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-manage-debtors-and-creditors.webp" srcset="/static/data/images/360w/rr-og-manage-debtors-and-creditors.webp 360w, /static/data/images/640w/rr-og-manage-debtors-and-creditors.webp 640w, /static/data/images/1080w/rr-og-manage-debtors-and-creditors.webp 1080w, /static/data/images/1280w/rr-og-manage-debtors-and-creditors.webp 1280w" title="Record Rack OG"></picture></p>
<p>"Manage users" window:
<picture><img alt='The "Manage user" window in the Record Rack application' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-manage-users.webp" srcset="/static/data/images/360w/rr-og-manage-users.webp 360w, /static/data/images/640w/rr-og-manage-users.webp 640w, /static/data/images/1080w/rr-og-manage-users.webp 1080w, /static/data/images/1280w/rr-og-manage-users.webp 1280w" title="Record Rack OG"></picture></p>
<p>Multiple sale and purchase windows:
<picture><img alt="Multiple sale and purchase windows open in the Record Rack application" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-multiple-sales-and-purchase-windows.webp" srcset="/static/data/images/360w/rr-og-multiple-sales-and-purchase-windows.webp 360w, /static/data/images/640w/rr-og-multiple-sales-and-purchase-windows.webp 640w, /static/data/images/1080w/rr-og-multiple-sales-and-purchase-windows.webp 1080w, /static/data/images/1280w/rr-og-multiple-sales-and-purchase-windows.webp 1280w" title="Record Rack OG"></picture></p>
<p>Multiple sale windows:
<picture><img alt="Multiple sale windows open in the Record Rack application" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-multiple-sales-windows.webp" srcset="/static/data/images/360w/rr-og-multiple-sales-windows.webp 360w, /static/data/images/640w/rr-og-multiple-sales-windows.webp 640w, /static/data/images/1080w/rr-og-multiple-sales-windows.webp 1080w, /static/data/images/1280w/rr-og-multiple-sales-windows.webp 1280w" title="Record Rack OG"></picture></p>
<p>First summary page:
<picture><img alt="The old summary page in the Record Rack application" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-old-summary-widget.webp" srcset="/static/data/images/360w/rr-og-old-summary-widget.webp 360w, /static/data/images/640w/rr-og-old-summary-widget.webp 640w, /static/data/images/1080w/rr-og-old-summary-widget.webp 1080w, /static/data/images/1280w/rr-og-old-summary-widget.webp 1280w" title="Record Rack OG"></picture></p>
<p>Revised summary page:
<picture><img alt="The new summary page in the Record Rack application" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-new-summary-widget.webp" srcset="/static/data/images/360w/rr-og-new-summary-widget.webp 360w, /static/data/images/640w/rr-og-new-summary-widget.webp 640w, /static/data/images/1080w/rr-og-new-summary-widget.webp 1080w, /static/data/images/1280w/rr-og-new-summary-widget.webp 1280w" title="Record Rack OG"></picture></p>
<p>Old "User Privileges" window:
<picture><img alt='The old "User Privileges" window in the Record Rack application' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-user-privileges.webp" srcset="/static/data/images/360w/rr-og-user-privileges.webp 360w, /static/data/images/640w/rr-og-user-privileges.webp 640w, /static/data/images/1080w/rr-og-user-privileges.webp 1080w, /static/data/images/1280w/rr-og-user-privileges.webp 1280w" title="Record Rack OG"></picture></p>
<p>Revised "User privileges" page:
<picture><img alt='The new "User Privileges" window in the Record Rack application' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-new-user-privileges-window.webp" srcset="/static/data/images/360w/rr-og-new-user-privileges-window.webp 360w, /static/data/images/640w/rr-og-new-user-privileges-window.webp 640w, /static/data/images/1080w/rr-og-new-user-privileges-window.webp 1080w, /static/data/images/1280w/rr-og-new-user-privileges-window.webp 1280w" title="Record Rack OG"></picture></p>
<p>Add a note to a new sale entry:
<picture><img alt="Dialog in the Record Rack application that allows you to enter notes concerning a transaction" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-notes.webp" srcset="/static/data/images/360w/rr-og-notes.webp 360w, /static/data/images/640w/rr-og-notes.webp 640w, /static/data/images/1080w/rr-og-notes.webp 1080w, /static/data/images/1280w/rr-og-notes.webp 1280w" title="Record Rack OG"></picture></p>
<p>The notification widget:
<picture><img alt="The notification widget in the Record Rack application, keeping users up-to-date" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-notifications-widget.webp" srcset="/static/data/images/360w/rr-og-notifications-widget.webp 360w, /static/data/images/640w/rr-og-notifications-widget.webp 640w, /static/data/images/1080w/rr-og-notifications-widget.webp 1080w, /static/data/images/1280w/rr-og-notifications-widget.webp 1280w" title="Record Rack OG"></picture></p>
<p>Windows load independent of others:
<picture><img alt="The Record Rack application with different windows open; each can load without blocking the UI" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-open-multiple-windows-while-one-is-loading.webp" srcset="/static/data/images/360w/rr-og-open-multiple-windows-while-one-is-loading.webp 360w, /static/data/images/640w/rr-og-open-multiple-windows-while-one-is-loading.webp 640w, /static/data/images/1080w/rr-og-open-multiple-windows-while-one-is-loading.webp 1080w, /static/data/images/1280w/rr-og-open-multiple-windows-while-one-is-loading.webp 1280w" title="Record Rack OG"></picture></p>
<p>Highlighted terms for quick search:
<picture><img alt="Searched terms are highlighted in the Record Rack application" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-search-sales-entries.webp" srcset="/static/data/images/360w/rr-og-search-sales-entries.webp 360w, /static/data/images/640w/rr-og-search-sales-entries.webp 640w, /static/data/images/1080w/rr-og-search-sales-entries.webp 1080w, /static/data/images/1280w/rr-og-search-sales-entries.webp 1280w" title="Record Rack OG"></picture></p>
<p>Alternate summary page:
<picture><img alt="Alternate summary page in the Record Rack application, displaying the end-of-day report" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-summary.webp" srcset="/static/data/images/360w/rr-og-summary.webp 360w, /static/data/images/640w/rr-og-summary.webp 640w, /static/data/images/1080w/rr-og-summary.webp 1080w, /static/data/images/1280w/rr-og-summary.webp 1280w" title="Record Rack OG"></picture></p>
<p>Another alternate summary page:
<picture><img alt="Alternate summary page in the Record Rack application, displaying the end-of-day report" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-summary-widget.webp" srcset="/static/data/images/360w/rr-og-summary-widget.webp 360w, /static/data/images/640w/rr-og-summary-widget.webp 640w, /static/data/images/1080w/rr-og-summary-widget.webp 1080w, /static/data/images/1280w/rr-og-summary-widget.webp 1280w" title="Record Rack OG"></picture></p>
<p>Another alternate summary page:
<picture><img alt="Alternate summary page in the Record Rack application, displaying the end-of-day report" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-summary-wid.webp" srcset="/static/data/images/360w/rr-og-summary-wid.webp 360w, /static/data/images/640w/rr-og-summary-wid.webp 640w, /static/data/images/1080w/rr-og-summary-wid.webp 1080w, /static/data/images/1280w/rr-og-summary-wid.webp 1280w" title="Record Rack OG"></picture></p>
<p>Show detailed quantity breakdown using the subunits:
<picture><img alt="The Record Rack application displaying of quantities in their subunits" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-unit-information-feature.webp" srcset="/static/data/images/360w/rr-og-unit-information-feature.webp 360w, /static/data/images/640w/rr-og-unit-information-feature.webp 640w, /static/data/images/1080w/rr-og-unit-information-feature.webp 1080w, /static/data/images/1280w/rr-og-unit-information-feature.webp 1280w" title="Record Rack OG"></picture></p>
<p>List of sale entries for the day:
<picture><img alt="The Record Rack application showing all sale entries made for the day" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-og-view-sales-entries.webp" srcset="/static/data/images/360w/rr-og-view-sales-entries.webp 360w, /static/data/images/640w/rr-og-view-sales-entries.webp 640w, /static/data/images/1080w/rr-og-view-sales-entries.webp 1080w, /static/data/images/1280w/rr-og-view-sales-entries.webp 1280w" title="Record Rack OG"></picture></p>
<h3 id="rr-og-miscellaneous-details-about-the-project">Miscellaneous details about the project</h3>
<ul>
<li>Date started: September 2013</li>
<li>Initial release date: ~ March 2014</li>
<li>Stable release date: ~ May 2014</li>
<li>Customers: 1</li>
<li>Used between: 2014 - 2022</li>
<li>Released as a desktop app and a mobile app</li>
</ul>
<h3 id="rr-og-tech-stack-used">Tech stack used</h3>
<ul>
<li>
<a href="https://www.sqlite.org/" title="SQLite official website">SQLite</a> (later changed to <a href="https://www.mysql.com/" title="MySQL official website">MySQL</a>)</li>
<li><a href="https://doc.qt.io/qt-6/index.html" title="Qt - qt.io">Qt C++</a></li>
</ul>
<h2 id="record-rack-epsilon">Record Rack Epsilon</h2>
<p>After I left Nigeria, I worked in in-flight entertainment<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup> for a couple years and I decided to work on a new version of Record Rack. This version was created to:</p>
<ul>
<li>Address all the bugs of the previous version.<ul>
<li>There was a lot of rounding errors, since I stored floating point numbers for subunit quantities. (I know, <a href="https://www.youtube.com/shorts/aZoYRpwZuAo" title="Rookie mistake - YouTube">rookie mistake</a> 🙈).</li>
<li>There were random crashes.</li>
<li>Some days, the application wouldn't record some quantity changes.</li>
</ul>
</li>
<li>Make the look-and-feel of the application more modern.</li>
<li>Update the UI code to use QML instead of C++, since QML was better for <a href="https://en.wikipedia.org/wiki/Rapid_application_development" title="Rapid application development - Wikipedia">rapid application development</a>.</li>
<li>Write better code. The last version's code was monstrous!<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>.</li>
</ul>
<p>Unfortunately, this version was canned, but it did teach me a lot about C++/QML development and <a href="https://doc.qt.io/qt-6/qtquick-bestpractices.html" title="Best Practices for QML and Qt Quick">separating UI and logic</a>.</p>
<h3 id="rr-epsilon-gallery">Gallery</h3>
<p>Testing <a href="https://www.chartjs.org/" title="Chart JS official website">Chart.js</a> (excuse my French in the image 🙈):</p>
<p><picture><img alt="Record Rack Epsilon application with a few charts displayed" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-chart-js-test.webp" srcset="/static/data/images/360w/rr-eps-chart-js-test.webp 360w, /static/data/images/640w/rr-eps-chart-js-test.webp 640w, /static/data/images/1080w/rr-eps-chart-js-test.webp 1080w, /static/data/images/1280w/rr-eps-chart-js-test.webp 1280w" title=""></picture></p>
<p>Same screen with a more defined sidebar (excuse my French in the image 🙈):
<picture><img alt="Record Rack Epsilon application with charts and full sidebar displayed" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/modern-rr.webp" srcset="/static/data/images/360w/modern-rr.webp 360w, /static/data/images/640w/modern-rr.webp 640w, /static/data/images/1080w/modern-rr.webp 1080w, /static/data/images/1280w/modern-rr.webp 1280w" title=""></picture></p>
<p>Our company name and logo, Gecko Solutions:
<picture><img alt="Gecko Solutions official logo" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-gecko-logo-with-name.webp" srcset="/static/data/images/360w/rr-eps-gecko-logo-with-name.webp 360w, /static/data/images/640w/rr-eps-gecko-logo-with-name.webp 640w, /static/data/images/1080w/rr-eps-gecko-logo-with-name.webp 1080w, /static/data/images/1280w/rr-eps-gecko-logo-with-name.webp 1280w" title=""></picture></p>
<p>Login screen:
<picture><img alt="Login screen for Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-login.webp" srcset="/static/data/images/360w/rr-eps-login.webp 360w, /static/data/images/640w/rr-eps-login.webp 640w, /static/data/images/1080w/rr-eps-login.webp 1080w, /static/data/images/1280w/rr-eps-login.webp 1280w" title=""></picture></p>
<p>Login screen with access granted dialog:
<picture><img alt="Login screen for Record Rack Epsilon with access granted dialog" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-login-successful.webp" srcset="/static/data/images/360w/rr-eps-login-successful.webp 360w, /static/data/images/640w/rr-eps-login-successful.webp 640w, /static/data/images/1080w/rr-eps-login-successful.webp 1080w, /static/data/images/1280w/rr-eps-login-successful.webp 1280w" title=""></picture></p>
<p>Login screen with access denied dialog:
<picture><img alt="Login screen for Record Rack Epsilon with access denied dialog" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-login-failed.webp" srcset="/static/data/images/360w/rr-eps-login-failed.webp 360w, /static/data/images/640w/rr-eps-login-failed.webp 640w, /static/data/images/1080w/rr-eps-login-failed.webp 1080w, /static/data/images/1280w/rr-eps-login-failed.webp 1280w" title=""></picture></p>
<p>Login screen with access granted message (revised design):
<picture><img alt="Login screen for Record Rack Epsilon with access granted message instead of dialog" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-login-access-granted.webp" srcset="/static/data/images/360w/rr-eps-login-access-granted.webp 360w, /static/data/images/640w/rr-eps-login-access-granted.webp 640w, /static/data/images/1080w/rr-eps-login-access-granted.webp 1080w, /static/data/images/1280w/rr-eps-login-access-granted.webp 1280w" title=""></picture></p>
<p>Login screen with access denied message (revised design):
<picture><img alt="Login screen for Record Rack Epsilon with access denied message instead of dialog" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-login-screen.webp" srcset="/static/data/images/360w/rr-eps-login-screen.webp 360w, /static/data/images/640w/rr-eps-login-screen.webp 640w, /static/data/images/1080w/rr-eps-login-screen.webp 1080w, /static/data/images/1280w/rr-eps-login-screen.webp 1280w" title=""></picture></p>
<p>Stock page with a product list:
<picture><img alt="List of products in Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-main-stock.webp" srcset="/static/data/images/360w/rr-eps-main-stock.webp 360w, /static/data/images/640w/rr-eps-main-stock.webp 640w, /static/data/images/1080w/rr-eps-main-stock.webp 1080w, /static/data/images/1280w/rr-eps-main-stock.webp 1280w" title=""></picture></p>
<p>Dashboard page:
<picture><img alt="Dashboard page in Record Rack Epsilon displaying charts" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-main.webp" srcset="/static/data/images/360w/rr-eps-main.webp 360w, /static/data/images/640w/rr-eps-main.webp 640w, /static/data/images/1080w/rr-eps-main.webp 1080w, /static/data/images/1280w/rr-eps-main.webp 1280w" title=""></picture></p>
<p>New stock item page (though it says "New Sales Entry" 🙈):
<picture><img alt='New stock item page in Record Rack Epsilon, though "New Sales Entry" is displayed as the title' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-new-sales-entry.webp" srcset="/static/data/images/360w/rr-eps-new-sales-entry.webp 360w, /static/data/images/640w/rr-eps-new-sales-entry.webp 640w, /static/data/images/1080w/rr-eps-new-sales-entry.webp 1080w, /static/data/images/1280w/rr-eps-new-sales-entry.webp 1280w" title=""></picture></p>
<p>New sales home page:
<picture><img alt="Sales home page in Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-new-sales-home.webp" srcset="/static/data/images/360w/rr-eps-new-sales-home.webp 360w, /static/data/images/640w/rr-eps-new-sales-home.webp 640w, /static/data/images/1080w/rr-eps-new-sales-home.webp 1080w, /static/data/images/1280w/rr-eps-new-sales-home.webp 1280w" title=""></picture></p>
<p>New sales entry page:
<picture><img alt="New sales entry page in Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-new-sales.webp" srcset="/static/data/images/360w/rr-eps-new-sales.webp 360w, /static/data/images/640w/rr-eps-new-sales.webp 640w, /static/data/images/1080w/rr-eps-new-sales.webp 1080w, /static/data/images/1280w/rr-eps-new-sales.webp 1280w" title=""></picture></p>
<p>Stock page with extended sidebar:
<picture><img alt="Stock page with the fully extended sidebar in Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-new-stock-expanded.webp" srcset="/static/data/images/360w/rr-eps-new-stock-expanded.webp 360w, /static/data/images/640w/rr-eps-new-stock-expanded.webp 640w, /static/data/images/1080w/rr-eps-new-stock-expanded.webp 1080w, /static/data/images/1280w/rr-eps-new-stock-expanded.webp 1280w" title=""></picture></p>
<p>Stock page with collapsed sidebar (ignore the Spider-Man background 🙈):
<picture><img alt="Stock page with the sidebar collapsed in Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-new-stock.webp" srcset="/static/data/images/360w/rr-eps-new-stock.webp 360w, /static/data/images/640w/rr-eps-new-stock.webp 640w, /static/data/images/1080w/rr-eps-new-stock.webp 1080w, /static/data/images/1280w/rr-eps-new-stock.webp 1280w" title=""></picture></p>
<p>Old login screen vs new login screen (ignore the Spider-Man background 🙈):
<picture><img alt="Login screen of both old version and new version placed side by side" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-login-vs-new-login-2.webp" srcset="/static/data/images/360w/rr-eps-old-login-vs-new-login-2.webp 360w, /static/data/images/640w/rr-eps-old-login-vs-new-login-2.webp 640w, /static/data/images/1080w/rr-eps-old-login-vs-new-login-2.webp 1080w, /static/data/images/1280w/rr-eps-old-login-vs-new-login-2.webp 1280w" title=""></picture></p>
<p>Old access denied screen vs new access denied screen (ignore the Spider-Man background 🙈):
<picture><img alt="Login screen with access denied message of both old version and new version placed side by side" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-login-vs-new-login-access-denied.webp" srcset="/static/data/images/360w/rr-eps-old-login-vs-new-login-access-denied.webp 360w, /static/data/images/640w/rr-eps-old-login-vs-new-login-access-denied.webp 640w, /static/data/images/1080w/rr-eps-old-login-vs-new-login-access-denied.webp 1080w, /static/data/images/1280w/rr-eps-old-login-vs-new-login-access-denied.webp 1280w" title=""></picture></p>
<p>Old access granted screen vs new access granted screen (ignore the Spider-Man background 🙈):
<picture><img alt="Login screen with access granted message of both old version and new version placed side by side" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-login-vs-new-login-access-granted.webp" srcset="/static/data/images/360w/rr-eps-old-login-vs-new-login-access-granted.webp 360w, /static/data/images/640w/rr-eps-old-login-vs-new-login-access-granted.webp 640w, /static/data/images/1080w/rr-eps-old-login-vs-new-login-access-granted.webp 1080w, /static/data/images/1280w/rr-eps-old-login-vs-new-login-access-granted.webp 1280w" title=""></picture></p>
<p>Old login screen vs new login screen (ignore the Spider-Man background 🙈):
<picture><img alt="Loading login screen of both old version and new version placed side by side" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-login-vs-new-login.webp" srcset="/static/data/images/360w/rr-eps-old-login-vs-new-login.webp 360w, /static/data/images/640w/rr-eps-old-login-vs-new-login.webp 640w, /static/data/images/1080w/rr-eps-old-login-vs-new-login.webp 1080w, /static/data/images/1280w/rr-eps-old-login-vs-new-login.webp 1280w" title=""></picture></p>
<p>Old main screen vs new main screen (ignore the Spider-Man background 🙈):
<picture><img alt="Main screens of both old version and new version, with new version placed a little over old version" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-main-vs-new-main.webp" srcset="/static/data/images/360w/rr-eps-old-main-vs-new-main.webp 360w, /static/data/images/640w/rr-eps-old-main-vs-new-main.webp 640w, /static/data/images/1080w/rr-eps-old-main-vs-new-main.webp 1080w, /static/data/images/1280w/rr-eps-old-main-vs-new-main.webp 1280w" title=""></picture></p>
<p>Old "New Sales Entry" page vs new "New Sales Entry" page with prompt:
<picture><img alt='"New Sales Entry" page of both old and new version placed side by side, the new version showing a prompt' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-sales-vs-new-sales-prompt.webp" srcset="/static/data/images/360w/rr-eps-old-sales-vs-new-sales-prompt.webp 360w, /static/data/images/640w/rr-eps-old-sales-vs-new-sales-prompt.webp 640w, /static/data/images/1080w/rr-eps-old-sales-vs-new-sales-prompt.webp 1080w, /static/data/images/1280w/rr-eps-old-sales-vs-new-sales-prompt.webp 1280w" title=""></picture></p>
<p>Old "New Sales Entry" page vs new "New Sales Entry" page without prompt:
<picture><img alt='"New Sales Entry" page of both old and new version placed side by side' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-sales-vs-new-sales.webp" srcset="/static/data/images/360w/rr-eps-old-sales-vs-new-sales.webp 360w, /static/data/images/640w/rr-eps-old-sales-vs-new-sales.webp 640w, /static/data/images/1080w/rr-eps-old-sales-vs-new-sales.webp 1080w, /static/data/images/1280w/rr-eps-old-sales-vs-new-sales.webp 1280w" title=""></picture></p>
<p>Old stock page vs new stock page:
<picture><img alt='"Manage Stock" page of both old and new version placed side by side' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-stock-vs-new-stock.webp" srcset="/static/data/images/360w/rr-eps-old-stock-vs-new-stock.webp 360w, /static/data/images/640w/rr-eps-old-stock-vs-new-stock.webp 640w, /static/data/images/1080w/rr-eps-old-stock-vs-new-stock.webp 1080w, /static/data/images/1280w/rr-eps-old-stock-vs-new-stock.webp 1280w" title=""></picture></p>
<p>Old main screen vs new dashboard page:
<picture><img alt="Main screen of both old and new version placed side by side" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-old-vs-new-dashboard.webp" srcset="/static/data/images/360w/rr-eps-old-vs-new-dashboard.webp 360w, /static/data/images/640w/rr-eps-old-vs-new-dashboard.webp 640w, /static/data/images/1080w/rr-eps-old-vs-new-dashboard.webp 1080w, /static/data/images/1280w/rr-eps-old-vs-new-dashboard.webp 1280w" title=""></picture></p>
<p>Login page (again):
<picture><img alt="Login page for Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-record-rack-login.webp" srcset="/static/data/images/360w/rr-eps-record-rack-login.webp 360w, /static/data/images/640w/rr-eps-record-rack-login.webp 640w, /static/data/images/1080w/rr-eps-record-rack-login.webp 1080w, /static/data/images/1280w/rr-eps-record-rack-login.webp 1280w" title=""></picture></p>
<p>Sales home page:
<picture><img alt="Sales home page for Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-sales-home.webp" srcset="/static/data/images/360w/rr-eps-sales-home.webp 360w, /static/data/images/640w/rr-eps-sales-home.webp 640w, /static/data/images/1080w/rr-eps-sales-home.webp 1080w, /static/data/images/1280w/rr-eps-sales-home.webp 1280w" title=""></picture></p>
<p>Sign up page:
<picture><img alt="Sign up page for Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-signup.webp" srcset="/static/data/images/360w/rr-eps-signup.webp 360w, /static/data/images/640w/rr-eps-signup.webp 640w, /static/data/images/1080w/rr-eps-signup.webp 1080w, /static/data/images/1280w/rr-eps-signup.webp 1280w" title=""></picture></p>
<p>Sign up page with picture selected:
<picture><img alt="Sign up page for Record Rack Epsilon with picture selected" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-signup-picture.webp" srcset="/static/data/images/360w/rr-eps-signup-picture.webp 360w, /static/data/images/640w/rr-eps-signup-picture.webp 640w, /static/data/images/1080w/rr-eps-signup-picture.webp 1080w, /static/data/images/1280w/rr-eps-signup-picture.webp 1280w" title=""></picture></p>
<p>Stock grid view:
<picture><img alt="Stock grid view in Record Rack Epsilon" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-stock-grid-view.webp" srcset="/static/data/images/360w/rr-eps-stock-grid-view.webp 360w, /static/data/images/640w/rr-eps-stock-grid-view.webp 640w, /static/data/images/1080w/rr-eps-stock-grid-view.webp 1080w, /static/data/images/1280w/rr-eps-stock-grid-view.webp 1280w" title=""></picture></p>
<p>Old stock page:
<picture><img alt="Old stock page from the original Record Rack application" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-eps-stock.webp" srcset="/static/data/images/360w/rr-eps-stock.webp 360w, /static/data/images/640w/rr-eps-stock.webp 640w, /static/data/images/1080w/rr-eps-stock.webp 1080w, /static/data/images/1280w/rr-eps-stock.webp 1280w" title=""></picture></p>
<h3 id="rr-epsilon-miscellaneous-details-about-the-project">Miscellaneous details about the project</h3>
<ul>
<li>Date started: ~ November 2015</li>
<li>Date ended: ~ November 2018</li>
<li>Release date: Never released</li>
<li>Created as a desktop app</li>
<li>Eventually abandoned</li>
</ul>
<h3 id="rr-epsilon-tech-stack-used">Tech stack used</h3>
<ul>
<li><a href="https://www.mysql.com/" title="MySQL official website">MySQL</a></li>
<li><a href="https://doc.qt.io/qt-6/index.html" title="Qt - qt.io">Qt C++</a></li>
<li><a href="https://doc.qt.io/qt-6/qmlapplications.html" title="Qt Quick - qt.io">QML</a></li>
<li><a href="https://www.chartjs.org/" title="Chart JS official website">Chart.js</a></li>
</ul>
<h2 id="record-rack-paper-yet-another-version">Record Rack Paper: Yet another version</h2>
<p>I stopped Record Rack Epsilon because I got distracted. Plus, it lacked some solid UI patterns like the first version. The first Record Rack used the widgets library from Qt, making the look and feel more consistent. Epsilon used QML, which encouraged you to code the UI yourself from scratch at the time.</p>
<p>Building Epsilon from scratch was kinda hard. Mind you, at the time I knew nothing about <a href="/posts/the-music-of-typography" title="The music of typography - Mind Matters HQ">typography</a>, colors, spacing, nothing! My shortcomings were revealed in my final design. (Check the <a href="/posts/record-rack-in-a-nutshell#rr-epsilon-gallery" title="Record Rack Epsilon Gallery - Mind Matters HQ">Epsilon gallery</a> above.)</p>
<p>So for this version, I chose to use <a href="https://m3.material.io/" title="Material Design - material.io">Material Design</a> by Google instead. With the help of a QML library I found on GitHub (called <a href="https://github.com/lirios/fluid" title="Fluid QML by Liri OS - GitHub">Fluid</a>), I decided to start Record Rack (again) from scratch. This time, I would use more of my experience and all the best practices I've learned over the years.</p>
<p>This was definitely my best attempt, compared to previous years.</p>
<h3 id="rr-paper-gallery">Gallery</h3>
<p>Unfortunately, I don't have any pictures of this lying around. If I could get it to compile again, I'll update this section.<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup></p>
<h3 id="rr-paper-miscellaneous-details-about-the-project">Miscellaneous details about the project</h3>
<ul>
<li>Date started: ~ January 2019</li>
<li>Date ended: ~ November 2020</li>
<li>Release date: Never released</li>
<li>Created as a desktop app (to be ported to mobile)</li>
<li>Eventually abandoned</li>
</ul>
<h3 id="rr-paper-tech-stack-used">Tech stack used</h3>
<ul>
<li><a href="https://www.mysql.com/" title="MySQL official website">MySQL</a></li>
<li><a href="https://doc.qt.io/qt-6/index.html" title="Qt - qt.io">Qt C++</a></li>
<li><a href="https://doc.qt.io/qt-6/qmlapplications.html" title="Qt Quick - qt.io">QML</a></li>
<li>
<a href="https://github.com/lirios/fluid" title="Fluid QML by Liri OS - GitHub">Fluid QML</a> (for <a href="https://m3.material.io/" title="Material Design - material.io">Material Design</a> components)</li>
</ul>
<h2 id="record-rack-to-infinity-and-beyond">Record Rack: To infinity, and beyond!</h2>
<p>On October 2025, my college colleague and I decided to give it one more go. We observed that the market is still vacant in Nigeria, and since we've done it before, we believe we could do it again. However, this time, we are much more knowledgeable in our crafts (we both code) and the market needs. My colleague also has connections to some of the businesses that would be interested, so we decided to get back to the Rack!</p>
<p>Over the course of the year, I'll update you on how things are going. Right now, we are still ironing out bugs and features, but we plan to release soon. By the time we release, I would blog more about how that is going. The main focus is to make a product and get it out there as soon as possible so we can get user feedback quickly and iterate.</p>
<h3 id="rr-latest-gallery">Gallery</h3>
<p>List of products:
<picture><img alt="List of products in the latest Record Rack" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-products.webp" srcset="/static/data/images/360w/rr-latest-products.webp 360w, /static/data/images/640w/rr-latest-products.webp 640w, /static/data/images/1080w/rr-latest-products.webp 1080w, /static/data/images/1280w/rr-latest-products.webp 1280w" title=""></picture></p>
<p>"New Sale Entry" page:
<picture><img alt='"New Sale Entry" in the latest Record Rack' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-new-sale-entry.webp" srcset="/static/data/images/360w/rr-latest-new-sale-entry.webp 360w, /static/data/images/640w/rr-latest-new-sale-entry.webp 640w, /static/data/images/1080w/rr-latest-new-sale-entry.webp 1080w, /static/data/images/1280w/rr-latest-new-sale-entry.webp 1280w" title=""></picture></p>
<p>"New Sale Entry" page with cart items:
<picture><img alt='"New Sale Entry" with cart items in the latest Record Rack' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-new-sale-entry-with-cart-items.webp" srcset="/static/data/images/360w/rr-latest-new-sale-entry-with-cart-items.webp 360w, /static/data/images/640w/rr-latest-new-sale-entry-with-cart-items.webp 640w, /static/data/images/1080w/rr-latest-new-sale-entry-with-cart-items.webp 1080w, /static/data/images/1280w/rr-latest-new-sale-entry-with-cart-items.webp 1280w" title=""></picture></p>
<p>"Stock" home page:
<picture><img alt='"Stock" home page in the latest Record Rack' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-stock-home.webp" srcset="/static/data/images/360w/rr-latest-stock-home.webp 360w, /static/data/images/640w/rr-latest-stock-home.webp 640w, /static/data/images/1080w/rr-latest-stock-home.webp 1080w, /static/data/images/1280w/rr-latest-stock-home.webp 1280w" title=""></picture></p>
<p>List of income entries:
<picture><img alt="List of income entries in the latest Record Rack" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-income-entries.webp" srcset="/static/data/images/360w/rr-latest-income-entries.webp 360w, /static/data/images/640w/rr-latest-income-entries.webp 640w, /static/data/images/1080w/rr-latest-income-entries.webp 1080w, /static/data/images/1280w/rr-latest-income-entries.webp 1280w" title=""></picture></p>
<p>"Reports" page:
<picture><img alt='"Reports" page in the latest Record Rack' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-all-reports.webp" srcset="/static/data/images/360w/rr-latest-all-reports.webp 360w, /static/data/images/640w/rr-latest-all-reports.webp 640w, /static/data/images/1080w/rr-latest-all-reports.webp 1080w, /static/data/images/1280w/rr-latest-all-reports.webp 1280w" title=""></picture></p>
<p>"Stock Reports" page:
<picture><img alt='"Stock Reports" page in the latest Record Rack' sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/rr-latest-stock-reports.webp" srcset="/static/data/images/360w/rr-latest-stock-reports.webp 360w, /static/data/images/640w/rr-latest-stock-reports.webp 640w, /static/data/images/1080w/rr-latest-stock-reports.webp 1080w, /static/data/images/1280w/rr-latest-stock-reports.webp 1280w" title=""></picture></p>
<h3 id="rr-latest-miscellaneous-details-about-the-project">Miscellaneous details about the project</h3>
<ul>
<li>Date started: October 2025</li>
<li>Release date: To be determined</li>
<li>Created as a <a href="https://whatpwacando.today/" title="What PWA can do today official website">PWA</a> (supported by all platforms a browser can run on)</li>
</ul>
<h3 id="rr-latest-tech-stack-used">Tech stack used</h3>
<ul>
<li><a href="https://www.postgresql.org/" title="PostgreSQL official website">PostgreSQL</a></li>
<li><a href="https://uwsgi-docs.readthedocs.io/en/latest" title="uWSGI official website">uWSGI</a></li>
<li><a href="https://nginx.org" title="Nginx official website">Nginx</a></li>
<li><a href="https://vultr.com" title="Vultr official website">Vultr</a></li>
<li>
<a href="https://flask.palletsprojects.com/en/stable" title="Flask official website">Flask</a> (<a href="https://www.python.org" title="Python official website">Python</a>)</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML" title="HTML - Mozilla Developer Network">HTML</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS" title="CSS - Mozilla Developer Network">CSS</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" title="JavaScript - Mozilla Developer Network">JavaScript</a></li>
<li><a href="https://www.chartjs.org/" title="Chart JS official website">Chart.js</a></li>
</ul>
<h2 id="the-bottom-line">The bottom line</h2>
<p>In summary, <strong>Record Rack is dead; long live Record Rack!</strong> 👑</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Almost like they were punished for making more money. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Shout out to <a href="https://www.thalesgroup.com/en" title="Thales Group official website">Thales</a> 🛫! <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>I guess I should have expected it, being an amateur at the time. <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>This is why I chose the <a href="/posts/record-rack-in-a-nutshell#rr-latest-tech-stack-used" title="Tech stack used for latest Record Rack - Mind Matters HQ">current stack</a> for the latest. I hated having to recompile and with newer versions of Qt, though my functionality hadn't changed. This is part of the reason why web code "lasts forever" compared to native code. <a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sat, 31 Jan 2026 01:44:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/record-rack-in-a-nutshell</guid>
    </item>
    <item>
      <title>About business</title>
      <link>https://www.mmhq.me/posts/about-business</link>
      <description><![CDATA[<p><picture><img alt="Finger pointing at a sheet of paper on a table containing charts" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/business-stats.webp" srcset="/static/data/images/360w/business-stats.webp 360w, /static/data/images/640w/business-stats.webp 640w, /static/data/images/1080w/business-stats.webp 1080w, /static/data/images/1280w/business-stats.webp 1280w" title="Business"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Philippians-2-3_2-4/">
    <p><span>3</span>
    Let nothing be done through strife or vainglory;
    but in lowliness of mind let each esteem other better than themselves.</p>
    <p><span>4</span>
    Look not every man on his own things,
    but every man also on the things of others.</p>
    <cite>Philippians 2:3-4, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Business is empathy</em></summary>
<pre class="poem">
They run from you because you drool for cash;
They know that that's your one and only task;
They wish you understood all of their pain;
They know you have no interest in their gain.
</pre>
</details>

<p>I just recently finished reading a book called <a href="https://www.amazon.com/Company-One-Staying-Small-Business/dp/0358213258/ref=pd_rhf_dp_s_ci_mcx_mr_hp_d_d_sccl_1_1/147-2777445-3314434?pd_rd_w=lh6pC&amp;content-id=amzn1.sym.c5dee08d-b11d-4c8c-b272-714fd8f96f22:amzn1.symc.1ce8a41e-053b-4bdc-9570-9f81c17d9d85&amp;pf_rd_p=c5dee08d-b11d-4c8c-b272-714fd8f96f22&amp;pf_rd_r=EJVRKWEW48J7K1RKTAQV&amp;pd_rd_wg=dEti6&amp;pd_rd_r=f65d7084-a55f-4b38-b191-e0982e125ef2&amp;pd_rd_i=0358213258&amp;psc=1" title="Company of One: Why Staying Small is the Next Big Thing for Business by Paul Jarvis">Company of One</a> and it got me thinking about everything I've learned about business over the years.</p>
<p>Here's a list of points that come to mind.</p>
<h2 id="you-need-a-passion-for-pain">You need a passion for pain.</h2>
<p>It may sound ironic, but it's true. In business, <strong>you have to be obsessed with the problem</strong>. Through that obsession, you can find solutions for your customers and your customers will be willing to compensate you.</p>
<p>The keyword here is <em>pain</em>. I use that word very intentionally. Whatever your customer is facing has to be equivalent to body pain. And just like we are when we have body pain, we are desperate to alleviate it, even if it costs us a fortune<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>.</p>
<h2 id="you-need-to-satisfy-at-least-one-customer">You need to satisfy at least <em>one</em> customer.</h2>
<p><strong>One customer.</strong> That is all you need at first. If you can make one customer happy, 2 is a piece of cake, then 3, and so on.</p>
<h2 id="its-very-similar-to-the-gospel">It's very similar to <em>the gospel</em>.</h2>
<p>I know this may sound like a stretch, but the gospel has the same format:</p>
<ol>
<li>As a Christian, understand the God-man problem. God wants to fellowship with us, but sin provides a barrier. Therefore, <a href="https://www.kingjamesbibleonline.org/John-3-16/" title="The gospel">God sent his only begotten Son</a> to save humanity.</li>
<li>Go about looking for those in need of help.</li>
<li>Offer the solution to a person in need. The solution is the good news (i.e. the gospel) of Jesus Christ dying to save us. This is <em>evangelism</em>.</li>
<li>Ask the person if he/she believes. If so, he/she is instantly saved by Jesus. This is an agreement between the person and Jesus that Jesus will give him/her everlasting life.</li>
<li>Keep a relationship with the person to ensure he/she is growing in Christ.</li>
<li>The new convert repeats the cycle.</li>
</ol>
<p>Compare this to the business format:</p>
<ol>
<li>Understand the problem.</li>
<li>Understand the demographics that need help.</li>
<li>Offer a solution (i.e. product or service) to your customers.</li>
<li>Enter into a contractual agreement with your customers.</li>
<li>Keep up with the customer to make sure the solution still works.</li>
<li>If the customer is happy enough, he/she would most likely let others know about your solution.</li>
</ol>
<p>Both formats start with <em>empathy</em>. Understand the customer's pain, then develop a passion that would lead to the solution.</p>
<h2 id="its-similar-to-marriage">It's similar to marriage.</h2>
<p>Once again, there are similarities with business and marriage:</p>
<ol>
<li>Understand the problem. This involves understanding the shortcomings of your to-be spouse.</li>
<li>Understand who else might be involved (like children) that you may have to also help.</li>
<li>Offer the solution i.e. marriage.</li>
<li>Enter into a contractual agreement with your spouse i.e. marriage.</li>
<li>Ensure your spouse is well taken of.</li>
<li>If both are happy, the relationship would last until death.</li>
</ol>
<h2 id="learning-the-company-of-one-method-is-helpful-in-the-workplace">Learning the "<em>Company-of-One</em> method" is helpful in the workplace.</h2>
<p>You don't have to be an entrepreneur to apply the principles of the book <em>Company of One</em>. You can do it even at your workplace. It's more of a mindset. With that mindset, your thinking aligns more with the goals and vision of the corporation you work at.</p>
<h2>Bottom line</h2>
<p><strong>The foundation of business is simple and is not very different from patterns we already engage in.</strong> It is up to business owners to recognize the similarities and apply any principle that works with their customers.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>This is why healthcare makes so much money 💵. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Thu, 29 Jan 2026 09:09:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/about-business</guid>
    </item>
    <item>
      <title>HTML as a document model</title>
      <link>https://www.mmhq.me/posts/html-as-a-document-model</link>
      <description><![CDATA[<p><picture><img alt="A signed document with a pen sitting on top of it" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/document.webp" srcset="/static/data/images/360w/document.webp 360w, /static/data/images/640w/document.webp 640w, /static/data/images/1080w/document.webp 1080w, /static/data/images/1280w/document.webp 1280w" title="Document"></picture></p>
<blockquote class="quote" cite="https://www.azquotes.com/quote/687107">
    <p>When you understand things, there's no more magic.</p>
    <cite>Tim Burners-Lee, inventor of the world wide web</cite>
</blockquote>

<p>In my <a href="/posts/html-101-web-programming-for-absolute-beginners" title="HTML 101: Web programming for absolute beginners - Mind Matters HQ">last post</a>, I spoke about how web content is made with HTML and how to write your first lines of HTML code. I also mentioned that HTML is modeled after real-life documents.</p>
<p>In this post, I'd like to go a little deeper on HTML being a document model.</p>
<h2 id="the-purpose-of-the-web">The purpose of the web</h2>
<p><strong>The original purpose of the web was to share scientific papers, reports and documentation among researchers over the internet<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>.</strong> In order for its creator, Tim Burners-Lee, to do that, he created HTML, a language used to create digital documents on the web.</p>
<p>This decision comes with a couple downsides (for instance, it's harder to make web applications than it is to make web documents etc.), but it has a couple advantages, the main one being that anyone who understood documents could learn HTML fairly quickly, as it was just a digital representation of a document.</p>
<p>So how do HTML documents <em>map</em> to real-life documents?</p>
<h2 id="the-document-parallels">The document parallels</h2>
<p>Let's go through each of the individual parts of a document and see how that connects to HTML.</p>
<h3 id="the-document-itself">The document itself</h3>
<p>Of course, what makes a document is what is <em>in</em> the document, but a document's content has to be written on <em>something</em>. In our world today, that medium is paper.</p>
<p>In HTML, the "paper" that we write upon is the root element called <code>&lt;html&gt;</code>. Therefore, all proper HTML documents start with <code>&lt;html&gt;</code>:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<h3 id="the-document-head">The document head</h3>
<p>The document head usually has some information that may be unrelated to the document itself but gives more information about the document.</p>
<p>A perfect example of this is a letter with the address at the top. The address is not needed to understand the letter, but it is helpful in getting the document to where it needs to be, and provides more information for those who are interested.</p>
<p>This parallel exists in HTML as the <code>&lt;head&gt;</code> element. As explained in the last paragraph, the <code>&lt;head&gt;</code> element contains metadata (or "data about data"). It usually appears at the (...you guessed it...) <em>head</em> of the document i.e. the top:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<p>When the HTML page is rendered by the browser, information in the head is not shown to the site visitor at all and is not really considered to be useful to visitor. I see it as a literal head; no one can read the thoughts inside your head<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>.</p>
<p>The only data that could possibly be seen from the <code>&lt;head&gt;</code> element is the <code>&lt;title&gt;</code>. Adding a title to <code>&lt;head&gt;</code> makes the title appear in the browser's tab title area:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My Webpage<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<h3 id="the-document-body">The document body</h3>
<p>Next is your document's content. What do you want to tell the world? This is where the <code>&lt;body&gt;</code> element comes in:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My Webpage<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<p>Everything in the <code>&lt;body&gt;</code> is visible to the site visitor<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>.</p>
<p>Here is where you could divide your document into the header, the main content, and the footer:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My Webpage<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">header</span><span class="p">&gt;&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">footer</span><span class="p">&gt;&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<p>Note that this structure depends on what the document is. For example, if there is nothing to present in the <code>&lt;footer&gt;</code>, you could leave it out.</p>
<h3 id="the-document-header">The document header</h3>
<p>In HTML, <code>&lt;header&gt;</code> is different from <code>&lt;head&gt;</code>. One major distinction is that <code>&lt;header&gt;</code>s are always visible (unless you explicitly hide them) while the <code>&lt;head&gt;</code> is never visible.</p>
<p>The <code>&lt;header&gt;</code> represents what is at the top of your document <em>and</em> is also relevant to the document. An example of elements that may be created under the <code>&lt;header&gt;</code> are navigation bars (i.e. <code>&lt;nav&gt;</code>) and the top heading of the document (i.e. <code>&lt;h1&gt;</code>).</p>
<p>The <code>&lt;nav&gt;</code> element helps you to navigate the document; it contains links (or <em>anchors</em> i.e. <code>&lt;a&gt;</code>) for you to quickly access different parts of the document (or possibly link you to another document entirely). They also act as a table of contents revealing topics covered by the document.</p>
<p>The <code>&lt;h1&gt;</code> element is the heading of your document, giving a short title to the content. Unlike <code>&lt;title&gt;</code>, <code>&lt;h1&gt;</code> is shown on the page, usually at the top.</p>
<p>Updating our document<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup>:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My Webpage<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">header</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">nav</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Home<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>About<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Contact<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Welcome to my site<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">footer</span><span class="p">&gt;&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<h3 id="the-documents-main-content">The document's main content</h3>
<p>The document's main content comes right after the header. This contains the "meat and potatoes" of the site. This portion in HTML contains paragraphs (i.e. <code>&lt;p&gt;</code>), subheadings (i.e. <code>&lt;h2&gt;</code>, <code>&lt;h3&gt;</code> etc), bold text (i.e. <code>&lt;strong&gt;</code>), italicized text (i.e. <code>&lt;em&gt;</code>), highlighted text (i.e. <code>&lt;mark&gt;</code>) and another other tool used in writing to present information.</p>
<p>Adding this to our document:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My Webpage<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">header</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">nav</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Home<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>About<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Contact<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Welcome to my site<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is where I start to <span class="p">&lt;</span><span class="nt">strong</span><span class="p">&gt;</span>talk<span class="p">&lt;/</span><span class="nt">strong</span><span class="p">&gt;</span> about what <span class="p">&lt;</span><span class="nt">em</span><span class="p">&gt;</span>I<span class="p">&lt;/</span><span class="nt">em</span><span class="p">&gt;</span> want <span class="p">&lt;</span><span class="nt">mark</span><span class="p">&gt;</span>to talk about<span class="p">&lt;/</span><span class="nt">mark</span><span class="p">&gt;</span>.

            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>More things I would like to say<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is another topic.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Even more things I would like to say<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is another topic, again.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">footer</span><span class="p">&gt;&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<h3 id="the-document-footer">The document footer</h3>
<p>This is where you leave the last parts of your documents like links, copyright notices, privacy policies and other information that is not immediately relevant, but relevant nonetheless.</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>My Webpage<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">header</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">nav</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Home<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>About<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Contact<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Welcome to my site<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is where I start to <span class="p">&lt;</span><span class="nt">strong</span><span class="p">&gt;</span>talk<span class="p">&lt;/</span><span class="nt">strong</span><span class="p">&gt;</span> about what <span class="p">&lt;</span><span class="nt">em</span><span class="p">&gt;</span>I<span class="p">&lt;/</span><span class="nt">em</span><span class="p">&gt;</span> want <span class="p">&lt;</span><span class="nt">mark</span><span class="p">&gt;</span>to talk about<span class="p">&lt;/</span><span class="nt">mark</span><span class="p">&gt;</span>.

            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>More things I would like to say<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is another topic.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Even more things I would like to say<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>This is another topic, again.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">footer</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Welcome again to my site<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Don't let the door hit you on the way out.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span><span class="ni">&amp;copy;</span> My site forever<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

            <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Other Links<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Photos<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Videos<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#"</span><span class="p">&gt;</span>Marketplace<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<h2 id="bottom-line">Bottom line</h2>
<p>I hope this post gave you more of an idea of what I mean by "HTML is a document model"<sup id="fnref:5"><a class="footnote-ref" href="#fn:5">5</a></sup>. It mimics documents in so many ways. Understanding this drops the barrier to entry of web programming.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>The "internet" and the "web" are actually different. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>However, if you would really like to see it, you can view it through DevTools. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>Unless, of course, it's <em>explicitly</em> hidden. <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>Note that <code>&lt;ul&gt;</code> stands for <em>unordered list</em> and is used when presenting (...you guessed it...) unordered lists (i.e. lists with no numbering). There is also <code>&lt;ol&gt;</code> for <em>ordered lists</em>. Both lists contain <em>list items</em> (i.e. <code>&lt;li&gt;</code>). <a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
<li id="fn:5">
<p>Of course the example HTML code used in this post is oversimplified, but it drives the point home. <a class="footnote-backref" href="#fnref:5" title="Jump back to footnote 5 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sat, 13 Dec 2025 10:58:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/html-as-a-document-model</guid>
    </item>
    <item>
      <title>HTML 101: Web programming for absolute beginners</title>
      <link>https://www.mmhq.me/posts/html-101-web-programming-for-absolute-beginners</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<blockquote class="quote" cite="https://www.azquotes.com/quote/687099">
    <p>The web is more a social creation than a technical one. I designed it for a social effect — to help people work together — and not as a technical toy.</p>
    <cite>Tim Burners-Lee, creator of the world wide web</cite>
</blockquote>

<p>HTML (<em>Hypertext Markup Language</em>) is to the world wide web as English is to Americans; it is not only the language with which we communicate, but also a very part of the culture. <a href="https://developer.mozilla.org/en-US/docs/Web/HTML" title="Mozilla Docs HTML Definition">Mozilla</a> defines HTML as the most basic building block of the web. All user-facing content in the world wide web is written in HTML, from games to web applications to videoconferencing.</p>
<p>In this article, we'll be exploring how we can make web content from HTML.</p>
<h2 id="what-is-html-all-about">What is HTML all about?</h2>
<p>HTML is a language for writing web pages. The web pages written in HTML can be displayed by web browsers. The content that you are viewing on this page right now was written in HTML. That is why the browser can render it and you can view it.</p>
<blockquote>
<p>The web pages you write with HTML model how documents are written in the real world.</p>
</blockquote>
<p>We'll come back to this later.</p>
<h2 id="lets-write-code">Let's write code!</h2>
<p>Now, I know what you are thinking: "I am not a coder. I have never even read a line of code in my life." Fear not lad — the title of this article was not clickbait! Just follow my instructions.</p>
<p>Let's start with a program that displays the text "Hello, World". In the editor on the left below, type the text <code>Hello, World</code> and watch it appear on the right:</p>
<p><live-preview></live-preview></p>
<p>If you see <code>Hello, world</code> appear on the right, then congratulations, you have just written your first line of code 🎉!</p>
<p>Let's spice things up a little bit. In the editor on the left below, change the text from <code>Hello, world</code> to <code>&lt;h1&gt;Hello, world&lt;/h1&gt;</code>:</p>
<p><live-preview>
    <span slot="html">Hello, world</span>
</live-preview></p>
<p>If everything was done right, you should see <code>Hello, world</code> displayed in large font on the right. Good job 🎊🙌!</p>
<h2 id="what-just-happened">What just happened?</h2>
<p>You wrote HTML code! <code>Hello, world</code> is not <em>standard</em> HTML code, but it's understood by the browser. Why? Because HTML is a <em>markup language</em>. Markup languages are coding systems that use symbols to control structure and formatting. In other words, they are used to enhance text. If no symbols are added, the text is displayed unaltered.</p>
<p>However, in the second code drill, you wrapped <code>Hello, world</code> with <code>h1</code> tags, which are <code>&lt;h1&gt;</code>, the opening tag, and <code>&lt;/h1&gt;</code>, the closing tag. These symbols signal to the browser that the wrapped text is a heading, specifically the topmost heading. This is why the text grew in size, as you would expect of any heading in any document.</p>
<h2 id="html-as-a-document-model">HTML as a document model</h2>
<p><strong>HTML was created to model documents: it has headings, paragraphs, navigation (which mirrors "table of contents" of a document), lists, sections, headers, footers and all the stuff you'd usually see in a document.</strong> In fact, I would go as far as saying the web is just a <em>network of documents</em>. When you visit a website, you receive a document. When you send an email, you send a document. And so on and so forth.</p>
<p>This <em>document model</em> is what makes HTML simpler than most languages. If you understand how to write documents, you are already halfway familiar with writing HTML.</p>
<p>For instance, look at this document:</p>
<iframe style="width: 100%; min-height: 400px; border: 1px solid black;" src="https://mmhq.me/examples/the-impact-of-technology-on-society.html"></iframe>

<p>The equivalent in HTML:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>The Impact of Technology on Society<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">header</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>The Impact of Technology on Society<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Exploring how technological advances shape our daily lives, economy, and future.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">nav</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#intro"</span><span class="p">&gt;</span>Introduction<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#impact"</span><span class="p">&gt;</span>Impact on Society<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"#future"</span><span class="p">&gt;</span>Future Trends<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">section</span> <span class="na">id</span><span class="o">=</span><span class="s">"intro"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Introduction<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Technology has drastically transformed the way we live, work, and interact. From the rise of the internet to the proliferation of smartphones, its influence is pervasive in every facet of modern life.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">section</span> <span class="na">id</span><span class="o">=</span><span class="s">"impact"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Impact on Society<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Technological advancements have affected various sectors of society, from communication to healthcare, education, and business.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"content-section"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Communication<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>With the advent of social media and instant messaging apps, communication has become faster and more accessible, bridging gaps across the world.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"content-section"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Healthcare<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Medical technology has improved diagnostic accuracy, treatment options, and patient care. Wearable devices now track health data, providing real-time information to both doctors and patients.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"content-section"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Business<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Technology has streamlined business operations, making processes more efficient and cost-effective. E-commerce, digital marketing, and cloud computing are just a few examples of how tech influences business today.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">section</span> <span class="na">id</span><span class="o">=</span><span class="s">"future"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Future Trends<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>The future of technology holds exciting possibilities, from artificial intelligence to quantum computing. Innovations are expected to continue reshaping industries and creating new opportunities for growth and change.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">ol</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Artificial Intelligence (AI)<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Virtual Reality (VR)<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Blockchain Technology<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>Internet of Things (IoT)<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">ol</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">section</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">footer</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span><span class="ni">&amp;copy;</span> 2025 Technology Insights, All rights reserved.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">footer</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<p>As you can see, HTML <em>models</em> real-life documents.</p>
<h2 id="bottom-line">Bottom line</h2>
<p>Congratulations, you are a web coder 🕸️ — welcome to the club! Now if you were thrilled with the lesson, you may have a secret passion for writing websites. You can feed your desire at multiple sites that offer free tutorials:</p>
<ul>
<li><a href="https://www.freecodecamp.org" title="Free Code Camp official website">Free Code Camp</a></li>
<li><a href="https://www.w3schools.com/html/default.asp" title="HTML Tutorial - W3 Schools">W3 Schools</a></li>
</ul>]]></description>
      <pubDate>Sat, 06 Dec 2025 14:55:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/html-101-web-programming-for-absolute-beginners</guid>
    </item>
    <item>
      <title>Bars that linger</title>
      <link>https://www.mmhq.me/posts/bars-that-linger</link>
      <description><![CDATA[<p><picture><img alt="Headphones hanging on a microphone stand with the microphone" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/microphone.webp" srcset="/static/data/images/360w/microphone.webp 360w, /static/data/images/640w/microphone.webp 640w, /static/data/images/1080w/microphone.webp 1080w, /static/data/images/1280w/microphone.webp 1280w" title="Microphone"></picture></p>
<blockquote class="scripture" cite="https://www.youtube.com/watch?v=ALNqrHzIGY8&amp;t=822s">
    <p>And let it be known I'll beat a motherf*cker to death<br>
    You'll get a knife stuck in your head so you don't f*cking forget</p>
    <cite>Pat Stay, battle rapper</cite>
</blockquote>

<p>Today I was listening to some of my favorite songs and I started remembering some of the bars that have remained in my brain longer than I expected.</p>
<p>Ladies and gentlemen, let me give a list of the bars from some of my favorite artists that are burnt into my brain<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>. 🔥🧠</p>
<h2 id="on-blind-criticism">On blind criticism 🙈</h2>
<p>Eminem raps in his song, <a href="https://www.youtube.com/watch?v=xy2xz-x-ryM&amp;t=158s" title="To Be Hunted - YouTube"><em>If I Get Locked Up</em></a><sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>:</p>
<pre class="poem">
You critics try to criticize but couldn't visualize individuals' lives through a criminal's eyes
</pre>

<p>Other than the amazing rhythm, this is a deep, honest line. It's easy to criticize people, but do we try to see their lives through their own eyes? <a href="https://www.kingjamesbibleonline.org/Matthew-7-1_7-5/" title="Matthew 7:1-5">Before we judge</a>, we should look at both sides of the coin 🪙.</p>
<h2>On world imbalance 🌎</h2>
<p>Childish Gambino sings these lyrics in his song, <a href="https://www.youtube.com/watch?v=cTugYhdMDEY&amp;t=103s" title="To Be Hunted - YouTube"><em>To Be Hunted</em></a>:</p>
<pre class="poem">
To be happy
Really means that someone else ain't
And balance ain't a one-food take
Everything is give and take
</pre>

<p>I heard this song again today and that is what inspired this whole post. This hits hard. We forget that if there is rich, there is poor; if there is full, there is hungry; if there is happiness, there is sadness too. We can't have it all, but we should not overlook our privileges.</p>
<h2 id="on-childlike-creativity">On childlike creativity 👶</h2>
<p>In Kanye West song <a href="https://www.youtube.com/watch?v=chPDTUjnWgA&amp;t=110s" title="Power - YouTube"><em>Power</em></a>, he raps:</p>
<pre class="poem">
I just needed time alone, with my own thoughts
Got treasures in my mind, but couldn't open up my own vault
My childlike creativity, purity and honesty, is honestly
Being crowded by these grown thoughts
</pre>

<p>These bars are some of the realest lines I've ever heard from a rapper! To be honest, it's pretty much a summary of my life.</p>
<p>"Time alone" for me has always been a benefit, because that is when I'm at my most creative. And when I finally get that "vault" open, it's curtains! That's when the childlike creativity comes out, but then my "grown thoughts" join the party to bully the poor baby.</p>
<h2 id="on-dreams-and-aspirations">On dreams and aspirations 💤</h2>
<p>In his song <a href="https://www.youtube.com/watch?v=-5pIEDvec0g&amp;t=197s" title="See Me Now - YouTube"><em>See Me Now</em></a>, Kanye raps:</p>
<pre class="poem">
Here's something you could use as an analogy
My life is like a child's illusions become reality
</pre>

<p>I think of this a lot. I've reached points in my life that I never thought I'd be in and I'm grateful. Some of these things I could only dream of as a kid. I know there is still plenty of room to grow, and I definitely don't have it all, but I'm content.</p>
<h2 id="bottom-line">Bottom line</h2>
<p>Music is one thing, but adding sense to go along with it is always worthy of praise. Stay tuned, I would drop more posts on this if anymore come to my mind.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Ironically, these bars specifically don't have cussing in them (though some do cuss later in the song lol). <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Not to be confused with Akon's <a href="https://www.youtube.com/watch?v=QcMEmuPFlwM" title="Locked Up - Akon">Locked Up</a>. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Fri, 05 Dec 2025 01:01:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/bars-that-linger</guid>
    </item>
    <item>
      <title>Rules I follow when writing web code</title>
      <link>https://www.mmhq.me/posts/rules-i-follow-when-writing-web-code</link>
      <description><![CDATA[<p><picture><img alt="Screen full of minified JS code" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code-2.webp" srcset="/static/data/images/360w/computer-code-2.webp 360w, /static/data/images/640w/computer-code-2.webp 640w, /static/data/images/1080w/computer-code-2.webp 1080w, /static/data/images/1280w/computer-code-2.webp 1280w" title="Code"></picture></p>
<blockquote class="quote" cite="https://adactio.com/journal/6692">
    <p>The web is a continuum, not a platform.</p>
    <cite>Alex Russell, Google Chrome team</cite>
</blockquote>

<p>A couple weeks ago, I started a brand new web project I call <a href="https://recordrack.io" title="Record Rack official website">Record Rack</a>. It's an inventory application that I'm working on with an old college mate specifically targeted for the African market. Maybe, I'll talk more about the story of Record Rack in a later post.</p>
<p>Over the course of writing the code today, I was going over rules I've picked up along the way from all the web projects I've worked on<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>. Here's what I came up with:</p>
<ul>
<li>
<p><strong>Don't modify CSS through the style property in JavaScript.</strong> To change a style, add or remove the class names of an element instead.</p>
<div class="codehilite"><pre><span></span><code><span class="c1">// Don't do this:</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">button</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">"button"</span><span class="p">);</span>
<span class="nx">button</span><span class="p">.</span><span class="nx">style</span><span class="p">.</span><span class="nx">display</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"none"</span><span class="p">;</span>

<span class="c1">// Do this:</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">button</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">"button"</span><span class="p">);</span>
<span class="nx">button</span><span class="p">.</span><span class="nx">classList</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s2">"hidden"</span><span class="p">);</span>
</code></pre></div>

<p>That way, CSS-specific code can <em>stay</em> in your CSS file:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">hidden</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">none</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

</li>
<li>
<p><strong>Use containers to contain data.</strong> This may seem obvious but I never knew what containers did in CSS, until I started building interfaces on the web. Containers help to keep elements <em>contained</em> in a certain area of the screen. A common use is to keep text in the center. You can do this simply with a little CSS:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">container</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">max-width</span><span class="p">:</span><span class="w"> </span><span class="mi">800</span><span class="kt">px</span><span class="p">;</span><span class="w"> </span><span class="c">/* Keeps contents contained */</span>
<span class="w">    </span><span class="k">margin-inline</span><span class="p">:</span><span class="w"> </span><span class="kc">auto</span><span class="p">;</span><span class="w"> </span><span class="c">/* Centers the container */</span>
<span class="p">}</span>
</code></pre></div>

</li>
<li>
<p><strong>Use SVG spritesheets.</strong> This does not get enough attention. SVGs (or <em>Scalable Vector Graphics</em>) are the future of vector graphics. And they have a lot of benefits like being scalable to any size without deterioration in image quality, being lightweight (they are pretty much XML files), and being customizable or extended with CSS and JavaScript.
    <strong>An SVG spritesheet is a collection of SVG sprites (mostly icons) all in one file.</strong> This is better than using hardcoded SVGs in your HTML files because SVG spritesheets are cached (like CSS and JavaScript are). This prevents them from being downloaded each time your refresh your page. If you want a simple tool to create SVG spritesheets, look no further than a tool I created a while ago, <a href="https://github.com/obeezzy/ssm" title="ssm - SVG Spritesheet Maker - Github"><code>ssm</code></a><sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>.
    Once your spritesheet is created, you can use a sprite like this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"menu icon"</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">use</span> <span class="na">href</span><span class="o">=</span><span class="s">"/static/icons/sprites.svg#menu</span><span class="p">&gt;&lt;/</span><span class="nt">use</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
</code></pre></div>

</li>
<li>
<p><strong>Use HTML and CSS for your UI.</strong> You don't need any JavaScript. This ensures faster loading and rendering.</p>
</li>
<li>
<p><strong>Use IDs for elements that appear once, and classes for elements that appear more than once.</strong> This simple principle helped me get rid of <a href="/posts/goodbye-bem" title="Goodbye, BEM - Mind Matters">BEM</a> in my CSS and I'm a happier man now 😄.</p>
</li>
<li>
<p><strong>Use buttons to respond to clicks and anchors for taking visitors to another page.</strong> Sounds simple, but some people interchange the two. Swapping them could disrupt the accessibility of the webpage.</p>
</li>
<li>
<p><strong>Use rem and hsl() when you can.</strong> <code>rem</code> is a size unit in CSS that's based off the default font size (usually at 16 pixels). Using this unit helps to keep spacing between elements proportional to the font size and more uniform.
    Using <code>hsl()</code> makes it easier to differentiate colors. I've written extensively on it in a <a href="/posts/hsl-over-rgb-and-hex" title="HSL over RGB (and hex) - Mind Matters">previous post</a>.</p>
</li>
<li>
<p><strong>Create deploy scripts.</strong> Because ain't nobody want to have to type a thousand commands just to update your website. And no one definitely has time to <a href="/posts/build-step-obsession" title="Build step obsession - Mind Matters">build anything either</a>.</p>
</li>
<li>
<p><strong>Use dev tools for debugging and fine tuning an interface.</strong> Dev tools is your best friend in the web dev, I can't stress this enough.</p>
</li>
<li>
<p><strong>Use <code>@container</code> over <code>@media</code> whenever possible.</strong> CSS containers are more <em>local</em> than media queries; it only cares about its own size rather than the size of the whole page. This makes them easier to work with and more flexible since you can rearrange the container's elements at different screen sizes.</p>
</li>
<li>
<p><strong>Test for responsiveness early.</strong> Make sure your layouts work well. Also, work on the desktop interface first as it is usually the more complex. Mobile is generally simpler and straightforward, making it easier to collapse the desktop into the mobile screen size once complete.</p>
</li>
<li>
<p><strong>Use flexbox over grids.</strong> Flexbox is good for one-dimensional layouts (i.e. layouts the stretch in only one direction like rows and columns) while grid is good for two-dimensional layouts. In my experience, most of my layouts have been one-dimensional, and mastering flexbox has made it easy to build interfaces faster.</p>
</li>
<li>
<p><strong>Set up a cache buster.</strong> There's nothing worse than pushing up your changes to the server, only to refresh your page and not see any of your changes<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>. The cache is the one to blame for this, but cache busting fixes it. I wrote my own cache buster script that creates a hash and appends it to the end of all cacheable resources (like CSS files, JavaScript files, images, SVG spritesheets etc.). That way, when I want changes to happen on the browser, I just bust the cache and refresh the page. I run it like this:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>python<span class="w"> </span>-m<span class="w"> </span>app.cachebuster<span class="w"> </span>mmhq.me
</code></pre></div>

<p>Then voila! My updates show immediately after I refresh the browser.</p>
</li>
<li>
<p><strong>The cascade is your friend, use it!</strong> I'm talking about the CSS cascade, or the "C" in "CSS"<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup>. The better you get familiar with it, the less likely you would end up breaking your code.</p>
</li>
<li>
<p><strong>Semantics matter.</strong> That's the key to SEO and accessibility. It all starts with choosing the right HTML elements to use on the page. And by avoiding JavaScript frameworks, I can skip the extra steps required and get them for free with semantic HTML.</p>
</li>
</ul>
<h2>Bottom line</h2>
<p>Well, that's all folks! I'm heading back to go wiggle my fingers some more for this web project. Cheers 🍻!</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>It's really not <em>that</em> many. I think I've worked on at least 10 so far. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Allow me to shamelessly plug myself 😜. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>As the wise coders say, <a href="https://syntax.fm/show/753/cache-ruins-everything-around-me/transcript" title="Cache Ruins Everything Around Me - Syntax FM">cache ruins everything around me (C.R.E.A.M.)</a> 😜. <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>CSS stands for <em>Cascading Style Sheets</em>. <a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Mon, 10 Nov 2025 22:50:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/rules-i-follow-when-writing-web-code</guid>
    </item>
    <item>
      <title>Bash shortcuts I use often</title>
      <link>https://www.mmhq.me/posts/bash-shortcuts-i-use-often</link>
      <description><![CDATA[<p><picture><img alt="Mac computer glowing in a dark room" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/glowing-mac-computer.webp" srcset="/static/data/images/360w/glowing-mac-computer.webp 360w, /static/data/images/640w/glowing-mac-computer.webp 640w, /static/data/images/1080w/glowing-mac-computer.webp 1080w, /static/data/images/1280w/glowing-mac-computer.webp 1280w" title="The new web"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Psalms-147-15/">
    <p>He sendeth forth his commandment upon earth: his word runneth very swiftly.</p>
    <cite>Psalms 147:15, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Bourne Again</em></summary>
<pre class="poem">
I'm born again like <a href="https://en.wikipedia.org/wiki/Daredevil:_Born_Again">Matt Murdock</a> — 
Transformed when I use <a href="https://www.gnu.org/software/bash/">Bash</a>;
Performing signs and miracles,
My fingers flinging fast 👨‍💻.
</pre>
</details>

<p><a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)" title="Bash - Wikipedia">Bash</a> and the <a href="https://en.wikipedia.org/wiki/Terminal_emulator" title="Terminal - Wikipedia">terminal</a> are two of the best things to happen to computing. I can talk to the soul of the computer with just the tips of my fingers — talk about sheer power! It's the <em><a href="https://www.urbandictionary.com/define.php?term=OG" title="OG - Urban Dictionary">OG</a> ChatGPT</em> 😉.</p>
<p>In this blog post, I'd like to talk about Bash<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup> shortcuts that save me typing time.</p>
<h2 id="shell-shortcuts">Shell shortcuts</h2>
<p>Rename a file using brace expansion (<code>{}</code>):</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>mv<span class="w"> </span>imaginary-playmate<span class="o">{</span>,-rene-and-angela<span class="o">}</span>.mp3
mv<span class="w"> </span>imaginary-playmate.mp3<span class="w"> </span>imaginary-playmate-rene-and-angela.mp3
</code></pre></div>

<p>Run previous command with <code>sudo</code> using history expansion (<code>!</code>):</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span>/<span class="w">   </span><span class="c1"># Delete folder without proper permission</span>
Permission<span class="w"> </span>denied.
$<span class="w"> </span>sudo<span class="w"> </span>!!<span class="w">   </span><span class="c1"># Run last command with "sudo"</span>
sudo<span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span>/
</code></pre></div>

<p>Run last command with a specific prefix:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>user@mmhq.me<span class="w">   </span><span class="c1"># SSH to server</span>

<span class="c1"># Run a couple commands on server ...</span>
<span class="c1"># ...</span>

$<span class="w"> </span>!ssh<span class="w">   </span><span class="c1"># Return to server</span>
ssh<span class="w"> </span>user@mmhq.me
</code></pre></div>

<p>Print last command (so you know what it is before you run it):</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>!make:p<span class="w">   </span><span class="c1"># print last "make" command without running it</span>
make<span class="w"> </span><span class="nv">VERBOSE</span><span class="o">=</span><span class="m">1</span>

<span class="c1"># Press the "Up" key and hit "Enter" to run the command.</span>
</code></pre></div>

<p>Copy folder and all its contents:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>cp<span class="w"> </span>~/Music/songs/<span class="w"> </span>/run/media/flashdrive/<span class="w">   </span><span class="c1"># Try to copy folders with the "-r" flag missing, fails</span>
cp:<span class="w"> </span>-r<span class="w"> </span>not<span class="w"> </span>specified<span class="p">;</span><span class="w"> </span>omitting<span class="w"> </span>directory<span class="w"> </span><span class="s1">'/home/efe/Music/songs/'</span>
$<span class="w"> </span>cp<span class="w"> </span>-r<span class="w"> </span>!*<span class="w">   </span><span class="c1"># Copy folder with the right flag, succeeds</span>
cp<span class="w"> </span>-r<span class="w"> </span>~/Music/songs/<span class="w"> </span>/run/media/flashdrive/
</code></pre></div>

<p>Run a very long command; use the printed result in another command:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>ls<span class="w"> </span>-1rth<span class="w"> </span>~/Music/songs/*.mp3<span class="w"> </span><span class="p">|</span><span class="w"> </span>tail<span class="w"> </span>-1<span class="w">   </span><span class="c1"># Print last added song in folder</span>
/home/efe/Music/songs/imaginary-playmate.mp3
$<span class="w"> </span>mid3v2<span class="w"> </span>-l<span class="w"> </span><span class="k">$(</span>!!<span class="k">)</span><span class="w">   </span><span class="c1"># Check ID3 metadata tag in MP3 file</span>
mid3v2<span class="w"> </span>-l<span class="w"> </span><span class="k">$(</span>ls<span class="w"> </span>-1rth<span class="w"> </span>~/Music/songs/*.mp3<span class="w"> </span><span class="p">|</span><span class="w"> </span>tail<span class="w"> </span>-1<span class="k">)</span>
</code></pre></div>

<p>Use last argument of last command:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>cp<span class="w"> </span>blog/posts/.template.md<span class="w"> </span>blog/posts/something-exciting-i-have-to-say.md<span class="w">   </span><span class="c1"># Create new blog post by copying template file</span>
$<span class="w"> </span>vim<span class="w"> </span>!$<span class="w">   </span><span class="c1"># Open Markdown file in vim</span>
vim<span class="w"> </span>blog/posts/something-exciting-i-have-to-say.md
</code></pre></div>

<p>Check the error status of the last command to know if I should run it again:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>yay<span class="w"> </span>-Syu<span class="w">   </span><span class="c1"># Run updates on my computer</span>
$<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="nv">$?</span><span class="w">   </span><span class="c1"># Print last error code; prints "0" if successful and any other number if not</span>
<span class="m">0</span>
</code></pre></div>

<p>Switch directories without typing the directory names:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>~/Downloads<span class="w">   </span><span class="c1"># Switch to "Downloads" directory</span>
$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>~/Documents<span class="w">   </span><span class="c1"># Switch to "Documents" directory</span>
$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>-<span class="w">   </span><span class="c1"># Switch back to "Downloads" directory</span>
$<span class="w"> </span><span class="nb">cd</span><span class="w">   </span><span class="c1"># Switch to home directory</span>
</code></pre></div>

<p>Run a recently run command:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span><span class="nb">history</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>rm<span class="w">   </span><span class="c1"># Check history for all "rm" commands</span>
<span class="m">1094</span><span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span>blog/posts/talk-a-lot.md
<span class="m">1096</span><span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span>/tmp/cache
<span class="m">1099</span><span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span>blog/posts/talk-some-more.md
$<span class="w"> </span>!1096<span class="w">   </span><span class="c1"># Run second-to-last command</span>
rm<span class="w"> </span>-rf<span class="w"> </span>/tmp/cache
</code></pre></div>

<h2 id="keyboard-shortcuts">Keyboard shortcuts</h2>
<ul>
<li>
<kbd>Ctrl</kbd> + <kbd>W</kbd> to cut word</li>
<li>
<kbd>Ctrl</kbd> + <kbd>Y</kbd> to restore cut words</li>
<li>
<kbd>↑</kbd> to display previous command</li>
<li>
<kbd>Ctrl</kbd> + <kbd>D</kbd> to logout and close Linux terminal (or to make Mac terminal stop responding and force you to close it and reopen it 🙄🤦).</li>
<li>
<kbd>Ctrl</kbd> + <kbd>C</kbd> to kill a process that's taking forever, or when I run a script or program by mistake.</li>
<li>
<kbd>Ctrl</kbd> + <kbd>L</kbd> to clear the screen.</li>
<li>
<kbd>Ctrl</kbd> + <kbd>Z</kbd> to suspend Vim. (Restore Vim with the <code>fg</code> command.)</li>
<li>
<kbd>Ctrl</kbd> + <kbd>A</kbd> to jump to the start of the line.</li>
<li>
<kbd>Ctrl</kbd> + <kbd>E</kbd> to jump to the end of the line.</li>
<li>
<kbd>Ctrl</kbd> + <kbd>R</kbd> to reverse search through command history.</li>
<li>
<kbd>Tab</kbd> to autocomplete commands and file paths.</li>
<li>
<kbd>Alt</kbd> + <kbd>.</kbd> to display last argument of the last command.</li>
</ul>
<h2 id="bottom-line">Bottom line</h2>
<p><strong>You don't have to move like a snail 🐌 when using the terminal.</strong> Try these shortcuts out today and become the Speedy Gonzalez ⚡ of executing commands. (Leave your nerdy coworkers in awe 🤓🙃.)</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://quickref.me/bash.html" title="Bash cheatsheet - quickref.me">Bash cheatsheet</a></li>
</ul>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p><em>Bash</em> stands for <em>Bourne-Again Shell</em>. Yes, I will <a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">see it in heaven</a> 😇🙏😉. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Tue, 09 Sep 2025 14:50:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/bash-shortcuts-i-use-often</guid>
    </item>
    <item>
      <title>Best battle rap slogans #2</title>
      <link>https://www.mmhq.me/posts/best-battle-rap-slogans-2</link>
      <description><![CDATA[<p><picture><img alt="Headphones hanging on a microphone stand with the microphone" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/microphone.webp" srcset="/static/data/images/360w/microphone.webp 360w, /static/data/images/640w/microphone.webp 640w, /static/data/images/1080w/microphone.webp 1080w, /static/data/images/1280w/microphone.webp 1280w" title="Microphone"></picture></p>
<p>More <a href="https://en.wikipedia.org/wiki/Battle_rap" title="Battle rap - Wikipedia">battle rap</a> slogans I like!</p>
<h2 id="real-sikh">Real Sikh</h2>
<p>Said <a href="https://www.youtube.com/watch?v=Z_pZXYmnBUM&amp;t=2602s" title="Real Sikh vs A. Ward - YouTube">vs A. Ward</a>:</p>
<pre class="poem">
I'm on that Jersey sh*t, that going all out sh*t
Real Sikh, and I'm the problem that you want rounds with?
You were supposed to put in work, but it's wrong now b*tch
Because you can't show up to work, when you call out Sikh
</pre>

<h2 id="arsonal">Arsonal</h2>
<p>Said <a href="https://www.youtube.com/watch?v=NYWPBh3xPW4&amp;t=1184s" title="Arsonal vs Tay Roc - YouTube">vs Tay Roc</a>:</p>
<pre class="poem">
My sh*t is real, my sh*t is raw, my sh*t is authentic
You can't spell bars without putting that "ars" in it
</pre>

<h2 id="gucci-gotti">Gucci Gotti</h2>
<p>Said <a href="https://www.youtube.com/watch?v=uzsN3UIsl34&amp;t=1325s" title="Gucci Gotti vs Loso - YouTube">vs Loso</a>:</p>
<pre class="poem">
And when it's real, y'all can tell, y'all can see it in their eyes
Your turn
See if you can make n*ggas believe them lies
N*gga time
</pre>

<h2 id="showoff">Showoff</h2>
<p>Said <a href="https://www.youtube.com/watch?v=dDy-K05U96c&amp;t=2680s" title="Show Off vs HEAD ICE - YouTube">vs Head ICE</a>:</p>
<pre class="poem">
Don't ask me why I end my rounds with show off n*gga
Three reasons — one being I'ma show off n*gga
Ask my psychiatrist, he'll tell you that Show <em>off</em> n*gga
And I'm a stone cold killer the way Show <em>off</em> n*ggas
Show off n*gga
</pre>

<h2 id="danny-myers">Danny Myers</h2>
<p>Said <a href="https://www.youtube.com/watch?v=h6pdi-Jk1AE&amp;t=638s" title="Danny Myers vs Anderson Burrus - YouTube">vs Anderson Burrus</a>:</p>
<pre class="poem">
You on the ground with this sh*t
This wack MC got another round of this sh*t
Yikes!
</pre>

<h2 id="related-posts">Related posts</h2>
<ul>
<li><a href="/posts/best-battle-rap-slogans-1" title="Best battle rap slogans #1 - Mind Matters HQ">Best battle rap slogans #1</a></li>
</ul>]]></description>
      <pubDate>Tue, 02 Sep 2025 06:04:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/best-battle-rap-slogans-2</guid>
    </item>
    <item>
      <title>Best battle rap slogans #1</title>
      <link>https://www.mmhq.me/posts/best-battle-rap-slogans-1</link>
      <description><![CDATA[<p><picture><img alt="Headphones hanging on a microphone stand with the microphone" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/microphone.webp" srcset="/static/data/images/360w/microphone.webp 360w, /static/data/images/640w/microphone.webp 640w, /static/data/images/1080w/microphone.webp 1080w, /static/data/images/1280w/microphone.webp 1280w" title="Microphone"></picture></p>
<p>As you may or may not know, I watch a lot of <a href="https://en.wikipedia.org/wiki/Battle_rap" title="Battle rap - Wikipedia">battle rap</a> 😄. Here's a list of some of my favorite battle rap slogans. Enjoy!</p>
<h2 id="ill-will">Ill Will</h2>
<p>Said <a href="https://www.youtube.com/watch?v=Qzr62fNfaAA&amp;t=2338s" title="Ill Will vs Bill Collector - YouTube">vs Bill Collector</a>:</p>
<pre class="poem">
I killed you n*gga but I'm still your folks
I just want you to know when you go against Ill, your will get wrote
N*ggas say they the best, but I don killed the goat
Any ill will towards Ill Will, Ill will get ill and you will get smoked
</pre>

<h2 id="jaz-the-rapper">Jaz the Rapper</h2>
<p>Said <a href="https://www.youtube.com/watch?v=4nvk7AGoRTA&amp;t=167s" title="Jaz the Rapper vs Hollow Da Don - YouTube">vs Hollow Da Don</a>:</p>
<pre class="poem">
If y'all don't remember how I does this, good I'ma remind you
It's my first time battling in Houston, I'm 'bout to have a good time too
But if you loved me last time, tonight? I'm that times two
I work on my timing to address bullsh*t when it's time to —
And it's time to
</pre>

<h2 id="a-ward">A. Ward</h2>
<p>Said <a href="https://www.youtube.com/watch?v=KA8Gq2Q1lw4&amp;t=2031s" title="A. Ward vs Charlie Clips - YouTube">vs Charlie Clips</a>:</p>
<pre class="poem">
I did not come here to get personal with you
I brought enough bars to body you, and any person that's with you
I tell them fall in line
Hey, God is good, all the time
</pre>

<h2 id="e-ness">E Ness</h2>
<p>Said <a href="https://www.youtube.com/watch?v=iud_4ZxSxgs&amp;t=538s" title="O Solo vs E Ness - YouTube">vs O Solo</a>:</p>
<pre class="poem">
First round is bars
Second round is personal
Third round I grab the chainsaw and get surgical
</pre>

<p>Said <a href="https://www.youtube.com/watch?v=A7PMHLsi8Rs&amp;t=448s" title="E Hart vs E Ness">vs E Hart</a>:</p>
<pre class="poem">
Because n*ggas don't like to hear the truth but here it goes
I'ma fry these n*ggas till I'm 50 years old
Cause when I wear Da Vinci it's like 50 pair of those
I got 32 questions to ask, where the hoes?
</pre>

<h2 id="e-hart">E Hart</h2>
<p>Said <a href="https://www.youtube.com/watch?v=zRCPaChCz2Y&amp;t=344s" title="E Hart vs QB Diamond - YouTube">vs QB Diamond</a>:</p>
<pre class="poem">
I don't talk much, y'all know it's simple with me
But tonight I will smack a b*tch, bring out the pimping in me
What you ain't know? I tried telling you, it's different with me
Unlimited bars, just call me infinite E
</pre>

<h2 id="o-solo">O Solo</h2>
<p>Said <a href="https://www.youtube.com/watch?v=iud_4ZxSxgs&amp;t=156s" title="O Solo vs E Ness - YouTube">vs E Ness</a>:</p>
<pre class="poem">
It's the most electrified
Your father's uncle, your father's uncle
On your mother's side
</pre>

<h2>Marvwon</h2>
<p>Said <a href="https://www.youtube.com/watch?v=iyJbuu-c5EI&amp;t=985s" title="Marvwon vs Tay Roc - YouTube">vs Tay Roc</a>:</p>
<pre class="poem">
There are only 3 things promised in life, that's death and taxes
And my legend status
When you play the game as good as Iverson
They should never expect you to step in practice
And this is practice
</pre>

<p>Said <a href="https://www.youtube.com/watch?v=iyJbuu-c5EI&amp;t=2798s" title="Marvwon vs Tay Roc - YouTube">vs Tay Roc</a>:</p>
<pre class="poem">
I'm a motherf*cking legend n*gga, are you crazy dude?
I'm a real Detroit n*gga, and I just brought them .380s through
The last thing he gon' see is the D over that navy blue
Like "n*gga, look what you made me do"
</pre>]]></description>
      <pubDate>Mon, 01 Sep 2025 16:16:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/best-battle-rap-slogans-1</guid>
    </item>
    <item>
      <title>I made my blog a little faster</title>
      <link>https://www.mmhq.me/posts/i-made-my-blog-a-little-faster</link>
      <description><![CDATA[<p><picture><img alt="Mac computer glowing in a dark room" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/glowing-mac-computer.webp" srcset="/static/data/images/360w/glowing-mac-computer.webp 360w, /static/data/images/640w/glowing-mac-computer.webp 640w, /static/data/images/1080w/glowing-mac-computer.webp 1080w, /static/data/images/1280w/glowing-mac-computer.webp 1280w" title="New web"></picture></p>
<p><strong>Let's admit it: the speed of this blog sucks.</strong> I've been trying to ignore it for a while, because I was thinking my code was perfect 😇 but it got too bad to ignore. <strong>Load times were taking up to 4 seconds, and it was embarrassing.</strong></p>
<p>In this blog post, I'd like to take you through that journey and speak on the lessons I learned along the way.</p>
<h2 id="4-seconds-thats-an-eternity">4 seconds? That's an eternity!</h2>
<p>I know, and I agree. So I had to ask <a href="https://gemini.google/about/" title="Learn about Gemini, the everyday AI assistant from Google - Gemini's official website">Gemini</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup> about it<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>.</p>
<p><b>Me</b>: "Why is my Flask app slow?"</p>
<p><b>Gemini</b>: "Because you made it that way. Have you tried profiling it?"</p>
<p><b>Me</b>: "Profiling? You mean analyze its performance to identify bottlenecks and areas for optimization? Why would I want to do that?" 🤔</p>
<p><b>Gemini</b>: 😐</p>
<p><b>Me</b>: 😅 "Oh yeah, you right. I'll get right to it."</p>
<p>So I downloaded a profiler using <code>pip</code> called <code>Flask-Profiler</code>, only to eventually find out that there is a built-in profiler in Flask 🤦‍♂️🏾. I eventually figure out that my website takes 4 seconds to load — on <a href="https://en.wikipedia.org/wiki/Localhost" title="Localhost - Wikipedia">localhost</a><sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>! So I turned to my AI genie once more:</p>
<p><b>Me</b>: "Gemini, help! The profiler said my app takes 4 seconds. How long should it take for my website to load on localhost?"</p>
<p><b>Gemini</b>: ... 🤔 ... "It should take your website <strong>300 - 500 milliseconds</strong> at most to load. You must really suck at making websites."</p>
<p><b>Me</b>: 🙄 "Thanks for the compliment. So what can I do to make it faster, wise guy?"</p>
<p><b>Gemini</b>: ... 🤔 ... "Have you tried the <code>Flask-Caching</code> library for Python?"</p>
<p><b>Me</b>: 😯 "What's that?"</p>
<p><b>Gemini</b>: "Flask-Caching is a Flask extension that adds caching to your application. <strong>It stores the results of functions, like database queries or rendered HTML pages, in a fast storage system</strong>. The next time a request is made for the same content, it's served directly from the cache instead of being regenerated, which significantly speeds up your application and reduces the load on your server."</p>
<p><b>Me</b>: 🤯</p>
<p>I rush to download the library and create two caches in my Flask app, a memory cache for storing relatively constant data in my computer's memory, and a file cache for storing data like rendered HTML pages on my file system. Now with all confidence, I restart the server and refresh the home page. I take a look at my results on the <a href="https://qutebrowser.org/" title="Qutebrowser - Qutebrowser official website">qutebrowser's</a> devtools.</p>
<p><b>Me</b>: "What? It's still taking <em>1 second</em> to load. I mean, that's a significant increase, down to a quarter of the initial time taken, but why still so slow? 😩"</p>
<p><b>Gemini</b>: ... 🤔 ... "If you are using the Flask-Caching library and it's still that slow, the situation is worse than I thought. At this point, it's not Python's fault, it's not Flask's fault, it's not Flask-Caching's fault, it's completely on you! You may want to take a look at what you've coded."</p>
<p><b>Me</b>: "Fine, how do I measure durations of functions in Python?"</p>
<p><b>Gemini</b>: ... 🤔 ... "You could use the <code>time.perf_counter()</code> from the <code>time</code> library. It has ..."</p>
<p><b>Me</b>: (<em>Stops prompt.</em>) Say less. 😤</p>
<p>I go down the rabbit hole of my own code ... only to eventually find the culprits, each of them taking at least 0.91 seconds to load:</p>
<div class="codehilite"><pre><span></span><code><span class="k">def</span><span class="w"> </span><span class="nf">index</span><span class="p">(</span><span class="n">page</span><span class="o">=</span><span class="mi">1</span><span class="p">):</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">page</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">page</span><span class="p">)</span>
        <span class="n">db</span> <span class="o">=</span> <span class="n">Database</span><span class="p">(</span><span class="n">cache</span><span class="o">=</span><span class="n">DataCache</span><span class="p">()</span>
                      <span class="k">if</span> <span class="n">Config</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">data_cache_enabled</span>
                      <span class="k">else</span> <span class="kc">None</span><span class="p">)</span>
        <span class="n">posts</span> <span class="o">=</span> <span class="n">db</span><span class="o">.</span><span class="n">posts</span><span class="o">.</span><span class="n">previews</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">page</span><span class="o">=</span><span class="n">page</span><span class="p">)</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">posts</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">page</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No posts for page </span><span class="si">{</span><span class="n">page</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">render_template</span><span class="p">(</span><span class="s2">"index.html"</span><span class="p">,</span>
                               <span class="n">title</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">SITE_TITLE</span><span class="p">,</span>
                               <span class="n">cache_hash</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">cache_hash</span><span class="p">,</span>
                               <span class="n">heading</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">SITE_HEADING</span><span class="p">,</span>
                               <span class="n">subheading</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">SITE_SUBHEADING</span><span class="p">,</span>
                               <span class="n">base_url</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">BASE_URL</span><span class="p">,</span>
                               <span class="n">og_title</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">OG_TITLE</span><span class="p">,</span>
                               <span class="n">og_image</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">OG_IMAGE</span><span class="p">,</span>
                               <span class="n">og_url</span><span class="o">=</span><span class="n">Config</span><span class="o">.</span><span class="n">BASE_URL</span><span class="p">,</span>
                               <span class="n">header</span><span class="o">=</span><span class="n">Header</span><span class="p">(),</span>
                               <span class="n">footer</span><span class="o">=</span><span class="n">Footer</span><span class="p">(</span><span class="n">page_count</span><span class="o">=</span><span class="n">db</span><span class="o">.</span><span class="n">posts</span><span class="o">.</span><span class="n">page_count</span><span class="p">,</span>
                                             <span class="n">rss_visible</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
                               <span class="n">posts</span><span class="o">=</span><span class="n">posts</span><span class="p">,</span>
                               <span class="n">tags</span><span class="o">=</span><span class="n">db</span><span class="o">.</span><span class="n">posts</span><span class="o">.</span><span class="n">tags</span><span class="o">.</span><span class="n">get</span><span class="p">(),</span>  <span class="c1"># &lt;- CULPRIT #1</span>
                               <span class="n">history</span><span class="o">=</span><span class="n">db</span><span class="o">.</span><span class="n">posts</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">get</span><span class="p">())</span>  <span class="c1"># &lt;- CULPRIT #2</span>
    <span class="k">except</span> <span class="ne">RuntimeError</span><span class="p">:</span>
        <span class="n">abort</span><span class="p">(</span><span class="mi">404</span><span class="p">)</span>
</code></pre></div>

<p>The <code>db.posts.tags.get()</code> and <code>db.posts.history.get())</code> functions were to blame! The ironic thing about it is that my blog doesn't even display them on any page. They were features I was planning to add to the early design of my blog but I later decided to keep it simple and leave them out of the webpage. Unfortunately I forgot to take the queries out.</p>
<p>What's worse is that they both would keep getting slower and slower and dragging the page load longer and longer with every new post, because the functions had to go through every blog post file.</p>
<p>After deleting those functions from the file, pages loads were way faster, ranging from <strong>500 - 800 milliseconds</strong> for the home page and <strong>200 - 300 milliseconds</strong> for a blog post. These are not the most ideal of speeds but it's way better than 4 seconds!</p>
<h2 id="bottom-line">Bottom line</h2>
<p>I've learned a couple lessons:</p>
<ul>
<li>
<strong>Don't just assume, measure.</strong> That's the only way to keeping your website fast. You never know what could be hiding in your code.</li>
<li>
<strong>Caching can't save you.</strong> Find out the root cause to issues.</li>
<li>
<strong>Don't look down on <a href="https://en.wikipedia.org/wiki/Static_site_generator" title="Static site generator - Wikipedia">SSGs</a>.</strong> I used to think that they were somewhat redundant and unnecessary because they create a whole bunch of static files that need to be diffed later. Now I know they have their place. In fact, save yourself the stress and use one!<sup id="fnref:4"><a class="footnote-ref" href="#fn:4">4</a></sup>
</li>
</ul>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>I used to use ChatGPT more often, but now they are asking me to sign in before I use it at all. I don't want to give everyone my information (just in case of a data breach), so I use Google's AI, Gemini. Wise decision? 🤷‍♂️🏾 <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Of course, this is an exaggerated (partly fictional) take on the AI 😏. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>For those who are unaware, localhost doesn't go through the Internet at all. It means the website was slow not including the time it takes to get from the server to the browser. TLDR: it was crawling. <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>I will stick to using Flask and caching since I like pain — I'm a masochist 😏. <a class="footnote-backref" href="#fnref:4" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Thu, 28 Aug 2025 18:11:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/i-made-my-blog-a-little-faster</guid>
    </item>
    <item>
      <title>Fruit inspectors in the faith</title>
      <link>https://www.mmhq.me/posts/fruit-inspectors-in-the-faith</link>
      <description><![CDATA[<p><picture><img alt="Table of a variety of fruit, some whole, some cut open" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/fruit.webp" srcset="/static/data/images/360w/fruit.webp 360w, /static/data/images/640w/fruit.webp 640w, /static/data/images/1080w/fruit.webp 1080w, /static/data/images/1280w/fruit.webp 1280w" title="Rainbow of fruit"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Matthew-7-16/">
    <p>You will recognize them by their fruits. Are grapes gathered from thornbushes, or figs from thistles?</p>
    <cite>Matthew 7:16, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Fruit Inspectors</em></summary>
<pre class="poem">
Fruit inspectors in the faith,
Guarding who can pass the gate,
Looking for corrupted seed,
Ignoring their own evil deeds.
</pre>
</details>

<p>Most people in the faith are alright. <strong>They understand the one thing that binds all Christians: the <a href="https://www.kingjamesbibleonline.org/John-3-16/" title="John 3:16 - King James Bible Online">gospel</a> 🙏.</strong></p>
<p><strong>But there are tares among us.</strong> There is a certain group of people that I recently heard can be identified as <em>fruit inspectors</em>.</p>
<h2 id="what-is-a-fruit-inspector">What is a fruit inspector?</h2>
<p><strong>A fruit inspector is a person who believes that Christian believers can recognize someone's spiritual condition by their actions or <em>fruit</em>.</strong> If they analyze a person's actions and see that it doesn't <em>align</em> with God, they claim the believer <em>does not believe</em> and is condemned to hell.</p>
<p>It’s not a biblical title, but the concept is loosely based on Jesus’ teaching (<a href="https://www.kingjamesbibleonline.org/Matthew-7-15_7-20/" title="Matthew 7:15-20 - King James Bible Online">Matthew 7:15–20</a>).</p>
<p>In that scripture, Jesus is warning about false prophets, saying their actions and results (or <em>fruits</em>) reveal their true character — even if they appear godly on the outside.</p>
<p>However, fruit inspectors use the <em>fruits</em> to condemn people as not being fit for heaven.</p>
<p><strong>They are right; none of us are fit for heaven.</strong></p>
<p>This is the whole purpose why Jesus came, to redeem us all. None of us should go if we look at our works because none of us are faithful:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-3-10/">
    <p>As it is written, There is none righteous, no, not one.</p>
    <cite>Romans 3:10, The Bible</cite>
</blockquote>

<p>Fruit inspectors are <a href="https://en.wikipedia.org/wiki/Gatekeeping_(communication)" title="Gatekeeping - Wikipedia">gatekeeping</a> the kingdom preventing eligible men and women from going to heaven, whether they know it or not. They ironically become <em>false prophets</em> themselves because they are <em>prophesying</em> that these people will not go to heaven.</p>
<h2>So if it's not by their <em>fruits</em>, how would I know them?</h2>
<p>It is not wrong to judge people's actions as good or bad in accordance with the Bible. But if we are to judge, we should only judge the action, not the person. We don't know if the person is born again or not.</p>
<p>The only way to know is to recite the gospel and ask if he/she believes. They could be in one of the following situations:</p>
<ul>
<li>They have <strong>never heard</strong> of Christ before.</li>
<li>They have <strong>never believed</strong> Christ before.</li>
<li>They have <strong>believed Christ</strong> before, but they have fallen away.</li>
<li>They have <strong>believed Christ</strong> before, but keep falling away and believing, then falling away...</li>
</ul>
<p>In any case, if they have <strong>believed once</strong>, they are saved for eternity! God will keep them until the last day:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/John-10-27_10–29/">
    <p><span>27</span>
    My sheep hear my voice, and I know them, and they follow me:</p>
    <p><span>28</span>
    And I give unto them eternal life; and they shall never perish, neither shall any man pluck them out of my hand.</p>
    <p><span>29</span>
    My Father, which gave them me, is greater than all; and no man is able to pluck them out of my Father's hand.</p>
    <cite>John 10:27–29, The Bible</cite>
</blockquote>

<p>The evidence is also seen with Abraham, because Abraham <strong>lost faith</strong> that God would give him Isaac. That's why he laughed when God mentioned it:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-17-17/">
    <p>Then Abraham fell upon his face, and laughed, and said in his heart, Shall a child be born unto him that is an hundred years old? and shall Sarah, that is ninety years old, bear?</p>
    <cite>Genesis 17:17, The Bible</cite>
</blockquote>

<p>And yet, God still kept his promise, despite Abraham's doubt:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-21-3/">
    <p>And Abraham called the name of his son that was born unto him, whom Sarah bare to him, Isaac.</p>
    <cite>Genesis 21:3, The Bible</cite>
</blockquote>

<p>Abraham is <em>still</em> known as the <strong>father of faith</strong>, despite his shortcoming.<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></p>
<h2>Bottom line</h2>
<p>In summary, <strong>your belief in Christ is not based on your actions.</strong> <a href="https://www.kingjamesbibleonline.org/2-Corinthians-5-7/" title="2 Corinthians 5:7 - King James Bible Online">We walk by faith, not by sight.</a> We are going to sin whether we are born again or not. Once we believe the <a href="https://www.kingjamesbibleonline.org/John-3-16/" title="John 3:16 - King James Bible Online">gospel</a>, Jesus saves us from the <a href="https://www.kingjamesbibleonline.org/Romans-6-23/" title="Romans 6:23 - King James Bible Online">wages of sin</a> (i.e. death) and gifts us with eternal life that <em>cannot</em> be taken back.</p>
<p>Now that's good news!</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>It's also worth noting that Judas' actions seemed pure but <a href="https://www.kingjamesbibleonline.org/John-6-64/" title="John 6:64 - King James Bible Online">Jesus knew he never believed</a>. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sun, 17 Aug 2025 03:05:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/fruit-inspectors-in-the-faith</guid>
    </item>
    <item>
      <title>Code is communication</title>
      <link>https://www.mmhq.me/posts/code-is-communication</link>
      <description><![CDATA[<p><picture><img alt="Screen full of minified JS code" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code-2.webp" srcset="/static/data/images/360w/computer-code-2.webp 360w, /static/data/images/640w/computer-code-2.webp 640w, /static/data/images/1080w/computer-code-2.webp 1080w, /static/data/images/1280w/computer-code-2.webp 1280w" title="Code"></picture></p>
<blockquote class="quote" cite="https://www.goodreads.com/quotes/6341736-any-fool-can-write-code-that-a-computer-can-understand">
    <p>Any fool can write code that a computer can understand. Good programmers write code that humans can understand.</p>
    <cite>Martin Fowler, software author</cite>
</blockquote>

<details>
    <summary>Poem: <em>Encrypted</em></summary>
<pre class="poem">
I know the script is hard to read,
But reading's not the goal;
You're not supposed to understand —
That's why they call it <em>code</em>!
</pre>
</details>

<p><strong>Just like music, poetry, or even language, code is a form of communication.</strong> Each line, each variable name, each class name etc. tells a story and gives context to the reader of the code.</p>
<p><strong>Code has two purposes: to function and to communicate.</strong> Though your functional code does not have to communicate (i.e. it doesn't <em>have</em> to be readable), failing to do so may leave future developers (including you) puzzled at what you intended at the time of writing the code (i.e. if modifications ever need to be made).</p>
<h2 id="first-example">First example</h2>
<p>Take for instance, which is better?</p>
<p>This:</p>
<div class="codehilite"><pre><span></span><code><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
</code></pre></div>

<p>Or this:</p>
<div class="codehilite"><pre><span></span><code><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
</code></pre></div>

<p>I think it is clear to see that <strong>the second block of code is slightly better than the first</strong>. Why? Because I can assume that <code>10</code> is the coordinate for the <em>x</em> axis and <code>20</code> is the coordinate for the <em>y</em> axis. That is all to it.</p>
<p>We could even make it more explicit:</p>
<div class="codehilite"><pre><span></span><code><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
</code></pre></div>

<p>This works too, but I would say either method would be preferred over the first.</p>
<p>So what's wrong with the first block of code?</p>
<p>The real problem is that we can't tell what the <code>True</code> argument is for. Thankfully, <a href="https://treyhunner.com/2018/04/keyword-arguments-in-python/" title="Keyword Arguments in Python: How to Use Them - Trey Hunner">named arguments</a> exist in Python<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>:</p>
<div class="codehilite"><pre><span></span><code><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">has_label</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">x</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
</code></pre></div>

<p>However, this still <em>feels</em> worse. Why? A couple reasons:</p>
<ul>
<li>We would be unable to set <code>x</code> and <code>y</code> without setting <code>has_label</code><sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>.</li>
<li>It just doesn't look like every other <code>Point</code> object we may have encountered elsewhere. Why break convention if we don't have to?</li>
</ul>
<p>I would argue a better constructor would be this (i.e. assuming that <code>has_label</code> <em>must</em> be used in the constructor):</p>
<div class="codehilite"><pre><span></span><code><span class="n">p</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">has_label</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</code></pre></div>

<p>At this <em>point</em> (pun intended 😉), it depends on how the user intends to make use of <code>Point</code>, but this is a lot <em>less jarring</em> than how it looked before.</p>
<p>In the old code, I would have to look up what the Boolean flag (<code>True</code>) represents; in the new code, its purpose is stated right in front of you. <strong>This may seem like a small change, but little changes like these really draw the line between amateur and professional developers.</strong></p>
<h2 id="second-example">Second example</h2>
<p>Which is better?</p>
<p>This:</p>
<div class="codehilite"><pre><span></span><code><span class="n">d</span> <span class="o">=</span> <span class="n">DateTime</span><span class="p">(</span><span class="mi">2025</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
</code></pre></div>

<p>Or:</p>
<div class="codehilite"><pre><span></span><code><span class="n">d</span> <span class="o">=</span> <span class="n">DateTime</span><span class="p">(</span><span class="n">Date</span><span class="p">(</span><span class="mi">2025</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">15</span><span class="p">),</span> <span class="n">Time</span><span class="p">(</span><span class="mi">13</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">20</span><span class="p">))</span>
</code></pre></div>

<p>Once again, <strong>I would say the second</strong>. There is nothing wrong with the first <em>per se</em>, but it's definitely harder to read compared to the second. Sometimes, there is no wrong or right answer; it's all contextual.</p>
<h2>Bottom line</h2>
<p>Every line of code tries to communicate to its reader, whether we like it or not. <strong>What story is your code telling?</strong></p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Some languages (like C, C++, Java) do not support named arguments, though there are workarounds for that. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>I'm assuming the object's arguments match the way it was declared. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sat, 16 Aug 2025 15:46:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/code-is-communication</guid>
    </item>
    <item>
      <title>Using types defeats the purpose of JavaScript</title>
      <link>https://www.mmhq.me/posts/using-types-defeats-the-purpose-of-javascript</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<blockquote class="scripture" cite="https://www.azquotes.com/quote/803748?ref=javascript">
    <p>JavaScript is the world's most misunderstood programming language.</p>
    <cite>Douglas Crockford, computer programmer</cite>
</blockquote>

<details>
    <summary>Poem: <em>A type</em></summary>
<pre class="poem">
A type for <code>&lt;script&gt;</code>s, a type for <code>&lt;style&gt;</code>s,
A type for <code>&lt;div&gt;</code>s and <code>&lt;span&gt;</code>s,
But JavaScript's the type of code
That's not at all a fan.
</pre>
</details>

<p>I read an <a href="https://dev.to/wisdombits/working-with-html-elements-in-typescript-a-complete-guide13-1b3k" title="Working with HTML Elements in TypeScript: A Complete Guide - dev.to">article</a> on <a href="https://dev.to" title="dev.to">dev.to</a> (again) that talked about how important it is to know types used in JavaScript to do Typescript.</p>
<p>This is already a problem. With the effort made by the browser and the creator of JavaScript to hide types from the developer, why are developers <em>so obsessed</em> with bringing them around?</p>
<p><strong>JavaScript is weakly typed for a reason: it makes easier to read, write, understand and remember.</strong></p>
<p>Let's take a look at the same example,</p>
<p>In JavaScript:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">"myInput"</span><span class="p">);</span>
</code></pre></div>

<p>In Typescript:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">const</span><span class="w"> </span><span class="nx">input</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s2">"myInput"</span><span class="p">)</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="nx">HTMLInputElement</span><span class="p">;</span>
</code></pre></div>

<p>This leads me to ask, why do I care if an object is a <code>HTMLInputElement</code>? How does that make the code easier to understand or write, or even read? The code itself implies that it is an input element; choosing the variable name <code>input</code> makes it even easier!</p>
<p>Now, knowing the type could be useful if you have a lot of code and you are debugging. But to read, write and understand code? I don't think you need them at all. And to add to that, there are other ways to debug without the types, like using DevTools and the built-in <a href="https://javascript.info/debugging-chrome" title="Debugging chrome - javascript.info">browser debugger</a>.</p>
<p>The JavaScript code snippet above is also easier to remember compared to its Typescript counterpart.</p>
<p>I'm not against static typing in general; I do believe it fits lower level languages like C, C++, Java, C# etc. I just don't believe it should be used for interpreted languages like JavaScript (or Python). JavaScript is a <em>scripting language</em> and scripting languages should be easy to script!</p>
<h2>Bottom line</h2>
<p><strong>Nobody cares about types in frontend development (and you shouldn't either)!</strong> Learn to choose clear variable names and that can take you a long way.</p>]]></description>
      <pubDate>Sun, 27 Jul 2025 10:38:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/using-types-defeats-the-purpose-of-javascript</guid>
    </item>
    <item>
      <title>Judas: The proud "publican"</title>
      <link>https://www.mmhq.me/posts/judas-the-proud-publican</link>
      <description><![CDATA[<p><picture><img alt="Inside the center of a church with painted windows" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/church.webp" srcset="/static/data/images/360w/church.webp 360w, /static/data/images/640w/church.webp 640w, /static/data/images/1080w/church.webp 1080w, /static/data/images/1280w/church.webp 1280w" title="Church"></picture></p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-6-70_6-71/">
    <p><span>70</span>
    Jesus answered them, Have not I chosen you twelve, and one of you is a devil?</p>
    <p><span>71</span>
    He spake of Judas Iscariot the son of Simon: for he it was that should betray him,
    being one of the twelve.</p>
    <cite>John 6:70-71, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Judas</em></summary>
<pre class="poem">
<em>In reference to <a href="https://www.kingjamesbibleonline.org/John-12-1_12-8/">John 12:1-8</a></em>

All money to be given to the Son of man I take;
That means I am the least likely to make money mistakes;
Why would Mary anoint his feet and bring us all such gloom?
We would have made a lot of cash from selling the perfume.
</pre>
</details>

<p><strong>Disclaimer: Judas was not a publican; he was the treasurer for Jesus and the disciples.</strong> I use the word as a metaphor because he behaves very <a href="/posts/the-way-of-the-publican#who-were-the-publicans" title="Who were the publicans? - MMHQ">similar to them</a>.</p>
<p>In this post, I would like to explore another exception to the Pharisee-publican rule, Judas Iscariot.</p>
<h2 id="who-was-judas-iscariot">Who was Judas Iscariot?</h2>
<p><a href="https://en.wikipedia.org/wiki/Judas_Iscariot" title="Judas Iscariot - Wikipedia">Judas</a> was a disciple of Jesus that betrayed him. <strong>He had the same greed of a publican; he stole money as the treasurer for Jesus and the disciples:</strong></p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-12-4_12-6/">
    <p><span>4</span>
    Then saith one of his disciples, Judas Iscariot,
    Simon's son, which should betray him,</p>
    <p><span>5</span>
    Why was not this ointment sold for three hundred pence,
    and given to the poor?</p>
    <p><span>6</span>
    This he said, not that he cared for the poor;
    but because he was a thief, and had the bag,
    and bare what was put therein.</p>
    <cite>John 12:4-6, The Bible</cite>
</blockquote>

<p>The strange thing is that this is not what makes Judas different, after all, publicans were greedy too.</p>
<p>What makes Judas different from the publican in <a href="https://www.kingjamesbibleonline.org/Luke-18-13_18-14/" title="The parable of the Pharisee and the publican - King James Bible Online">Luke 18:13-14</a> is the fact that <strong>Judas did not believe in Jesus:</strong></p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-6-64/">
    <p>But there are some of you that believe not. For Jesus knew from the beginning who they were that believed not, and who should betray him.</p>
    <cite>John 6:64, The Bible</cite>
</blockquote>

<p>This was the biggest issue with Judas; he shut out possible redemption by hardening his heart. <strong>Jesus wants to save you, but he will not force it upon you; it will forever be <em>a choice</em>.</strong></p>
<p>Even after being remorseful and returning the money used to betray Jesus, <strong>Judas never believed that Christ could save someone like him, leading him to take his own life:</strong></p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/Matthew-27-3_27-5/">
    <p><span>3</span>
    Then Judas, which had betrayed him,
    when he saw that he was condemned, repented himself,
    and brought again the thirty pieces of silver to the chief priests and elders</p>
    <p><span>4</span>
    Saying, I have sinned in that I have betrayed the innocent blood.
    And they said, What is that to us?</p>
    <p><span>5</span>
    And he cast down the pieces of silver in the temple,
    and departed, and went and hanged himself.</p>
    <cite>Matthew 27:3-5, The Bible</cite>
</blockquote>

<h2 id="bottom-line">Bottom line</h2>
<p>The publican and the prostitute are not always humble. We must learn to humble ourselves before Jesus in order to receive the permanent gift of eternal life, and the knowledge of God through him.</p>
<p>Or as the book of Proverbs puts it, pride comes before a fall:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/Proverbs-16-18/">
    <p>Pride goeth before destruction, and an haughty spirit before a fall.</p>
    <cite>Proverbs 16:18, The Bible</cite>
</blockquote>

<p>We must also remember that Jesus is willing to redeem anyone that seeks it, anyone that <a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">believes in Him</a>. <strong>Salvation is a free gift that none of us have to earn; we just have to reach out and receive it through faith.</strong></p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">The Bible way to heaven</a></li>
</ul>
<h2 id="related-posts">Related posts</h2>
<ul>
<li><a href="/posts/the-way-of-the-pharisee" title="The way of the Pharisee - MMHQ">The way of the Pharisee</a></li>
<li><a href="/posts/the-way-of-the-publican" title="The way of the publican (and the prostitute) - MMHQ">The way of the publican (and the prostitute)</a></li>
<li><a href="/posts/nicodemus-the-humble-pharisee" title="Nicodemus: The humble Pharisee - MMHQ">Nicodemus: The humble Pharisee</a></li>
</ul>]]></description>
      <pubDate>Sat, 26 Jul 2025 05:44:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/judas-the-proud-publican</guid>
    </item>
    <item>
      <title>Nicodemus: The humble Pharisee</title>
      <link>https://www.mmhq.me/posts/nicodemus-the-humble-pharisee</link>
      <description><![CDATA[<p><picture><img alt="Paintings of biblical figures on temple walls" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/temple.webp" srcset="/static/data/images/360w/temple.webp 360w, /static/data/images/640w/temple.webp 640w, /static/data/images/1080w/temple.webp 1080w, /static/data/images/1280w/temple.webp 1280w" title="Temple"></picture></p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-3-1/">
    <p>There was a man of the Pharisees, named Nicodemus, a ruler of the Jews:</p>
    <cite>John 3:1, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Nicodemus</em></summary>
<pre class="poem">
Rabbi, you do miracles
That can only come from God;
How can I be born again?
Go back inside my mom?
</pre>
</details>

<p>With the last <a href="/posts/the-way-of-the-pharisee" title="The way of the Pharisee - MMHQ">couple</a> <a href="/posts/the-way-of-the-publican" title="The way of the publican (and the prostitute) - MMHQ">posts</a> I've posted, it may seem like Pharisees were <em>always proud</em> and publicans (and prostitutes) were <em>always humble</em>. Well, that was the <em>rule</em>, but there were definitely <em>exceptions</em>.</p>
<p>One notable exception was Nicodemus.</p>
<h2 id="who-was-nicodemus">Who was Nicodemus?</h2>
<p><a href="https://en.wikipedia.org/wiki/Nicodemus" title="Nicodemus - Wikipedia">Nicodemus</a> was a Pharisee, but he was different. Nicodemus was curious about Jesus. He didn't just dismiss him like his peers.</p>
<p>Nicodemus knew that for Jesus to perform these miracles, he must have been sent from God. And with that in mind, Nicodemus visited Jesus at night (so as not to be seen by fellow Pharisees) to inquire:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-3-2/">
    <p>The same came to Jesus by night, and said unto him, Rabbi, we know that thou art a teacher come from God: for no man can do these miracles that thou doest, except God be with him.</p>
    <cite>John 3:2, The Bible</cite>
</blockquote>

<p>Jesus answered him:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-3-3/">
    <p>Jesus answered and said unto him, Verily, verily, I say unto thee, Except a man be born again, he cannot see the kingdom of God.</p>
    <cite>John 3:3, The Bible</cite>
</blockquote>

<p>As we can see, even though Jesus was normally harsh to the Pharisees, he wasn't like that with Nicodemus, because Nicodemus <em>humbled</em> himself before him, so Jesus told him how he could receive everlasting life:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-3-16/">
    <p>For God so loved the world,
    that he gave his only begotten Son,
    that whosoever believeth in him should not perish,
    but have everlasting life.</p>
    <cite>John 3:16, The Bible</cite>
</blockquote>

<p><strong>Once again, this proves that Jesus is not <a href="https://www.kingjamesbibleonline.org/Acts-10-34/" title="God is not a respecter of persons - King James Bible Online">a respecter of persons</a>. He will save the Pharisee, the publican, the prostitute, everyone!</strong></p>
<p>Nicodemus also defended Jesus when some leaders wanted to arrest Jesus:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-7-50_7-51/">
    <p><span>50</span>
    Nicodemus saith unto them, (he that came to Jesus by night, being one of them,)</p>
    <p><span>51</span>
    Doth our law judge any man, before it hear him, and know what he doeth?</p>
    <cite>John 7:50-51, The Bible</cite>
</blockquote>

<p>Nicodemus also helped <a href="https://en.wikipedia.org/wiki/Joseph_of_Arimathea" title="Joseph of Arimathea - Wikipedia">Joseph of Arimathea</a> to bury Jesus:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/John-19-39_19-40/">
    <p><span>39</span>
    And there came also Nicodemus, which at the first came to Jesus by night, and brought a mixture of myrrh and aloes, about an hundred pound weight.</p>
    <p><span>40</span>
    Then took they the body of Jesus, and wound it in linen clothes with the spices, as the manner of the Jews is to bury.</p>
    <cite>John 19:39-40, The Bible</cite>
</blockquote>

<p>As you can see, Nicodemus revered Jesus, even after death.</p>
<h2 id="bottom-line">Bottom line</h2>
<p><strong>There is hope for everyone, even for the Pharisees.</strong> As I've discussed above, it all depends on true humility from the inside. This is why Jesus says we should focus on <em>cleaning the inside of the cup</em>:</p>
<blockquote class="quote" cite="https://www.kingjamesbibleonline.org/Matthew-23-25_23-26/">
    <p><span>25</span>
    Woe unto you, scribes and Pharisees, hypocrites! for ye make clean the outside of the cup and of the platter, but within they are full of extortion and excess.</p>
    <p><span>26</span>
    Thou blind Pharisee, cleanse first that which is within the cup and platter, that the outside of them may be clean also.</p>
    <cite>Matthew 23:25-26, The Bible</cite>
</blockquote>

<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.kingjamesbibleonline.org/John-3-1_3-21/" title="John 3:1-21 — King James Bible Online">The night visit</a></li>
<li><a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">The Bible way to heaven</a></li>
</ul>
<h2 id="related-posts">Related posts</h2>
<ul>
<li><a href="/posts/the-way-of-the-pharisee" title="The way of the Pharisee - MMHQ">The way of the Pharisee</a></li>
<li><a href="/posts/the-way-of-the-publican" title="The way of the publican (and the prostitute) - MMHQ">The way of the publican (and the prostitute)</a></li>
</ul>]]></description>
      <pubDate>Fri, 25 Jul 2025 05:21:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/nicodemus-the-humble-pharisee</guid>
    </item>
    <item>
      <title>The way of the publican (and the prostitute)</title>
      <link>https://www.mmhq.me/posts/the-way-of-the-publican</link>
      <description><![CDATA[<p><picture><img alt="Inside the center of a church with painted windows" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/church.webp" srcset="/static/data/images/360w/church.webp 360w, /static/data/images/640w/church.webp 640w, /static/data/images/1080w/church.webp 1080w, /static/data/images/1280w/church.webp 1280w" title="Church"></picture></p>
<blockquote id="the-publican" class="scripture" cite="https://www.kingjamesbibleonline.org/Luke-18-13_18-14/">
    <p><span>13</span>
    And the publican, standing afar off, would not lift up so much as his eyes unto heaven, but smote upon his breast, saying, God be merciful to me a sinner.</p>
    <p><span>14</span>
    I tell you, this man went down to his house justified rather than the other: for every one that exalteth himself shall be abased; and he that humbleth himself shall be exalted.
    </p>
    <cite>Luke 18:13-14, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>The Publican</em></summary>
<pre class="poem">
The publican would not lift up his eyes;
He knew that God could see through his disguise;
He knew that he got rich by telling lies;
"Please show me grace and mercy, Lord", he cried.
</pre>
</details>

<p>Yesterday I spoke about <a href="/posts/the-way-of-the-pharisee" title="The way of the Pharisee — MMHQ">what to expect from Pharisees</a> and how their mentality makes them think of themselves as better than their fellow men.</p>
<p>Today, I would like to talk about the <em>yin</em> of the Pharisee — the publican — and what we can learn from the <em>sinner</em>.</p>
<h2 id="who-were-the-publicans">Who were the publicans?</h2>
<p>Publicans were the tax collectors in the Bible; they collected tax on behalf of the Roman government.</p>
<p>I always wondered why they were mentioned a lot in the New Testament of the Bible. What was their significance?</p>
<p>So I asked ChatGPT, and here's what it said:</p>
<ul>
<li>
<p><strong>Despised by Jews:</strong> Publicans were often Jews working for the Roman occupiers, so they were seen as traitors. Many were also corrupt, charging extra and keeping the surplus.</p>
</li>
<li>
<p><strong>Symbol of sinners:</strong> Because of their reputation for greed and dishonesty, publicans became a symbol of moral and spiritual failure in Jewish society.</p>
</li>
<li>
<p><strong>Outcasts:</strong> Publicans were social and spiritual outcasts, yet were still capable of redemption through humility, repentance and faith.</p>
</li>
</ul>
<p>From what ChatGPT said, we can come to some interesting conclusions:</p>
<ul>
<li>Publicans were <em>willful</em> sinners; they were knowingly overcharging people in taxes to make a quick buck.</li>
<li>Publicans had a bad reputation and were looked at as the scum of the earth.</li>
<li>Publicans were rejected by many people, making them outcasts.</li>
</ul>
<h2 id="who-were-the-prostitutes">Who were the prostitutes?</h2>
<p>Prostitutes were women who engaged in sexual relations outside of marriage for payment.</p>
<p>The prostitutes were also <strong>despised by Jews</strong>, <strong>symbols of sinners</strong> and <strong>outcasts</strong>. The main difference was that publicans charged extra to get a financial gain, and prostitutes charged sex for the same advantage.</p>
<p>Just like the publicans:</p>
<ul>
<li>Prostitutes were <em>willful</em> sinners.</li>
<li>Prostitutes had a bad reputation.</li>
<li>Prostitutes were rejected by many people.</li>
</ul>
<p>Pharisees would look down on both publicans and prostitutes thinking, "Why can't they both be more like me?" or "Thank God I'm better than them."</p>
<h2 id="what-the-bible-says-about-publicans-and-prostitutes">What the Bible says about publicans and prostitutes</h2>
<p>Publicans and prostitutes may seem like they are beyond redemption; they are willful sinners that do not want to change, or want to change but refuse to do so. But there is even hope for them, according to Jesus:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Matthew-21-31/">
    <p>Verily I say unto you, That the publicans and the harlots go into the kingdom of God before you.</p>
    <cite>Matthew 21:31b, The Bible</cite>
</blockquote>

<p>The main attribute that distinguishes them from the Pharisee is their understanding that they need a savior. They know what they are doing is wrong, but they know only a higher power can deliver them from it.</p>
<p>These people are more likely to <a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">believe in Him</a> than the Pharisee, because the Pharisee is trusting in his own power.</p>
<p>As stated in the Bible, God desires to show us mercy (to the publicans and prostitutes), not to demand sacrifice (as the Pharisees believe):</p>
<blockquote id="hosea-6-6" class="scripture" cite="https://www.kingjamesbibleonline.org/Hosea-6-6/">
    <p>For I desired mercy, and not sacrifice; and the knowledge of God more than burnt offerings.</p>
    <cite>Hosea 6:6, The Bible</cite>
</blockquote>

<p>We can see when he showed Zacchaeus the publican mercy (<a href="https://www.kingjamesbibleonline.org/Luke-19-1_19-10/" title="The story of Zacchaeus the publican — King James Bible Online">Luke 19:1-10</a>) and when he showed a woman who committed adultery (similar to a prostitute) mercy (<a href="https://www.kingjamesbibleonline.org/John-8-1_8-11/" title="The story of the woman who committed adultery — King James Bible Online">John 8:1-11</a>). In both cases, none were <em>worthy</em> of salvation, but Jesus proved that <strong>the gift of salvation is for everyone, if you are humble enough to receive it.</strong></p>
<h2 id="bottom-line">Bottom line</h2>
<p><strong>The moral of the story is not to live like the Pharisee or to live like the publican or prostitute, but to understand that Jesus' mercy is limitless.</strong> Whether we like it or not, we will sin, but this should be a reminder of Jesus' mercy on us and how we should show mercy to others.</p>
<p>It also reminds us to be careful not to think we know what to do at all times like the Pharisee but to be humble enough to seek it out from God; <a href="/posts/the-way-of-the-publican#hosea-6-6" title="The way of the publican (and the prostitute) — MMHQ">the knowledge of God is more than burnt offerings</a>.</p>
<p>Or, as Paul the apostle put it:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/1-Corinthians-10-12/">
    <p>Wherefore let him that thinketh he standeth take heed lest he fall.</p>
    <cite>1 Corinthians 10:12, The Bible</cite>
</blockquote>

<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.kingjamesbibleonline.org/Luke-18-9_18-14/" title="Luke 18:9-14 — King James Bible Online">The parable of the Pharisee and the publican</a></li>
<li><a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">The Bible way to heaven</a></li>
</ul>]]></description>
      <pubDate>Thu, 24 Jul 2025 05:06:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/the-way-of-the-publican</guid>
    </item>
    <item>
      <title>The way of the Pharisee</title>
      <link>https://www.mmhq.me/posts/the-way-of-the-pharisee</link>
      <description><![CDATA[<p><picture><img alt="Paintings of biblical figures on temple walls" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/temple.webp" srcset="/static/data/images/360w/temple.webp 360w, /static/data/images/640w/temple.webp 640w, /static/data/images/1080w/temple.webp 1080w, /static/data/images/1280w/temple.webp 1280w" title="Temple"></picture></p>
<blockquote id="the-pharisee" class="scripture" cite="https://www.kingjamesbibleonline.org/Luke-18-11_18-12/">
    <p><span>11</span>
    The Pharisee stood and prayed thus with himself, God, I thank thee, that I am not as other men are, extortioners, unjust, adulterers, or even as this publican.</p>
    <p><span>12</span>
    I fast twice in the week, I give tithes of all that I possess.
    </p>
    <cite>Luke 18:11-12, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>The Pharisee</em></summary>
<pre class="poem">
The Pharisee is not like other men;
Not like extortioners who give God stress;
He fasts and prays and tithes more than the rest;
He doesn't have to ask 'cause he knows best.
</pre>
</details>

<p>I watched a <a href="https://www.youtube.com/watch?v=5YBexsJrhY4" title="Thank God I'm not like 'other men' — Onoranto Diamante">YouTube video</a> today that made me think of the real nature of the Pharisees in the Bible and how I'm sort of similar.</p>
<p>As highlighted in the <a href="/posts/the-way-of-the-pharisee#the-pharisee" title="Luke 18:11-12 — MMHQ">above scripture</a>, the Pharisee separates himself by thinking of himself to be better than <em>other men</em>, which brings me to my first observation:</p>
<p><strong>The Pharisee tends to measure himself against the standards of other men as opposed to the standard of God:</strong></p>
<ul>
<li>Churchgoers compare themselves to non-churchgoer.</li>
<li>The chaste compare themselves to the sexually immoral.</li>
<li>The sober compares himself to the drug addict.</li>
<li>The React JS user compares himself to the user of Angular/Vue user.</li>
</ul>
<p>This sort of thinking makes us self-righteous, because we believe we just need to be better than other people. But that is not the standard God wants for us:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Deuteronomy-18-13/">
    <p>Thou shalt be perfect with the LORD thy God.</p>
    <cite>Deuteronomy 18:13, The Bible</cite>
</blockquote>

<p>Or in the words of Jesus:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Matthew-5-48/">
    <p>Be ye therefore perfect, even as your Father which is in heaven is perfect.</p>
    <cite>Matthew 5:48, The Bible</cite>
</blockquote>

<p>If we were looking at God's standard, we wouldn't be so judgmental of others; we would more judgmental of ourselves and more focused on what God's word says about anything we deal with.</p>
<p>Therefore:</p>
<ul>
<li>The churchgoer should ask, should I go to church and how many times does God want me to go to church?</li>
<li>The chaste should ask, should I be chaste and how many people does God want me to sleep with?</li>
<li>The sober should ask, should I be sober and how long does God want me to be sober for?</li>
<li>The React JS user should ask himself, should I be a React user (No 😑) and what does the web standards require of me?</li>
</ul>
<p>However, <strong>even knowing God's standard doesn't fully help.</strong> We are incapable of keeping God's word:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-3-23/">
    <p>For all have sinned, and come short of the glory of God;</p>
    <cite>Romans 3:23, The Bible</cite>
</blockquote>

<p><strong>The solution? Jesus Christ!</strong></p>
<p>He fulfilled the law so that we don't have to. If you <a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">believe in Him</a> today, he will save you from the repercussion of sin, which is death:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-6-23/">
    <p>For the wages of sin is death; but the gift of God is eternal life through Jesus Christ our Lord.</p>
    <cite>Romans 6:23, The Bible</cite>
</blockquote>

<h2>Bottom line</h2>
<p>We should be more <em>self-aware</em> than <em>self-righteous</em>. Self-righteousness leads to <em>holier-than-thou</em> behavior and thinking of our fellow humans as less.</p>
<p><strong>If we meditate on God's standard, we would be more aware of our flaws and we could use that to become better people and to work on the parts of ourselves that fall short.</strong> It also makes us aware of our need for grace from God and man.</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.kingjamesbibleonline.org/Luke-18-9_18-14/" title="Luke 18:9-14 — King James Bible Online">The parable of the Pharisee and the publican</a></li>
<li><a href="https://www.youtube.com/watch?v=yvOzb8_ou_s" title="The Bible way to heaven — Onoranto Diamante">The Bible way to heaven</a></li>
</ul>]]></description>
      <pubDate>Wed, 23 Jul 2025 05:13:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/the-way-of-the-pharisee</guid>
    </item>
    <item>
      <title>Why I like Qt</title>
      <link>https://www.mmhq.me/posts/why-i-like-qt</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<blockquote class="quote" cite="https://www.linuxjournal.com/node/1338835">
    <p>Code less. Create more. Deploy everywhere.</p>
    <cite>Qt motto, Qt Company</cite>
</blockquote>

<details>
    <summary>Poem: <em>Qt's a cutie</em></summary>
<pre class="poem">
A framework made to bring you smiles
Without a lot to bear;
Code less, no stress; make more — galore;
And deploy everywhere!
</pre>
</details>

<p>The <a href="http://qt.io" title="Qt official homepage — qt.io">Qt C++ framework</a> (with <em>Qt</em> officially pronounced as <em>"cute"</em>) is software I hold dear to my heart. I have used it since I started learning C++ back in 2010. In fact, I would say Qt was the reason I learned C++.</p>
<p>At the time, I already knew the C programming language but I was looking for a programming language slightly higher level than C to build desktop user interfaces for the code I wrote. I was working with mostly microcontrollers and embedded systems then.</p>
<p>I searched for the best desktop UI framework on Google and Qt popped up on <a href="http://www.stackoverflow.com" title="Qt official homepage — qt.io">Stack Overflow</a>. Qt was among the favorites being used to make applications like Autodesk Maya, Blender, VirtualBox and Wireshark, so I chose Qt; it just happened to be written with C++. </p>
<p><strong>In this post, I would like to discuss some of the benefits of using Qt.</strong></p>
<h2>It's cross-platform</h2>
<p>Qt can be used to build applications that run natively on Windows, Mac, and Linux, and in recent years have extended their reach to Android, iOS, Tizen and even the web.</p>
<h2>C++ is its core language</h2>
<p><a href="https://harmful.cat-v.org/software/c++/" title="C++ — cat-v.org">C++ gets a lot of hate in programming communities</a> but it is definitely one of my favorite languages (along with <a href="/posts/why-i-like-python-and-javascript" title="Why i like python and javascript — MMHQ">Python and JavaScript</a>). I love how close it is to the hardware and how easy it is to connect that knowledge with software.</p>
<p>Qt being written with C++, a fast and efficient language that was similar to C, added to its <em>flair</em> for me.</p>
<h2>It has QML</h2>
<p><a href="https://www.qt.io/product/qt6/qml-book/ch04-qmlstart-qml-syntax" title="QML Syntax — qt.io">QML</a>, which stands for <em>Qt Modeling Language</em>, has changed the way I think about UI development.</p>
<p>User interfaces can be described with ease in this language. It made me to understand frontend-backend separation more and how that could lead to cleaner code.</p>
<h2>It has great documentation</h2>
<p>Qt's documentation is so simple and straightforward; I was surprised to see that other documentations are not always the same. I have lost a couple hair follicles from pulling while reading the Android documentation. Qt invests a lot of time in making sure the documentation is easy to understand and apply compared to other UI frameworks.</p>
<h2>Easy to use</h2>
<p>There is not a lot of required to get started. You could make a button appear on the screen after downloading the Qt SDK with the following code:</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;QApplication&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;QPushButton&gt;</span>

<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="w">    </span><span class="n">QApplication</span><span class="w"> </span><span class="n">app</span><span class="p">(</span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="n">argv</span><span class="p">);</span>
<span class="w">    </span><span class="n">QPushButton</span><span class="w"> </span><span class="n">button</span><span class="p">;</span>
<span class="w">    </span><span class="n">QObject</span><span class="o">::</span><span class="n">connect</span><span class="p">(</span><span class="o">&amp;</span><span class="n">button</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">QPushButton</span><span class="o">::</span><span class="n">clicked</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">app</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">QApplication</span><span class="o">::</span><span class="n">quit</span><span class="p">);</span>
<span class="w">    </span><span class="n">button</span><span class="p">.</span><span class="n">show</span><span class="p">();</span>
<span class="w">    </span><span class="n">app</span><span class="p">.</span><span class="n">exec</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div>

<h2>Consistency in code</h2>
<p>Classes in Qt with similar behavior have consistent interfaces. For instance, both <a href="https://doc.qt.io/qt-6/qtcpsocket.html" title="QTcpSocket — doc.qt.io"><code>QTcpSocket</code></a> and <a href="https://doc.qt.io/qt-6/qfile.html" title="QFile — doc.qt.io"><code>QFile</code></a> have a <code>read()</code> and <code>write()</code> function, along with the ability to use the stream operators (<code>&gt;&gt;</code> and <code>&lt;&lt;</code>) on them. (They both inherit from <a href="https://doc.qt.io/qt-6/qiodevice.html" title="QIODevice — doc.qt.io"><code>QIODevice</code></a>.) This makes it easy to learn similar classes quickly.</p>
<h2>Great API standards</h2>
<p>Compared to other UI frameworks, I think Qt's methods are a little more consistent and easy to invoke and memorize. Compare the code for rendering a button in Qt with that of Java Swing and Android:</p>
<div class="codehilite"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">javax.swing.*</span><span class="p">;</span>

<span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">ButtonExample</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">        </span><span class="c1">// Create a frame (window)</span>
<span class="w">        </span><span class="n">JFrame</span><span class="w"> </span><span class="n">frame</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">JFrame</span><span class="p">(</span><span class="s">"Swing Button Example"</span><span class="p">);</span>
<span class="w">        </span><span class="n">frame</span><span class="p">.</span><span class="na">setSize</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span><span class="w"> </span><span class="mi">200</span><span class="p">);</span>
<span class="w">        </span><span class="n">frame</span><span class="p">.</span><span class="na">setDefaultCloseOperation</span><span class="p">(</span><span class="n">JFrame</span><span class="p">.</span><span class="na">EXIT_ON_CLOSE</span><span class="p">);</span>

<span class="w">        </span><span class="c1">// Create a button</span>
<span class="w">        </span><span class="n">JButton</span><span class="w"> </span><span class="n">button</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">JButton</span><span class="p">(</span><span class="s">"Click Me"</span><span class="p">);</span>

<span class="w">        </span><span class="c1">// Add action listener to handle clicks</span>
<span class="w">        </span><span class="n">button</span><span class="p">.</span><span class="na">addActionListener</span><span class="p">(</span><span class="n">e</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="p">{</span>
<span class="w">            </span><span class="n">JOptionPane</span><span class="p">.</span><span class="na">showMessageDialog</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span><span class="w"> </span><span class="s">"Button was clicked!"</span><span class="p">);</span>
<span class="w">        </span><span class="p">});</span>

<span class="w">        </span><span class="c1">// Add button to the frame's content pane</span>
<span class="w">        </span><span class="n">frame</span><span class="p">.</span><span class="na">getContentPane</span><span class="p">().</span><span class="na">add</span><span class="p">(</span><span class="n">button</span><span class="p">);</span>

<span class="w">        </span><span class="c1">// Make the frame visible</span>
<span class="w">        </span><span class="n">frame</span><span class="p">.</span><span class="na">setVisible</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<div class="codehilite"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">android.os.Bundle</span><span class="p">;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">android.view.View</span><span class="p">;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">android.widget.Button</span><span class="p">;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">android.widget.Toast</span><span class="p">;</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">androidx.appcompat.app.AppCompatActivity</span><span class="p">;</span>

<span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">MainActivity</span><span class="w"> </span><span class="kd">extends</span><span class="w"> </span><span class="n">AppCompatActivity</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="nd">@Override</span>
<span class="w">    </span><span class="kd">protected</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">onCreate</span><span class="p">(</span><span class="n">Bundle</span><span class="w"> </span><span class="n">savedInstanceState</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">        </span><span class="kd">super</span><span class="p">.</span><span class="na">onCreate</span><span class="p">(</span><span class="n">savedInstanceState</span><span class="p">);</span>
<span class="w">        </span><span class="n">setContentView</span><span class="p">(</span><span class="n">R</span><span class="p">.</span><span class="na">layout</span><span class="p">.</span><span class="na">activity_main</span><span class="p">);</span>

<span class="w">        </span><span class="n">Button</span><span class="w"> </span><span class="n">myButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">findViewById</span><span class="p">(</span><span class="n">R</span><span class="p">.</span><span class="na">id</span><span class="p">.</span><span class="na">myButton</span><span class="p">);</span>

<span class="w">        </span><span class="n">myButton</span><span class="p">.</span><span class="na">setOnClickListener</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">View</span><span class="p">.</span><span class="na">OnClickListener</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w">            </span><span class="nd">@Override</span>
<span class="w">            </span><span class="kd">public</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">onClick</span><span class="p">(</span><span class="n">View</span><span class="w"> </span><span class="n">view</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">                </span><span class="n">Toast</span><span class="p">.</span><span class="na">makeText</span><span class="p">(</span><span class="n">MainActivity</span><span class="p">.</span><span class="na">this</span><span class="p">,</span><span class="w"> </span><span class="s">"Button clicked!"</span><span class="p">,</span><span class="w"> </span><span class="n">Toast</span><span class="p">.</span><span class="na">LENGTH_SHORT</span><span class="p">).</span><span class="na">show</span><span class="p">();</span>
<span class="w">            </span><span class="p">}</span>
<span class="w">        </span><span class="p">});</span>
<span class="w">    </span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div>

<p>I know, some complicated stuff 😒. </p>
<h2>Multi-language support</h2>
<p>Qt supports C++ and Python officially, but work is being done to <a href="https://www.qt.io/qt-bridges" title="Qt bridges — qt.io">extend it work with more languages</a>.</p>
<h2>Comprehensive framework</h2>
<p>Qt also has non-UI modules for database, networking, remote objects etc. This reduces the number of dependencies you need when using it.</p>
<h2>It's open source</h2>
<p>I had no money when I started programming, so this is important. It was good to use a framework that was completely free to use.</p>
<h2>Bottom line</h2>
<p><strong>Without Qt, I don't think I would be so immersed in the UI/UX world.</strong> Qt carefully crafted their APIs and gave me a reason to care. I appreciate the effort of all the engineers that contributed.</p>
<p>Qt is not perfect. I will definitely circle back later to talk its shortcomings.</p>]]></description>
      <pubDate>Tue, 22 Jul 2025 20:31:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/why-i-like-qt</guid>
    </item>
    <item>
      <title>VaneJS is vain JS</title>
      <link>https://www.mmhq.me/posts/vanejs-is-vain-js</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<blockquote id="aarons-staff" class="scripture" cite="https://www.kingjamesbibleonline.org/Exodus-7-10_7-12/">
    <p><span>10</span>
    And Moses and Aaron went in unto Pharaoh, and they did so as the LORD had commanded: and Aaron cast down his rod before Pharaoh, and before his servants, and it became a serpent.</p>
    <p><span>11</span>
    Then Pharaoh also called the wise men and the sorcerers: now the magicians of Egypt, they also did in like manner with their enchantments.</p>
    <p><span>12</span>
    For they cast down every man his rod, and they became serpents: but Aaron's rod swallowed up their rods.</p>
    <cite>Exodus 7:10-12, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Vain Vane</em></summary>
<pre class="poem">
Vain Vane, go away;
We don't want you here today;
We prefer vanilla tech;
Not the vain crap you inject.

Vain Vane, you're a pain;
Wind-twisted just like your name;
You cause my bloody veins to boil;
You give developers much toil.
</pre>
</details>

<p>I'm very surprised that new JS frameworks are still promoted in this time and age. I hold fast to the belief that <strong>all JS frameworks were never a good permanent solution</strong>. I was hoping that with all the problems of <a href="https://infrequently.org/2024/11/if-not-react-then-what/" title="If not React, then what? — Infrequently Noted">React</a> and <a href="https://www.webrocketx.com/angularSucks.html" title="Why Angular sucks — WebRocketX">Angular</a>, we would move away from this framework obsession.</p>
<p>But lo and behold, another "framework that is not really a framework" called <a href="https://dev.to/abtahitajwar/how-i-accidentally-came-up-with-a-reactive-js-ui-library-33ma#what-makes-vanejs-different" title="What makes VaneJS different — dev.to">VaneJS</a> rises from the ashes. When will these people quit?</p>
<p>In this post, <strong>I would like to take a look at the false advantages of VaneJS and compare them to a no-framework setup.</strong></p>
<h2 id="it-has-zero-build-steps">It has zero build steps</h2>
<p><strong>His claim</strong>: <em>Just add a single static <code>.js</code> file to your project. No bundlers, no compilers.</em></p>
<p><strong>My opinion</strong>: You know what else has zero build steps? Vanilla JavaScript!</p>
<p>Having no build steps is only a relative advantage; it only holds up if you compare it to <em>other JS frameworks</em>. But if you really don't want any build steps, just use HTML, CSS and vanilla JavaScript.</p>
<h2 id="its-backend-friendly">It's backend friendly</h2>
<p><strong>His claim</strong>: <em>Works out-of-the-box with PHP, Laravel, Django, Express, ASP.NET — whatever you want.</em></p>
<p><strong>My opinion</strong>: So does vanilla JavaScript.</p>
<h2 id="no-paradigm-shift">No paradigm shift</h2>
<p><strong>His claim</strong>: <em>Feels like HTML, behaves like a reactive system.</em></p>
<p><strong>My opinion</strong>: How is that an advantage? HTML, CSS and JavaScript are usually separated for good reason. They all have different goals, and are more manageable when they are updated separately.</p>
<p>Not every project needs a reactive system. Sometimes building towards that in your project provides a better, more lean solution than a one-size-fits-all approach where you have to ship a large framework to the browser.</p>
<h2 id="it-has-minimal-mental-overhead">It has minimal mental overhead</h2>
<p><strong>His claim</strong>: <em>You don’t need to "learn a framework." If you know HTML and JS, you’re good.</em></p>
<p><strong>My opinion</strong>: The most minimal mental overhead is when you use the vanilla web languages: HTML, CSS and JavaScript.</p>
<h2 id="reactive-stores-between-pages">Reactive stores between pages</h2>
<p><strong>His claim</strong>: <em>Yes, you can store values and retrieve them across HTML pages.</em></p>
<p>For example:</p>
<div class="codehilite"><pre><span></span><code><span class="cm">&lt;!-- about.html --&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span> <span class="na">data-vn-bind</span><span class="o">=</span><span class="s">"mystore.name"</span><span class="p">&gt;&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</code></pre></div>

<div class="codehilite"><pre><span></span><code><span class="c1">// main.js</span>
<span class="nx">$setStore</span><span class="p">(</span><span class="s2">"mystore"</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s2">"SharedValue"</span><span class="w"> </span><span class="p">});</span>
</code></pre></div>

<p><strong>My opinion</strong>: Has anyone ever heard of <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage" title="localStorage - MDN web docs"><code>localStorage</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage" title="sessionStorage - MDN web docs"><code>sessionStorage</code></a>? I think both of these features of the browser are flexible enough to hold any type of data you need to persist between page loads.</p>
<p>Also, does anyone really want to know what <code>data-vn-bind</code> means? Or what <code>$setStore()</code> does? Is any of this easy to interpret without reading the manual?</p>
<p>I know you need to read the documentation to learn about <code>localStorage</code> and <code>sessionStorage</code> but at least the only dependency it has is the browser. You don't need to download a whole framework to the browser.</p>
<p>It's really equivalent to bringing sand to the beach.</p>
<p>Once again, I don't see how this is an advantage.</p>
<h2 id="smart-inline-events">Smart inline events</h2>
<p><strong>His claim</strong>: <em>Attach multiple events inline:</em></p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">button</span> <span class="na">data-vn-on</span><span class="o">=</span><span class="s">"click:myFunc({user.name}); mouseover:logHover()"</span><span class="p">&gt;</span>Click me<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</code></pre></div>

<div class="codehilite"><pre><span></span><code><span class="nx">$event</span><span class="p">(</span><span class="s2">"myFunc"</span><span class="p">,</span><span class="w"> </span><span class="p">({</span><span class="w"> </span><span class="nx">params</span><span class="w"> </span><span class="p">})</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">params</span><span class="p">[</span><span class="mf">0</span><span class="p">]));</span>
<span class="nx">$event</span><span class="p">(</span><span class="s2">"logHover"</span><span class="p">,</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"hovered!"</span><span class="p">));</span>
</code></pre></div>

<p><strong>My opinion</strong>: You would be better off learning the JavaScript event system and how it works with the DOM. It is guaranteed to work on every browser, and you would have a better understanding of the simplicity of JavaScript coding.</p>
<h2>Bottom line</h2>
<p>Just the same way <a href="/posts/vanejs-is-vain-js#aarons-staff" title="Aaron's staff scripture">Aaron's staff swallowed up all the other staffs of the magicians</a>, HTML, CSS, vanilla JavaScript, and the browser would <em>swallow</em> every framework out there.</p>
<p><strong>So learn HTML, CSS and JavaScript. That is all you need to make websites.</strong> Unless of course you like pulling teeth.</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://dev.to/greenersoft/in-2025-we-can-and-should-simplify-web-development-2m8c" title="We can simplify web development — dev.to">We can and should simplify web development — dev.to</a></li>
</ul>]]></description>
      <pubDate>Wed, 16 Jul 2025 18:29:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/vanejs-is-vain-js</guid>
    </item>
    <item>
      <title>Why I like Python and JavaScript</title>
      <link>https://www.mmhq.me/posts/why-i-like-python-and-javascript</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<details>
    <summary>Poem: <em>The Spider and The Serpent</em></summary>
<pre class="poem">
One of them was quiet,
The other liked to hiss;
I never knew they'd bite me once
They leaned in for a kiss;

The venom power's strong,
I fell right for their trap;
One spun a bed of web,
The other tripped me for a nap.
</pre>
</details>

<p>I watched a <a href="https://www.youtube.com/watch?v=PYh6D1NhatY&amp;si=Tq50tiWzr22hdL9Q&amp;themeRefresh=1" title="The Most MISUNDERSTOOD Programming Language — YouTube">YouTube video</a> the other day where the speaker spoke about powerful languages like Lisp and Tcl. I asked myself, <strong>"Why don't I know these languages?"</strong> Then I thought, <strong>"because I know Python and JavaScript!"</strong></p>
<p>These are not the <em>best programming languages</em> out there, I haven't tried enough languages to make that claim. But they are very effective in helping me to get things done.</p>
<p>But what makes them so effective for me?</p>
<h2 id="they-both-use-modules">They both use modules</h2>
<p>Modules are files that contain bits of code. These modules can be imported into other code files. In both Python and JavaScript, <strong>modules can be aliased and can help you contextualize your code better.</strong></p>
<p>For example, in Python:</p>
<div class="codehilite"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">shapes.square</span><span class="w"> </span><span class="kn">import</span> <span class="n">Area</span> <span class="k">as</span> <span class="n">SquareArea</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">shapes.circle</span><span class="w"> </span><span class="kn">import</span> <span class="n">Area</span> <span class="k">as</span> <span class="n">CircleArea</span>

<span class="n">side</span> <span class="o">=</span> <span class="mi">4</span>
<span class="n">SquareArea</span><span class="p">()</span><span class="o">.</span><span class="n">calculate</span><span class="p">(</span><span class="n">side</span><span class="p">);</span>

<span class="n">radius</span> <span class="o">=</span> <span class="mi">4</span>
<span class="n">CircleArea</span><span class="p">()</span><span class="o">.</span><span class="n">calculate</span><span class="p">(</span><span class="n">radius</span><span class="p">);</span>
</code></pre></div>

<p>For example, in JavaScript:</p>
<div class="codehilite"><pre><span></span><code><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">Area</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="nx">SquareArea</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s2">"./shapes/square"</span><span class="p">;</span>
<span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">Area</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="nx">CircleArea</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s2">"./shapes/circle"</span><span class="p">;</span>

<span class="kd">const</span><span class="w"> </span><span class="nx">side</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">4</span>
<span class="ow">new</span><span class="w"> </span><span class="nx">SquareArea</span><span class="p">().</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">side</span><span class="p">);</span>

<span class="kd">const</span><span class="w"> </span><span class="nx">radius</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">4</span>
<span class="ow">new</span><span class="w"> </span><span class="nx">CircleArea</span><span class="p">().</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">radius</span><span class="p">);</span>
</code></pre></div>

<p>Being able to split your code neatly into smaller files also makes maintaining code easier.</p>
<h2 id="they-are-both-interpreted">They are both interpreted</h2>
<p>Interpreted languages like Python and JavaScript do not have to compile before they are run, making <a href="https://en.wikipedia.org/wiki/Rapid_application_development" title="Rapid Application Development — Wikipedia">rapid application development (RAD)</a> possible. No building is required at all<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>.</p>
<p>For Python, restart <code>python</code>. For JavaScript, refresh the browser.</p>
<h2 id="they-both-have-repls">They both have REPLs</h2>
<p><a href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop" title="Read-eval-print loop — Wikipedia">REPL</a> stands for <strong>read-eval-print loop</strong>. It's pretty much a computer programming environment where you can:</p>
<ul>
<li>put in commands (i.e. the computer <em>reads</em> the command)</li>
<li>press <kbd>Enter</kbd> on your keyboard (i.e. you request the computer to process the input)</li>
<li>wait for the computer to process what you put in (i.e. the computer <em>evaluates</em> the command)</li>
<li>wait for the computer to show the results on your screen (i.e. the computer <em>prints</em> the results it got)</li>
</ul>
<p>This is basically how a <a href="https://en.wikipedia.org/wiki/Shell_(computing)" title="Shell — Wikipedia"><em>shell</em></a> works.</p>
<p>This makes debugging and testing so easy and quick because you don't have restart the entire program each time. I love this feature and it really comes in handing when writing websites, even this blog.</p>
<p>For Python, you would just call the <code>python</code> command to enter the Python shell. Then you can type commands as you like:</p>
<div class="codehilite"><pre><span></span><code><span class="err">$</span> <span class="n">python</span>
<span class="o">&gt;&gt;&gt;</span> <span class="kn">import</span><span class="w"> </span><span class="nn">this</span>

<span class="n">The</span> <span class="n">Zen</span> <span class="n">of</span> <span class="n">Python</span><span class="p">,</span> <span class="n">by</span> <span class="n">Tim</span> <span class="n">Peters</span>

<span class="n">Beautiful</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">ugly</span><span class="o">.</span>
<span class="n">Explicit</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">implicit</span><span class="o">.</span>
<span class="n">Simple</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="nb">complex</span><span class="o">.</span>
<span class="n">Complex</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">complicated</span><span class="o">.</span>
<span class="n">Flat</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">nested</span><span class="o">.</span>
<span class="n">Sparse</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">dense</span><span class="o">.</span>
<span class="n">Readability</span> <span class="n">counts</span><span class="o">.</span>
<span class="n">Special</span> <span class="n">cases</span> <span class="n">aren</span><span class="s1">'t special enough to break the rules.</span>
<span class="n">Although</span> <span class="n">practicality</span> <span class="n">beats</span> <span class="n">purity</span><span class="o">.</span>
<span class="n">Errors</span> <span class="n">should</span> <span class="n">never</span> <span class="k">pass</span> <span class="n">silently</span><span class="o">.</span>
<span class="n">Unless</span> <span class="n">explicitly</span> <span class="n">silenced</span><span class="o">.</span>
<span class="n">In</span> <span class="n">the</span> <span class="n">face</span> <span class="n">of</span> <span class="n">ambiguity</span><span class="p">,</span> <span class="n">refuse</span> <span class="n">the</span> <span class="n">temptation</span> <span class="n">to</span> <span class="n">guess</span><span class="o">.</span>
<span class="n">There</span> <span class="n">should</span> <span class="n">be</span> <span class="n">one</span><span class="o">--</span> <span class="ow">and</span> <span class="n">preferably</span> <span class="n">only</span> <span class="n">one</span> <span class="o">--</span><span class="n">obvious</span> <span class="n">way</span> <span class="n">to</span> <span class="n">do</span> <span class="n">it</span><span class="o">.</span>
<span class="n">Although</span> <span class="n">that</span> <span class="n">way</span> <span class="n">may</span> <span class="ow">not</span> <span class="n">be</span> <span class="n">obvious</span> <span class="n">at</span> <span class="n">first</span> <span class="n">unless</span> <span class="n">you</span><span class="s1">'re Dutch.</span>
<span class="n">Now</span> <span class="ow">is</span> <span class="n">better</span> <span class="n">than</span> <span class="n">never</span><span class="o">.</span>
<span class="n">Although</span> <span class="n">never</span> <span class="ow">is</span> <span class="n">often</span> <span class="n">better</span> <span class="n">than</span> <span class="o">*</span><span class="n">right</span><span class="o">*</span> <span class="n">now</span><span class="o">.</span>
<span class="n">If</span> <span class="n">the</span> <span class="n">implementation</span> <span class="ow">is</span> <span class="n">hard</span> <span class="n">to</span> <span class="n">explain</span><span class="p">,</span> <span class="n">it</span><span class="s1">'s a bad idea.</span>
<span class="n">If</span> <span class="n">the</span> <span class="n">implementation</span> <span class="ow">is</span> <span class="n">easy</span> <span class="n">to</span> <span class="n">explain</span><span class="p">,</span> <span class="n">it</span> <span class="n">may</span> <span class="n">be</span> <span class="n">a</span> <span class="n">good</span> <span class="n">idea</span><span class="o">.</span>
<span class="n">Namespaces</span> <span class="n">are</span> <span class="n">one</span> <span class="n">honking</span> <span class="n">great</span> <span class="n">idea</span> <span class="o">--</span> <span class="n">let</span><span class="s1">'s do more of those!</span>
</code></pre></div>

<p>For JavaScript, you can inspect any element on the webpage by right-clicking and selecting <em>Inspect</em>, then switch over to the <em>Console</em> tab of your browser. From there, you can access the DOM:</p>
<div class="codehilite"><pre><span></span><code><span class="o">&gt;&gt;</span><span class="w"> </span><span class="nx">$0</span><span class="p">.</span><span class="nx">nodeName</span>
<span class="s2">"IMG"</span>
</code></pre></div>

<h2 id="they-both-used-for-the-web">They both are used for the web</h2>
<p>I like that I can write any program for the web using these languages (along with HTML and CSS). I just need to restart the server and/or refresh the browser to see my changes.</p>
<h2 id="they-both-used-for-the-web">They are easy to read</h2>
<p>Reading through some well-written Python and JavaScript code is very relaxing to the brain. Ideas can be expressed so neatly.</p>
<h2 id="they-both-use-weak-typing">They both use weak typing</h2>
<p><strong>Strong typing is not a language flaw at all, but in some contexts, it could be really distracting.</strong> I love languages where the chosen names by the programmer make the code more legible than using the types.</p>
<p><strong>In my experience, I only care about typing when I need to debug an issue. Also, splitting my code well into proper contexts makes types less useful.</strong></p>
<p>Here is an example of no typing with JavaScript:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">class</span><span class="w"> </span><span class="nx">BankAccount</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="kr">constructor</span><span class="p">(</span><span class="nx">owner</span><span class="p">,</span><span class="w"> </span><span class="nx">balance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">this</span><span class="p">.</span><span class="nx">owner</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">owner</span><span class="p">;</span>
<span class="w">    </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">balance</span><span class="p">;</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">deposit</span><span class="p">(</span><span class="nx">amount</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">amount</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">amount</span><span class="p">;</span>
<span class="w">      </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">owner</span><span class="si">}</span><span class="sb"> deposited $</span><span class="si">${</span><span class="nx">amount</span><span class="si">}</span><span class="sb">.`</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">withdraw</span><span class="p">(</span><span class="nx">amount</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">amount</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">amount</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="nx">amount</span><span class="p">;</span>
<span class="w">      </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">owner</span><span class="si">}</span><span class="sb"> withdrew $</span><span class="si">${</span><span class="nx">amount</span><span class="si">}</span><span class="sb">.`</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Insufficient funds or invalid amount.'</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">get</span><span class="w"> </span><span class="nx">balance</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="p">;</span>
<span class="w">  </span><span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Usage</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">account</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">BankAccount</span><span class="p">(</span><span class="s1">'Alice'</span><span class="p">);</span>
<span class="nx">account</span><span class="p">.</span><span class="nx">deposit</span><span class="p">(</span><span class="mf">100</span><span class="p">);</span>
<span class="nx">account</span><span class="p">.</span><span class="nx">withdraw</span><span class="p">(</span><span class="mf">40</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Balance: $</span><span class="si">${</span><span class="nx">account</span><span class="p">.</span><span class="nx">balance</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</code></pre></div>

<p>And strong typing with Typescript:</p>
<div class="codehilite"><pre><span></span><code><span class="kd">class</span><span class="w"> </span><span class="nx">BankAccount</span><span class="w"> </span><span class="p">{</span>
<span class="w">  </span><span class="k">private</span><span class="w"> </span><span class="nx">owner</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
<span class="w">  </span><span class="k">private</span><span class="w"> </span><span class="nx">balance</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>

<span class="w">  </span><span class="kr">constructor</span><span class="p">(</span><span class="nx">owner</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="nx">balance</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">this</span><span class="p">.</span><span class="nx">owner</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">owner</span><span class="p">;</span>
<span class="w">    </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">balance</span><span class="p">;</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">deposit</span><span class="p">(</span><span class="nx">amount</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="ow">void</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">amount</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">amount</span><span class="p">;</span>
<span class="w">      </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">owner</span><span class="si">}</span><span class="sb"> deposited $</span><span class="si">${</span><span class="nx">amount</span><span class="si">}</span><span class="sb">.`</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">withdraw</span><span class="p">(</span><span class="nx">amount</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="ow">void</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">amount</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">amount</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="nx">amount</span><span class="p">;</span>
<span class="w">      </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`</span><span class="si">${</span><span class="k">this</span><span class="p">.</span><span class="nx">owner</span><span class="si">}</span><span class="sb"> withdrew $</span><span class="si">${</span><span class="nx">amount</span><span class="si">}</span><span class="sb">.`</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span>
<span class="w">      </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Insufficient funds or invalid amount.'</span><span class="p">);</span>
<span class="w">    </span><span class="p">}</span>
<span class="w">  </span><span class="p">}</span>

<span class="w">  </span><span class="nx">get</span><span class="w"> </span><span class="nx">balance</span><span class="p">()</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">_balance</span><span class="p">;</span>
<span class="w">  </span><span class="p">}</span>
<span class="p">}</span>

<span class="c1">// Usage</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">account</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">BankAccount</span><span class="p">(</span><span class="s1">'Bob'</span><span class="p">);</span>
<span class="nx">account</span><span class="p">.</span><span class="nx">deposit</span><span class="p">(</span><span class="mf">200</span><span class="p">);</span>
<span class="nx">account</span><span class="p">.</span><span class="nx">withdraw</span><span class="p">(</span><span class="mf">50</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Balance: $</span><span class="si">${</span><span class="nx">account</span><span class="p">.</span><span class="nx">balance</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</code></pre></div>

<p>Which do you prefer to read? Which one makes sense faster?</p>
<h2 id="they-are-both-easy-to-teach">They are both easy to teach</h2>
<p><strong>Compared to lower-level languages like C and C++, Python and JavaScript are easier to become proficient in, as the programmer does not need to understand low-level concepts to get things done.</strong> For example, a knowledge of pointers does not help much in writing Python or JavaScript code.</p>
<p>Additionally, it makes it easier for programmers who already know C and C++ (like me) to learn. I also think this is why I appreciate the Python and JavaScript.</p>
<h2 id="they-both-have-clear-goals-and-domains">They both have clear goals and domains</h2>
<p>In the words of Guido van Rossum (the creator of Python):</p>
<blockquote class="quote" cite="https://www.instagram.com/reel/DIjv3G7NOYq/">
    <p>My goal is to make Python a language that is fun to use, and one that is so easy to learn that it brings the joy of programming to as many people as possible.</p>
</blockquote>

<p>JavaScript has the goal to be the language for the web.</p>
<p>Brendan Eich's goal for JavaScript was to create a lightweight, interpreted scripting language for the web that could make web pages interactive.</p>
<p>Python has many domains such as machine learning, web development, data science, automation, game development, embedded systems, finance and fintech, desktop applications and many more.</p>
<p>JavaScript, once again, has the web, though it has also been ported to many platforms with technologies like <a href="https://nodejs.org" title="Node JS — Node JS official website">Node</a>.</p>
<h2 id="they-both-are-easy-to-maintain">They both are easy to maintain</h2>
<p>Since they are easy to read and easy to write, they are also easy to maintain.</p>
<h2 id="they-both-are-easy-to-test">They both are easy to test</h2>
<p><strong>You can test either of them directly from shell</strong> (i.e. the terminal for Python and the web console for JavaScript). To test a function added to a class, you simply enter the shell, create an instance of the class and run the function.</p>
<h2 id="they-both-can-be-extended">They both can be extended</h2>
<p>If functionality is missing from the main libraries, Python can be extended with C, C++ and many other languages; JavaScript can be extended with <a href="https://webassembly.org/" title="WebAssembly — WebAssembly official website">WebAssembly</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components" title="Web Components — MDN Web Docs">web components</a>.</p>
<h2 id="they-both-have-a-plethora-of-libraries">They both have a plethora of libraries</h2>
<p>Not only do they have a lot of libraries, each one can be added to your project using a package manager: <code>pip</code> for Python and <code>npm</code> for JavaScript<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>.</p>
<h2 id="they-both-are-well-supported">They both are well supported</h2>
<p>They have strong communities that are willing to help and support you. Developer forums like <a href="https://www.stackoverflow.com" title="StackOverflow official website">Stack Overflow</a><sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup> are full of solutions.</p>
<h2 id="they-both-empower-the-entrepreneur">They both empower the entrepreneur</h2>
<p>As someone that wants to make money on the web someday, they both help my life quite a lot. It doesn't take much to get anything working quickly in these languages, depending on the tasks at hand of course.</p>
<h2>Bottom line</h2>
<p>If you are looking for languages that are easy to set up and get straight to it, look no further than Python and JavaScript. They can got you covered!</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>I know what <a href="/posts/build-step-obsession" title="Build step obsession — MMHQ">I've previously said about building</a>, but I don't think that <em>building</em> is bad. I think that <em>building on the web</em> is bad. Modifying web pages should be a breeze for me. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Once again, I'm not a fan of using many libraries but it's nice to know that the community has got your back, even if it's just for testing. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>Who still uses Stack Overflow when ChatGPT is around? <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Tue, 15 Jul 2025 16:22:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/why-i-like-python-and-javascript</guid>
    </item>
    <item>
      <title>Tithing</title>
      <link>https://www.mmhq.me/posts/tithing</link>
      <description><![CDATA[<p><picture><img alt="Man sitting on 10% sign" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/ten-percent.webp" srcset="/static/data/images/360w/ten-percent.webp 360w, /static/data/images/640w/ten-percent.webp 640w, /static/data/images/1080w/ten-percent.webp 1080w, /static/data/images/1280w/ten-percent.webp 1280w" title="Tithing"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Malachi-3-10/">
    <p>Bring ye all the tithes into the storehouse, that there may be meat in mine house, and prove me now herewith, saith the LORD of hosts, if I will not open you the windows of heaven, and pour you out a blessing, that there shall not be room enough to receive it.</p>
    <cite>Malachi 3:10, The Bible</cite>
</blockquote>

<p>This morning, I attended church (like I do on some Sundays) and was greeted with an interesting message. The title of the message was <a href="https://www.youtube.com/watch?v=UQg5_HNCXV4" title="Free Chapel OC Live">Storehouse</a>. In summary, the pastor was advising us to <a href="https://en.wikipedia.org/wiki/Tithes_in_Judaism" title="Tithes in Judaism - Wikipedia">tithe</a> regularly.</p>
<p>In this blog post, I would like to prove to you that tithing is <em>not</em> a Christian practice.</p>
<h2 id="the-origin-of-tithing">The origin of tithing</h2>
<p><a href="https://en.wikipedia.org/wiki/Tithes_in_Judaism" title="Tithes in Judaism - Wikipedia">Tithing</a> is giving 10% of whatever you make to God, or more specifically, the church.</p>
<p>The first time tithing was mentioned in the Bible was in the book of Genesis when <a href="https://www.kingjamesbibleonline.org/Genesis-14-1_14-24/" title="Abraham goes to war to save Lot">Abraham gave tithes of everything he recovered in war</a> to the <a href="https://en.wikipedia.org/wiki/Melchizedek" title="Melchizedek - Wikipedia">priest Melchizedek</a>:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-14-20/">
    <p>And blessed be the most high God, which hath delivered thine enemies into thy hand. And he gave him tithes of all.</p>
    <cite>Genesis 14:20, The Bible</cite>
</blockquote>

<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Hebrews-7-2/">
    <p>To whom also Abraham gave a tenth part of all; first being by interpretation King of righteousness, and after that also King of Salem, which is, King of peace;</p>
    <cite>Hebrews 7:2, The Bible</cite>
</blockquote>

<p>Abraham gave willingly at the time in gratitude for God delivering his cousin Lot back into his hands after he was kidnapped by some kings.</p>
<p>It became a law to the children of Israel when Moses brought the law from God to the people in Leviticus:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Leviticus-27-30/">
    <p>And all the tithe of the land, whether of the seed of the land, or of the fruit of the tree, is the LORD's: it is holy unto the LORD.</p>
    <cite>Leviticus 27:30, The Bible</cite>
</blockquote>

<p><strong>From this, we can establish that tithing is under the Mosaic Law.</strong></p>
<h2 id="christians-are-not-under-the-law">Christians are not under the law</h2>
<p>What does Paul say about the law?</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-10-4/">
    <p>For Christ is the end of the law for righteousness to every one that believeth.</p>
    <cite>Romans 10:4, The Bible</cite>
</blockquote>

<p>Christ <em>fulfilled</em> the law, which means we are no longer under the law, as he said in the book of Matthew:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Matthew-5-17/">
    <p>Think not that I am come to destroy the law, or the prophets: I am not come to destroy, but to fulfil.</p>
    <cite>Matthew 5:17, The Bible</cite>
</blockquote>

<p>Paul also says this:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-6-14/">
    <p>For sin shall not have dominion over you: for ye are not under the law, but under grace.</p>
    <cite>Romans 6:14, The Bible</cite>
</blockquote>

<p>The law was <em>never</em> for the Gentiles i.e. the Christians; it was only for the Jews.</p>
<p><strong>Christians are under God's grace through Christ. Our work as Christians is to believe Christ</strong>, Jesus said it himself:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/John-6-28_6-29/">
    <p>Then said they unto him, What shall we do, that we might work the works of God?</p>
    <p>Jesus answered and said unto them, This is the work of God, that ye believe on him whom he hath sent.</p>
    <cite>John 6:28-29, The Bible</cite>
</blockquote>

<p>Even <a href="https://brave.com/leo/" title="Brave Leo AI">Leo</a>, the Brave browser's AI assistant says:</p>
<blockquote class="scripture" cite="https://search.brave.com/search?q=who+was+supposed+to+tithe+in+the+bible&amp;source=web&amp;summary=1&amp;conversation=97a08c69fd99a6b9c7c637">
    <p>In the New Testament, Jesus and the apostles did not explicitly command Christians to tithe, but they did emphasize the importance of giving and stewardship.</p>
    <p>The practice of tithing is not explicitly required for Christians, but the principle of giving generously and joyfully is strongly encouraged.
</p>
    <cite>Leo, the Brave browser's AI assistant</cite>
</blockquote>

<h2 id="other-points-against-tithing">Other points against tithing</h2>
<h3 id="there-were-multiple-tithes-to-be-paid">There were multiple tithes to be paid, making it more than 10%</h3>
<p>The children of Israel were required to bring a second tithe to Jerusalem for celebration (<a href="https://www.kingjamesbibleonline.org/Deuteronomy-14-22_14-27/" title="Second tithe">Deuteronomy 14:22-27</a>) and a third tithe for the poor and needy (<a href="https://www.kingjamesbibleonline.org/Deuteronomy-14-28_14-29/" title="Third tithe">Deuteronomy 14:28-29</a> and <a href="https://www.kingjamesbibleonline.org/Deuteronomy-26-12/" title="Third tithe mentioned again">Deuteronomy 26:12</a>).</p>
<p>If Christians were to pay tithes, which tithe should we pay?</p>
<h3 id="tithes-were-never-paid-with-money">Tithes were never paid with money</h3>
<p>Tithes were a requirement for farmers and herdsmen. The Bible specifies that tithe should be given from agricultural produce and livestock, such as corn, oil, and oxen (see <a href="https://www.kingjamesbibleonline.org/Leviticus-27-30_27-32/" title="Tithes should be from produce and livestock">Leviticus 27:30-32</a>). People from other vocations, such as carpenters, fishermen, tax collectors, and craftsmen, were not required to tithe.</p>
<p>The children of Israel were never told to pay tithes with cash.</p>
<h2 id="so-never-give-to-the-church">So never give to the church?</h2>
<p>Of course you can, if you want. God loves a cheerful giver.</p>
<p>The only giving in the church that falls under willful giving is <em>offering</em>:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/2-Corinthians-9-7/">
    <p>Every man according as he purposeth in his heart, so let him give; not grudgingly, or of necessity: for God loveth a cheerful giver.</p>
    <cite>2 Corinthians 9:7, The Bible</cite>
</blockquote>

<p>If you want to take it a step up, you can <em>lend</em> to God instead:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Proverbs-19-17/">
    <p>He that hath pity upon the poor lendeth unto the LORD; and that which he hath given will he pay him again.</p>
    <cite>Proverbs 19:17, The Bible</cite>
</blockquote>

<h2 id="rebuttals-for-the-pastor">Rebuttals for the pastor</h2>
<p>These are all paraphrased quotes from the pastor and my responses.</p>
<h3>"We the church don't need your tithes!"</h3>
<p>Yes, you do. Stop lying on the pulpit! Actions deafen, words whisper. In other words, if you didn't need it, you wouldn't ask for it.</p>
<p>The book of Proverbs says you shouldn't give to the rich, so don't give to any church that says this.</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Proverbs-19-17/">
    <p>He that oppresseth the poor to increase his riches, and he that giveth to the rich, shall surely come to want.</p>
    <cite>Proverbs 22:16, The Bible</cite>
</blockquote>

<h3>"It shows you trust God with your finances!"</h3>
<p>There is no biblical backing for this statement. Just believe in Christ and rest.</p>
<h3>"Tithing is returning to God, the first of whatever He's blessed me with."</h3>
<p>Once again, there is no biblical backing for this statement.</p>
<h3>"You are not giving out of law, you are giving out of love."</h3>
<p>No, giving out of love is <em>offering</em>. Tithing is <em>lawful</em> giving.</p>
<h3>"God would never need my money."</h3>
<p>That's correct! So keep your money in your pocket or give to the poor instead.</p>
<h3>"It's testing humanity's faithfulness to him."</h3>
<p>No, it's not. Humans are not faithful, God is! That is why Christ had to come and die for our sins.</p>
<h3>"He's testing you, not tempting you. The enemy is tempting you to not pay tithes."</h3>
<p>Once again, there is no biblical backing for this statement.</p>
<h3>"When we don't give tithes, we are telling God we don't appreciate him giving to us."</h3>
<p>No biblical backing!</p>
<h3>"If you don't tithe, you are robbing God of the opportunity to bless you."</h3>
<p>No, you are not. The opposite is true because you are not operating under grace, you are under the law. If you are under the law, you will be judged by the law:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-2-12/">
    <p>For as many as have sinned without law shall also perish without law: and as many as have sinned in the law shall be judged by the law;</p>
    <cite>Romans 2:12, The Bible</cite>
</blockquote>

<h3>"Grace has a greater demand than the law."</h3>
<p>False. That is the antithesis of grace. The law tells us to do; grace reminds us of what God has done so we don't have to do anything ourselves.</p>
<h3>"I'm not giving out of routine, I'm giving out of response."</h3>
<p>No, you are not. If you are responding, you are responding under the law. Unless it is willful, which would make it an offering. Tithing is not willful, it is lawful.</p>
<h3>"He doesn't need it, we need it."</h3>
<p><a href="https://en.wikipedia.org/wiki/Freudian_slip" title="Freudian slip - Wikipedia">Freudian slip</a> — the church <em>does</em> need it.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>Give your money to the poor. Give offering to the church (if you like). Don't give tithes.</strong></p>
<p>But in the end, you can do whatever you want. 🤷‍♂️</p>]]></description>
      <pubDate>Sun, 30 Mar 2025 14:14:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/tithing</guid>
    </item>
    <item>
      <title>Goodbye, BEM</title>
      <link>https://www.mmhq.me/posts/goodbye-bem</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<p><strong><a href="https://www.getbem.com" title="BEM methodology - getbem.com">BEM</a> (Block-Element-Modifier) in CSS is an industry standard in web development;</strong> I know a lot of people who use it. I learned it, mastered it and started using it in my own projects.</p>
<p>However, like all systems and tools I've used, I started to question it. Was BEM really the prized <em>gem</em> that I've always thought it was?</p>
<p>In today's blog post, <strong>I would like to talk about <em>BEM</em>, why I used it, and why I don't use it anymore.</strong></p>
<h2 id="what-i-like-about-bem">What I like about BEM</h2>
<p>BEM was <em>magic</em> when I first discovered it. It solved a few issues:</p>
<ul>
<li>
<strong>Scoping</strong>: This is the number one problem it solves — <a href="https://github.com/jescalan/gps#scoping" title="Scoping - GPS - GitHub">scope leaks</a>. Scope leaks can cause your CSS to break in unpredictable ways.</li>
<li>
<strong>Name clashes</strong>: With BEM, you can rest assured that no two elements would have the same name on the same page.</li>
<li>
<strong>Readable</strong>: BEM names were easy to understand and to trace down in HTML.</li>
<li>
<strong>Less cascade conflicts</strong>: Because every element had a different name, a lot of conflicts disappeared.</li>
<li>
<strong>Modularity</strong>: Adding styles does not break existing styles.</li>
</ul>
<h2 id="what-i-hate-about-bem">What I hate about BEM</h2>
<p>With all the advantages listed above, I thought BEM was the perfect solution. Until I used it. Then I used it again. And again. And again.</p>
<p>Then I noticed a few shortcomings:</p>
<ul>
<li>
<strong>Long names</strong>: BEM names were just too long. And they only got longer and longer the more elements you add to your page. (Kinda like <em>O(n)</em> in <a href="https://medium.com/@tmakhlay2/what-is-o-n-big-o-notation-how-to-use-it-e3da8592ac0c" title="O(n) - Medium">algorithmic complexity</a> lingo.)</li>
<li>
<strong>Code is not DRY</strong>: <a href="https://github.com/jescalan/gps#dry-code" title="Dry code - GPS - GitHub">Don't Repeat Yourself</a> is important to all developers when it can be achieved. This should be <em>no exception</em>.</li>
<li>
<strong>Ugly code</strong>: Not only was the code long and repetitive, it was also unpleasing to look at.</li>
</ul>
<p>There was no cure for these issues; they are all <em>inherent</em> in BEM.</p>
<p>So you could imagine how elated (and surprised) I was to find a solution.</p>
<h2 id="introducing-gps">Introducing GPS</h2>
<p>As I was looking for a solution to the shortcomings of BEM, I stumbled upon an <a href="https://medium.com/@jescalan/bem-is-terrible-f421495d093a" title="'BEM Is Terrible' by Jeff Escalante - Medium">article</a> titled <em>BEM is terrible</em>.</p>
<p>In that article, <strong>the author introduced the concept of <em>GPS</em>: <em>Global, Page (or View), Section</em>.</strong> I have never heard of it, but I was intrigued to find out that it's a new system that could be better than BEM.</p>
<p>However, after reading the whole article, I discovered that the method is not new at all. In fact, it sounds more like how these technologies were <em>supposed</em> to be used.</p>
<p>In summary, <strong>the foundation of what he is saying is this:</strong></p>
<ul>
<li>Use IDs in CSS when you need to reference HTML elements that are unique (similar to every student in school having an ID).</li>
<li>Use class names in CSS when you need to reference HTML elements that will be repeated in the HTML document, or have a repeated style (similar to every student in school being grouped by classes).</li>
</ul>
<p>If you follow these principles, everything falls in line. I used to think that IDs were evil because of specificity, but this could not be further from the truth. CSS becomes more powerful when you learn to embrace its strengths.</p>
<h2 id="usage-examples-of-gps">Usage examples of GPS</h2>
<h3 id="my-blog">My blog</h3>
<p>With BEM, the code for my blog home page was looking like this</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"feed"</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span> <span class="na">class</span><span class="o">=</span><span class="s">"feed__item"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span> <span class="na">class</span><span class="o">=</span><span class="s">"feed__item"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span> <span class="na">class</span><span class="o">=</span><span class="s">"feed__item"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span> <span class="na">class</span><span class="o">=</span><span class="s">"feed__item"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<p>With GPS, you'd have something simpler:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"feed"</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">article</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">article</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<p>You see? Shorter names. Less bytes. Less cognitive load. More communication. No clutter. It's genius.</p>
<p>Now in CSS, instead of this with BEM:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">feed</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">feed__item</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>
</code></pre></div>

<p>I do this with GPS:</p>
<div class="codehilite"><pre><span></span><code><span class="p">#</span><span class="nn">feed</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">feed</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nt">article</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>
</code></pre></div>

<h3 a-clients-website="a-clients-website">A client's website</h3>
<p>Below is a simplified version of code I wrote for a client of mine using BEM:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary"</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Appointment summary<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart"</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__summary"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>2 services<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__summary__details"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"container"</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>$175.00<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"separator"</span> <span class="na">viewBox</span><span class="o">=</span><span class="s">"0 0 24 24"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__summary__details__duration"</span><span class="p">&gt;</span>
                        <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon icon--time"</span> <span class="na">viewBox</span><span class="o">=</span><span class="s">"0 0 24 24"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
                        <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>2 hr<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__summary__details__buttons"</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">button</span> <span class="na">class</span><span class="o">=</span><span class="s">"button--arrow-toggle"</span><span class="p">&gt;&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon icon--chevron-up"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">id</span><span class="o">=</span><span class="s">"book-appointment-mobile-button"</span> <span class="na">href</span><span class="o">=</span><span class="s">"booking-complete.html"</span> <span class="na">class</span><span class="o">=</span><span class="s">"button button--primary button--next button--book-appointment"</span><span class="p">&gt;</span>Book Appointment<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__services"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__services__service"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Wash and Blowdry<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>$55.00<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon icon--trash"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"appointment-summary__cart__services__service"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Jumbo Box Braids<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>$120.00<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon icon--trash"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">id</span><span class="o">=</span><span class="s">"book-appointment-button"</span> <span class="na">href</span><span class="o">=</span><span class="s">"booking-complete.html"</span> <span class="na">class</span><span class="o">=</span><span class="s">"button button--primary button--next button--book-appointment"</span><span class="p">&gt;</span>Book Appointment<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<p>Using GPS, a lot of complexity goes away:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"appointment-summary"</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Appointment summary<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"cart"</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"summary"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>2 services<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"summary-details"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"row"</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>$175.00<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"separator"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"summary-duration"</span><span class="p">&gt;</span>
                        <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon time"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
                        <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>2 hr<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"summary-buttons"</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">button</span> <span class="na">class</span><span class="o">=</span><span class="s">"arrow-toggle"</span><span class="p">&gt;&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon chevron-up"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
                    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">id</span><span class="o">=</span><span class="s">"book-appointment-mobile-button"</span>
                        <span class="na">href</span><span class="o">=</span><span class="s">"booking-complete.html"</span>
                        <span class="na">class</span><span class="o">=</span><span class="s">"button primary next book-appointment"</span><span class="p">&gt;</span>
                        Book Appointment<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
                <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"cart-services"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"service"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Wash and Blowdry<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>$55.00<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon trash"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"service"</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Jumbo Box Braids<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">span</span><span class="p">&gt;</span>$120.00<span class="p">&lt;/</span><span class="nt">span</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">svg</span> <span class="na">class</span><span class="o">=</span><span class="s">"icon trash"</span><span class="p">&gt;</span>...<span class="p">&lt;/</span><span class="nt">svg</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">a</span> <span class="na">id</span><span class="o">=</span><span class="s">"book-appointment-button"</span>
        <span class="na">href</span><span class="o">=</span><span class="s">"booking-complete.html"</span>
        <span class="na">class</span><span class="o">=</span><span class="s">"button primary next book-appointment"</span><span class="p">&gt;</span>
        Book Appointment<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<p>The CSS with BEM:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">appointment-summary</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary</span><span class="w"> </span><span class="nt">h2</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>

<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary</span><span class="w"> </span><span class="nt">p</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary__details</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary__details</span><span class="w"> </span><span class="p">.</span><span class="nc">container</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary__details</span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">icon</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">icon--chevron-up</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary__details__duration</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary__details__duration</span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__summary__details__buttons</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__services</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__services__service</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__services__service</span><span class="w"> </span><span class="nt">p</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">appointment-summary__cart__services__service</span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>
</code></pre></div>

<p>With GPS:</p>
<div class="codehilite"><pre><span></span><code><span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="nt">h2</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">cart</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary</span><span class="w"> </span><span class="nt">p</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary-details</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary-details</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="p">.</span><span class="nc">row</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary-details</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">.</span><span class="nc">icon</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">.</span><span class="nc">chevron-up</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary-duration</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary-duration</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">summary-buttons</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">services</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">services</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="p">.</span><span class="nc">service</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">services</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="p">.</span><span class="nc">service</span><span class="w"> </span><span class="nt">p</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>

<span class="p">#</span><span class="nn">appointment-summary</span><span class="w"> </span><span class="p">#</span><span class="nn">services</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="p">.</span><span class="nc">service</span><span class="w"> </span><span class="nt">span</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* CSS styles here */</span>
<span class="p">}</span>
</code></pre></div>

<p>There you have it. Shorter. Simpler. Clearer. 😄</p>
<h2 id="few-criticisms-on-gps">Few criticisms on GPS</h2>
<p>One thing I dislike about GPS is the recommendation of prefixes like <code>g-</code> for <em>global styles</em> and <code>p-</code> for <em>page styles</em>. I believe that prefixes are unnecessary, superfluous and make my CSS a little less readable.</p>
<p>I think the best thing is to allow these styles to be <em>inferred</em> by their context.</p>
<p>For instance, an About page may be structured like this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">body</span> <span class="na">id</span><span class="o">=</span><span class="s">"about"</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"intro"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">"images/our-team.webp"</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">"g-full-width"</span><span class="p">&gt;</span>Meet our team<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span>
</code></pre></div>

<p>The <code>g-</code> in <code>g-full-width</code> indicates that the values are read from the global styles.</p>
<p>However, I would argue that there is no difference between defining the selector as <code>full-width</code> (as opposed to <code>g-full-width</code>). I should not really care about where the value comes from. If I wanted to overwrite the value for some reason, I could use IDs to do so:</p>
<div class="codehilite"><pre><span></span><code><span class="c">/* In global CSS */</span>
<span class="p">.</span><span class="nc">full-width</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* Full width in global context */</span>
<span class="p">}</span>

<span class="c">/* In page CSS */</span>
<span class="p">#</span><span class="nn">about</span><span class="w"> </span><span class="p">.</span><span class="nc">full-width</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="c">/* Full width in about page context */</span>
<span class="p">}</span>
</code></pre></div>

<p>I've never tried this before, but I plan to give it a shot and see if I run into any roadblocks. I believe this is a much simpler approach and could make my CSS code even <em>more</em> readable.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>It's sad how I overlooked the basic principles of the web and dabbled into something that made using the web harder. 🤦</p>
<p>Oh well, I'm happy to have found a way that works best for me. 😄</p>]]></description>
      <pubDate>Fri, 28 Feb 2025 14:14:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/goodbye-bem</guid>
    </item>
    <item>
      <title>True love</title>
      <link>https://www.mmhq.me/posts/true-love</link>
      <description><![CDATA[<p><picture><img alt="Silhouette of a person with a glowing red neon heart in the dark, symbolizing love" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/glowing-heart.webp" srcset="/static/data/images/360w/glowing-heart.webp 360w, /static/data/images/640w/glowing-heart.webp 640w, /static/data/images/1080w/glowing-heart.webp 1080w, /static/data/images/1280w/glowing-heart.webp 1280w" title="Glowing heart"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/John-3-16/">
    <p>For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life.</p>
    <cite>John 3:16, The Bible</cite>
</blockquote>

<p>The only thing I hate more than recording my own singing is releasing the audio to the public. But I love Jesus so I had to drop this.</p>
<p>Best you listen on mute 😜. (You've been warned. 😏)</p>
<p><audio controls=""><source src="/static/data/audio/me-singing-differences.mp3" type="audio/mp3"><a href="/static/data/audio/me-singing-differences.mp3">Me singing Differences by Ginuwine</a></audio></p>
<blockquote class="quote" cite="https://genius.com/Ginuwine-differences-lyrics">
<pre class="lyrics">
My whole life has changed
Since you came in, I knew back then
You were that special one
I'm so in love, so deep in love
You made my life complete
You are so sweet, no one competes
Glad you came into my life
You blind me with your love
With you I have no sight
</pre>
    <cite>Ginuwine, from his song <em>Differences</em></cite>
</blockquote>

<p>Please listen to the <a href="https://www.youtube.com/watch?v=Ry5vYkaeRpo" title="Differences by Ginuwine - YouTube">original song</a> when you can. Ginuwine is a R&amp;B genius 🎶! </p>
<h2>The bottom line</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/1-John-4-19/">
    <p>We love him, because he first loved us.</p>
    <cite>1 John 4:19, The Bible</cite>
</blockquote>]]></description>
      <pubDate>Fri, 14 Feb 2025 09:07:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/true-love</guid>
    </item>
    <item>
      <title>My return to chess</title>
      <link>https://www.mmhq.me/posts/my-return-to-chess</link>
      <description><![CDATA[<p><picture><img alt="A chess board with the chess pieces in start position" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/chess.webp" srcset="/static/data/images/360w/chess.webp 360w, /static/data/images/640w/chess.webp 640w, /static/data/images/1080w/chess.webp 1080w, /static/data/images/1280w/chess.webp 1280w" title="Chess"></picture></p>
<blockquote class="quote" cite="https://www.superprof.com/blog/game-play-chess-strategy-planning">
    <p>Chess is a war over the board. The object is to crush the opponent's mind.</p>
    <cite>Bobby Fischer, chess grandmaster</cite>
</blockquote>

<details>
    <summary>Poem: <em>Battle ready</em></summary>
<pre class="poem">
The pawns are pushed, the bishops set,
The horses out the stall;
A castled king, a centered queen,
The rooks ready for war.
</pre>
</details>

<p>Back in college, I played lots of chess. I would play with my fellow college mates for fun when there were power outages during the day (which happened a lot back in my home country, Nigeria).</p>
<p>Ever since I've left college, I've played chess on and off. I would go to meetups (through <a href="https://meetup.com" title="Meetup.com official website">meetup.com</a>) to play with random people and get floored every time. I tried playing online for a while, but I prefer over-the-board games. I like to hold the pieces, see the board fully, and look my opponents in the eye. Without all that, are you really playing chess?</p>
<p><strong>A friend of mine recently asked me to join <a href="https://chess.com" title="Chess.com official website">chess.com</a>.</strong> I was reluctant at first because I don't like to play online. Plus, if I was going to play online, I would rather play on matches on <a href="https://lichess.org" title="Lichess Official Website">lichess</a> instead, since it's open-source. However, after we spoke on the phone, I was convinced to try it out.</p>
<p>But first, I had to fix the <em>over-the-board</em> issue.</p>
<h2 id="electronic-chess">Electronic chess</h2>
<p>I don't like playing chess on a flat board (on a flat screen) so I had to find a solution online.</p>
<p>After a little googling, I stumbled upon <a href="https://playchessup.com/" title="Chess Up 2 official website">Chess Up 2</a> and <a href="https://www.chessnutech.com/" title="Chessnut Evo official website">Chessnut Evo</a>. Both are electronic chessboards for playing chess online and offline. What's special about these chessboards is that they have built-in screens and chess squares that light up. They both looked pretty good in the YouTube videos I watched.</p>
<p><strong>After little contemplation, I purchased the Chess Up 2 board.</strong> I was skeptical at first, because I didn't know how much I'd like it. I was even more skeptical when I received the first board because it didn't work properly. None of the squares lit up, but the built-in screen seemed to work.</p>
<p>I had to contact Bryght Labs (i.e. the makers of Chess Up 2) via email. After a little back and forth, they sent me a brand new board and voila! Everything worked!</p>
<p>I've used the device for a couple days now, and I can say that it's money well spent. I like all the features of the board and the fact that I could play online games with it. I can play AI and even get AI to assist me against AI opponents. I never knew I would love chess again this much.<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></p>
<p><picture><img alt="White king checkmated on a Chess Up 2 board by black with some squares lit up" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/pxl-chess-up-2.webp" srcset="/static/data/images/360w/pxl-chess-up-2.webp 360w, /static/data/images/640w/pxl-chess-up-2.webp 640w, /static/data/images/1080w/pxl-chess-up-2.webp 1080w, /static/data/images/1280w/pxl-chess-up-2.webp 1280w" title="Chess Up 2"></picture></p>
<h2 id="using-the-chessboard-element">Using the chessboard element</h2>
<p>The next step was to blog about my new (or should I say <em>resurrected</em>) hobby. I want to share the games I play so I (and everyone that visits this blog) could watch them again and again.</p>
<p><strong>I learned about the <a href="https://justinfagnani.github.io/chessboard-element" title="chessboard-element official website"><code>&lt;chess-board&gt;</code></a> web component and I was blown away!</strong> It's an <a href="https://github.com/justinfagnani/chessboard-element" title="chessboard-element on GitHub">open-source</a>, custom HTML element that displays a chessboard on a web page. I coupled that with the <a href="https://github.com/jhlywa/chess.js" title="chess.js on GitHub">chess.js</a> module and created a way to display my games.</p>
<p>So after I played my first online game with my friend, I downloaded the <a href="https://en.wikipedia.org/wiki/Portable_Game_Notation" title="Portable Game Notation - Wikipedia">Portable Game Notation (PGN)</a> file from the chess.com Android app and sent it to my computer. I parsed all the moves and loaded them into a JS array, then I created a class called <code>ChessGame</code> that handles everything for me. <code>ChessGame</code> combines the display of <code>&lt;chessboard-element&gt;</code> and the logic of <code>chess.js</code> to bring my games to life.</p>
<p>The JS file for this page looks something like this:</p>
<div class="codehilite"><pre><span></span><code><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">ChessGame</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s2">"../common/chess-game.js"</span><span class="p">;</span>

<span class="kd">const</span><span class="w"> </span><span class="nx">moves</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[...];</span><span class="w"> </span><span class="c1">// An array of moves</span>

<span class="kd">const</span><span class="w"> </span><span class="nx">board</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">"#board"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">game</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">ChessGame</span><span class="p">(</span><span class="nx">board</span><span class="p">,</span><span class="w"> </span><span class="nx">moves</span><span class="p">);</span>

<span class="kd">const</span><span class="w"> </span><span class="nx">backButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">"#back-button"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">nextButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">"#next-button"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">resetButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">"#reset-button"</span><span class="p">);</span>
<span class="kd">const</span><span class="w"> </span><span class="nx">flipButton</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">"#flip-button"</span><span class="p">);</span>

<span class="nx">backButton</span><span class="p">.</span><span class="nx">onclick</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">game</span><span class="p">.</span><span class="nx">undoMove</span><span class="p">();</span>
<span class="nx">nextButton</span><span class="p">.</span><span class="nx">onclick</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">game</span><span class="p">.</span><span class="nx">makeMove</span><span class="p">();</span>
<span class="nx">resetButton</span><span class="p">.</span><span class="nx">onclick</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">game</span><span class="p">.</span><span class="nx">reset</span><span class="p">();</span>
<span class="nx">flipButton</span><span class="p">.</span><span class="nx">onclick</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nx">game</span><span class="p">.</span><span class="nx">flipBoard</span><span class="p">();</span>
</code></pre></div>

<p>With this, I can display games that I've played and allow users to see every move played by me and my opponent.</p>
<h2 id="my-first-online-game">My first online game</h2>
<p>Here's my first online game against my friend that convinced me to join chess.com. I played as black in this game.</p>
<p>I commented on some of the moves. Feel free to playback the game till the end.</p>
<p><chess-board id="board" position="start" orientation="black"></chess-board></p>
<div class="center">
    <button id="back-button">←</button>
    <button id="next-button">→</button>
    <button id="reset-button">↺</button>
    <button id="flip-button">⇵</button>
</div>
<p id="commentary"></p>

<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>It's not without its faults. Sometimes I try to play a bot on chess.com and the board loads forever. Resetting the device usually fixes the issue. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Thu, 13 Feb 2025 22:15:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/my-return-to-chess</guid>
    </item>
    <item>
      <title>Longevity</title>
      <link>https://www.mmhq.me/posts/longevity</link>
      <description><![CDATA[<p><picture><img alt="Meditating monk nature surrounded by history" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/longevity.webp" srcset="/static/data/images/360w/longevity.webp 360w, /static/data/images/640w/longevity.webp 640w, /static/data/images/1080w/longevity.webp 1080w, /static/data/images/1280w/longevity.webp 1280w" title="Longevity"></picture></p>
<blockquote class="quote" cite="https://genius.com/Jimmy-smith-jimmy-smith-rap-lyrics">
    <p>Jazz is the only real music that is gonna last; all that other bullshit is here today and gone tomorrow.</p>
    <cite>Jimmy Smith, jazz organist</cite>
</blockquote>

<p>A quote from Jimmy Smith that I heard from the last track of Drake's album <em>Nothing Was The Same</em> got me thinking about how many unique contexts the idea could fit in.</p>
<p>The full original quote by Jimmy Smith was from his track <em>Jimmy Smith Rap</em> on his album <em>Off The Top</em>:</p>
<p><audio controls=""><source src="/static/data/audio/jimmy-smith-rap.mp3" type="audio/mp3"><a href="/static/data/audio/jimmy-smith-rap.mp3">Only jazz would last</a></audio></p>
<p>The sample from the Drake track called <em>Pound Cake/Paris Morton Music 2</em> alters it a bit to say "Only real music is gonna last; all that other bullshit is here today and gone tomorrow":</p>
<p><audio controls=""><source src="/static/data/audio/pound-cake-intro.mp3" type="audio/mp3"><a href="/static/data/audio/pound-cake-intro.mp3">Only real music will last</a></audio></p>
<p>Pretty much the same thing, but slightly edited. I think this applies to a variety of subjects, so here are my <em>derived</em> quotes 🕺🏾:</p>
<blockquote>
<p>The web is the only real platform that is gonna last; all that other bullshit is here today and gone tomorrow.</p>
</blockquote>
<p>Another one:</p>
<blockquote>
<p>Raw food is the only real medicine that is gonna last; all that other bullshit is here today and gone tomorrow.</p>
</blockquote>
<p>And finally:</p>
<blockquote>
<p>Jesus is the only real king that is gonna last; all that other bullshit is here today and gone tomorrow.</p>
</blockquote>
<p>I highly recommend listening to both albums, <a href="https://www.youtube.com/watch?v=kAsoZc7MFCg&amp;list=OLAK5uy_kRINftXw_QTiPPiJEAwgjZXEUJWn8_nJg&amp;index=2" title="Nothing Was The Same - Drake">Nothing Was The Same</a> and <a href="https://www.youtube.com/watch?v=lcgRZyEqVp8&amp;list=PLEyxWPyoryRLnEEHT21oyv4qBuXarylbt" title="Off The Top - Jimmy Smith">Off The Top</a> 🔥.</p>]]></description>
      <pubDate>Sun, 09 Feb 2025 02:04:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/longevity</guid>
    </item>
    <item>
      <title>Blog questions challenge 2025</title>
      <link>https://www.mmhq.me/posts/blog-questions-challenge-2025</link>
      <description><![CDATA[<p><picture><img alt="4 question mark paper cutouts pasted on paper shaped like speech bubbles placed on a table" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/questions.webp" srcset="/static/data/images/360w/questions.webp 360w, /static/data/images/640w/questions.webp 640w, /static/data/images/1080w/questions.webp 1080w, /static/data/images/1280w/questions.webp 1280w" title="Questions"></picture></p>
<p>A lot of bloggers that I follow have responded to the ultimate <em>Blog Questions Challenge</em> and I thought I would give it a go myself.</p>
<h2 id="why-did-you-start-your-blogging-in-the-first-place">Why did you start your blogging in the first place?</h2>
<p>Funny enough, this question was supposed to be what my first blog post answered, but at the time I had no idea, so I didn't make the <em>first blog post</em> post.</p>
<p>However, now I can say <strong>I blog to talk about observations and opinions I have concerning:</strong></p>
<ul>
<li>The web</li>
<li>Life events</li>
<li>Tech (of course)</li>
<li>The cosmos</li>
<li>Music</li>
<li>Poetry</li>
<li>Christian faith and religion</li>
<li>Random stuff</li>
</ul>
<p>I always allude to the fact that everything is just ramblings in my head that are trying to get out, and my blog is that outlet.</p>
<h2 id="what-platform-are-you-using-to-manage-your-blog">What platform are you using to manage your blog and why did you choose it?</h2>
<p><strong>I use a custom stack I like to call the FUN stack:</strong> it includes <a href="https://flask.palletsprojects.com" title="Flask official website">Flask</a>, <a href="https://uwsgi-docs.readthedocs.io/en/latest" title="uWSGI official documentation">uWSGI</a> and <a href="https://nginx.org" title="Nginx official website">Nginx</a>.</p>
<p>Flask is a micro-framework for building web applications in Python. uWSGI is a production-ready application server primarily used for deploying Python web applications. Nginx is a web server. Each of these technologies run on my Vultr Virtual Private Server (VPS).</p>
<p>So the flow is like this:</p>
<ol>
<li>I write my blog post in a Markdown file and upload it to the VPS (with <code>rsync</code>).</li>
<li>When a user visits my website, Nginx receives the request and forwards it to the uWSGI process.</li>
<li>uWSGI manages multiple websites that I run on my VPS (using <a href="https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html" title="Emperor - uWSGI">Emperor</a>). uWSGI forwards the request to the Flask application responsible for the website.</li>
<li>The Flask application pulls the data from the Markdown file, converts it to HTML and sends the full HTML page down the chain again until it gets back to the user.</li>
</ol>
<p>It may seem like a long process, but all of this happens in milliseconds. Everything else (like image resizing, image format conversion etc.) is handled by custom Bash scripts I wrote.</p>
<p><strong>I like this way of writing blog posts the most because:</strong></p>
<ul>
<li>I understand each part, making it simple to set up. Most of the setup requires configuration files that are set-and-forget.</li>
<li>Each of them is open-source and have been maintained for a long time.</li>
<li>I don't have to use CMSs and JS frameworks.</li>
<li>It's flexible, I can have it my way (like <a href="https://en.wikipedia.org/wiki/List_of_Burger_King_marketing_campaigns#The_Burger_King_jingle" title="Have it your way - Wikipedia">Burger King</a> 🍔).</li>
<li>There are <strong>NO BUILD STEPS</strong>! I just push to my server and reset the running processes. (I know, magic. 🤩)</li>
</ul>
<h2 id="have-you-blogged-on-other-platforms-before">Have you blogged on other platforms before?</h2>
<p>I used to blog on Google's Blogger back in 2016. I also tried to set up the Ghost blogging platform back in 2020. In both cases, I got distracted (which happens to me more often than I could count).</p>
<p>I'm happy that I don't use these platforms though; I love to own my data!</p>
<h2 id="how-do-you-write-your-posts">How do you write your posts?</h2>
<p>When I'm inspired to write, I open Markdown file template (that I created and customized myself) in my Vim text editor and let my fingers wiggle. I don't post it until I've read it a couple times and I'm satisfied with my editing. If I'm not satisfied enough, I let the post sit for a while until I get to that point. That could range from a few minutes to a few weeks.</p>
<h2 id="when-do-you-feel-most-inspired-to-write">When do you feel most inspired to write?</h2>
<p>Almost never 😜. Inspiration comes so randomly. It usually comes when I'm watching a YouTube video, or I'm reading a book, or I'm lost in thought.</p>
<p>To remedy this issue, I try to journal every morning to get me more into the spirit of writing.</p>
<h2 id="do-you-publish-immediately-after-writing">Do you publish immediately after writing, or do you let it simmer a bit as a draft?</h2>
<p>It depends on the post, but I'm more likely to let it simmer, especially if it's a pretty long post. I'm also not afraid to make updates to my posts after the first couple hours/days of release.</p>
<h2 id="whats-your-favorite-post-on-your-blog">What's your favorite post on your blog?</h2>
<p>None; I hate them all equally 🙃.</p>
<h2 id="any-future-plans-for-your-blog">Any future plans for your blog?</h2>
<p>Yeah, I really need to work on my <a href="/about" title="My About page">About</a> page and the frequency of posting. I also want to add a couple new pages for the books I've read, what I'm doing now etc.</p>
<h2 id="why-do-you-write">Why do you write? Other than your blog, do you write long-form content elsewhere?</h2>
<p>I like to write because:</p>
<ul>
<li>I like to express my opinions and observations. It is very liberating. It makes me process my thoughts better and helps me to get better at expressing my thoughts for people to understand, a very important quality for a webmaster to possess.</li>
<li>People can tell me I'm wrong when I'm wrong, or just criticize me in general. I'm not an <em>island of knowledge</em>; I think that the feedback from visitors can really help me to see the world in new ways.</li>
</ul>
<p>I don't write long form content anywhere else (for now).</p>]]></description>
      <pubDate>Thu, 06 Feb 2025 00:16:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/blog-questions-challenge-2025</guid>
    </item>
    <item>
      <title>SQLite ain't that bad</title>
      <link>https://www.mmhq.me/posts/sqlite-aint-that-bad</link>
      <description><![CDATA[<p><picture><img alt="Computer code on a computer monitor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/computer-code.webp" srcset="/static/data/images/360w/computer-code.webp 360w, /static/data/images/640w/computer-code.webp 640w, /static/data/images/1080w/computer-code.webp 1080w, /static/data/images/1280w/computer-code.webp 1280w" title="Code"></picture></p>
<details>
    <summary>Poem: <em>SQLite ain't bad</em></summary>
<pre class="poem">
<em>SQLite</em> is not so bad
It has a couple perks
But so does every other file —
Be sure to use what works
</pre>
</details>

<p>With all my <a href="/posts/sqlite-vs-filesystem" title="SQLite vs filesystem">recent mentions</a> of <a href="/posts/the-evil-of-sql" title="The evil of S(e)Q(ue)L">SQL</a>, the title may seem clickbait-y or a little tongue-in-cheek, but I mean it: SQLite is not all that bad.</p>
<p>How did I come to this new conclusion? I read an <a href="https://avi.im/blag/2024/sqlite-facts/" title="SQLite facts">article</a> of course. It speaks about some of the superpowers of SQLite and to be honest, I was impressed. Here are a few:</p>
<ul>
<li>Data is stored on a single file. (I've always known this, but the article reminds me of how big of advantage it is.)</li>
<li>Data access is relatively fast when compared to the file system.</li>
<li>It uses weak typing, making it throw errors less and easier to adapt by beginners.</li>
<li>It accepts JSON now.</li>
<li>There is a workaround for its read/write locking nowadays.</li>
</ul>
<p>However, with all that said, I still believe that we have to choose the tools we use carefully. SQLite would not always be the <em>best</em> solution; sometimes a simple text/JSON/CSV file would suffice. Every situation should be carefully examined before you make a decision.</p>
<p>Moreover, most of the time the decision you make can always be changed; there are many ways to convert SQLite data to other forms and vice versa.</p>
<p>For me, I will stick to using the file system for most of the websites I run, since I don't have a lot of files to store. However, for my clients that I design websites for, I most likely would use SQLite as it makes the development process a little easier. I get the added benefit that all their data is in a <em>single</em> file. (It sounds kinda eerie if I keep repeating that to myself.😨)</p>
<p>Bottom line? Use what you need when you need it.</p>]]></description>
      <pubDate>Sun, 19 Jan 2025 06:45:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/sqlite-aint-that-bad</guid>
    </item>
    <item>
      <title>Introducing Simon Says</title>
      <link>https://www.mmhq.me/posts/introducing-simon-says</link>
      <description><![CDATA[<p><picture><img alt="PS5 Gamepad" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/gamepad.webp" srcset="/static/data/images/360w/gamepad.webp 360w, /static/data/images/640w/gamepad.webp 640w, /static/data/images/1080w/gamepad.webp 1080w, /static/data/images/1280w/gamepad.webp 1280w" title="Games"></picture></p>
<blockquote class="scripture" cite="https://kidadl.com/facts/quotes/best-gaming-quotes-that-gamers-will-love">
    <p>A game is the complete exploration of freedom within a restrictive environment.</p>
    <cite>Vineet Raj Kapoor</cite>
</blockquote>

<p>Let my <em>web-game-creating career</em> begin 🥳!</p>
<p><strong>Today, I would like to present my first game for the web called <em>Simon Says</em></strong>, and I did it all using <a href="https://webcomponents.org/introduction" title="Introduction to Web Components - webcomponents.org">web components</a>.</p>
<p>Without further ado, let's just jump in.</p>
<h2 id="the-game">The game</h2>
<p>Here she is: the web game component <a href="https://www.youtube.com/watch?v=xV8TEXpru7I" title="Peter's boat - YouTube">more powerful than Superman, Batman, Spider-Man, and the Incredible Hulk put together</a>!</p>
<p>In <a href="https://en.wikipedia.org/wiki/Simon_Says" title="Simon Says - Wikipedia">Simon Says</a>, once the game starts, the <em>CPU</em> 🤖 will light up some boxes on the screen. <strong>Your objective is to tap the boxes that were lit up by the CPU 🤖, but you'll have to wait your turn to do so.</strong></p>
<p>This version of Simon Says resembles the <a href="https://en.wikipedia.org/wiki/Simon_(game)" title="Simon - Wikipedia">electronic version</a> more than the kids version.</p>
<p>You could see it more-or-less like a memory game — or a game of "<a href="https://empoweredparents.co/follow-the-leader-game/">follow the leader</a>"🚶‍♂️🚶‍♂️🚶‍♂️.</p>
<p><simon-says></simon-says></p>
<h2 id="a-little-history">A little history</h2>
<p>This is not my first time making this game. I made it back while I was in college <em>NOT</em> studying for my classes. I made the game in C++ with a <a href="https://en.wikipedia.org/wiki/Platform-independent_GUI_library" title="GUI library - Wikipedia">GUI framework</a> called <a href="https://qt.io" title="Qt framework - Qt official website">Qt</a>. I really wanted to make a game because I knew that was what C++ was mostly made for (at least so I thought).</p>
<p><strong>That project was successful but I ran into an issue: I lost all the code! How it happened doesn't matter. The whole incident proves why the web could be a better solution for (some) games.</strong> If I had the game online, maybe I would still be playing it by now; all I would need to do is host it.</p>
<p>That is definitely not the only reason <a href="https://developer.mozilla.org/en-US/docs/Games/Introduction#the_business_case" title="The business case - MDN">I prefer web to native game development</a>. Here are a couple more:</p>
<ul>
<li>
<strong>The web has no build steps.</strong> Goodbye to waiting for 2 hours of compilation for 2 lines of changes to source code.</li>
<li><strong>I can add games as part of any web page just by dropping a web component in.</strong></li>
<li>
<strong><em>You</em> can add games as part of your web pages by just copying and pasting my web component.</strong> (Don't worry, you couldn't go to jail even if I <em>wanted</em> to snitch 😉.)</li>
<li>
<strong>It's cross-platform.</strong> Players can use the browsers on their phones, laptops, desktops, tabs, smart TV, Raspberry Pis etc. to access web games.</li>
<li>
<strong>Everyone uses the web</strong>, making marketing and discoverability easy.</li>
<li>
<strong>I can update my game <em>whenever</em> I want.</strong> Players get the latest updates as long as they are online.</li>
<li><strong>I can send a link to anyone and they get instant access to the game.</strong></li>
<li>
<strong>I could get and control analytics if I want.</strong> (I don't.)</li>
<li>
<strong>The web is ubiquitous;</strong> you can play anywhere, anytime.</li>
</ul>
<h2 id="whyd-you-do-it">"Why'd you do it?"</h2>
<ul>
<li>To see if I could get web components working on my blog.</li>
<li>To see if I could build a full game using JavaScript without losing my sanity.</li>
<li>For fun.</li>
<li>To prove the simplicity involved in creating games for the web.</li>
</ul>
<h2 id="how-can-i-use-it-in-my-website">"How can I use it in my website?"</h2>
<p>Simple. Add this to your HTML page:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">"module"</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://mmhq.me/static/js/wc/simon-says/simon-says.js"</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">simon-says</span><span class="p">&gt;&lt;/</span><span class="nt">simon-says</span><span class="p">&gt;</span>
</code></pre></div>

<h2 id="future-plans">Future plans</h2>
<p>I plan to fix any bugs and to enhance it much more with animations and better scoring when I get the chance.</p>
<p>I also plan to make more game web components and display them all in an upcoming <em>Wall of Game</em>. Stay tuned!</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>I hope you have as much fun playing this game as I had making it.</strong></p>
<p>Feel free to send feedback via email of your the highest score or complaints, criticisms, comments, or compliments you have on your mind.</p>
<p>And yes of course, 3D games are coming next (in 2034 🙃).</p>]]></description>
      <pubDate>Mon, 16 Dec 2024 23:53:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/introducing-simon-says</guid>
    </item>
    <item>
      <title>Thoughts on TDD</title>
      <link>https://www.mmhq.me/posts/thoughts-on-tdd</link>
      <description><![CDATA[<p><picture><img alt="Person in a lab coat using a syringe to transfer a liquid" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/lab-test.webp" srcset="/static/data/images/360w/lab-test.webp 360w, /static/data/images/640w/lab-test.webp 640w, /static/data/images/1080w/lab-test.webp 1080w, /static/data/images/1280w/lab-test.webp 1280w" title="Testing"></picture></p>
<p><strong>I admit it; I used to hate testing.</strong> It never made any sense. Why would I want to write more code (test code, that is) when I already have code to write?</p>
<p>With time (and many years of force by the industry), I have learned to understand its importance and place in a software project. However, I have also learned to understand its abuse.</p>
<p>Let's take a look at a practice that is commonly abused, <em>TDD</em>.</p>
<h2 id="tdd-the-poster-child-of-software-development">TDD: the "poster child" of software development</h2>
<p>What is <a href="https://en.wikipedia.org/wiki/Test-driven_development" title="Test-driven development - Wikipedia">TDD</a>?</p>
<p>Another <em>method</em> that developers made to help you code slower and miss deadlines more often. <strong>TDD stands for Test-Driven Doom, oh wait, I mean Test-Driven Development</strong>, and it's all about telling you how your code is wrong and how you can stop whatever you are doing to make sure you are writing code correctly.</p>
<p>First off, <strong>you may think that the first objective is to write code, but really, your first objective is to write test code for code you haven't written yet.</strong> That is the proper way to write code.</p>
<p>Then after you write that code, make sure that the code <em>doesn't</em> pass. If it passes on first run, you are definitely doing it wrong. In fact, if it compiles on the first run you are one confused individual. You have to make sure it doesn't pass. Then you write the code for the test code you wrote earlier, then keep writing and correcting the code until it passes — then, and only then, have you completed TDD.</p>
<p>Of course, I'm being hyperbolic here, but you see my point.</p>
<h2 id="the-problem-with-tdd">The problem with TDD</h2>
<p>So as you may have noticed, TDD is not my cup of tea. It has a few shortcomings:</p>
<ul>
<li>
<strong>It's recommended for <em>every</em> project</strong>. I don't even think I'm exaggerating. Every <em>senior developer</em> swears that it works for every project (and can cure cancer) and I can testify that that's not true. Never have I looked at a failed project of mine and said, "Yup, this project would have been much better using TDD."</li>
<li>
<strong>It stifles tinkering, imagination and exploration.</strong> It causes me to do a lot of <em>upfront thinking</em>, which is not always a bad thing. However, if I'm dabbling into projects that I'm not too familiar with or I'm not sure of the full direction, I want to plan what I can plan on paper, then code at my computer. That way, I can just jump into code when I get on my computer.</li>
<li>
<strong>They claim it helps you to know how to start your project.</strong> However, in my experience, you have to do this for <em>every</em> project you ever encounter: you have to determine what code to write first. You don't need TDD to do this.</li>
<li>
<strong>They claim that it enforces good practices.</strong> I don't like the term "enforces" in this context. I believe every developer should have the <em>freedom</em> to do <em>whatever they want</em> to do when developing. And as for "good practices"; what encourages <em>good practices</em> is extensive coding i.e. you must code to be better at coding.</li>
</ul>
<h2 id="but-still-i-use-tdd">But still, I use TDD...</h2>
<p>It's ironic, I know. <strong>But sometimes it works. Just not every time.</strong></p>
<p>TDD purists would swear up and down that they <em>always</em> use TDD and <em>follow</em> the <em>laws of programming</em> to the T.</p>
<p>But let's be honest: the importance of practices like TDD are nowhere close to that of other practices and philosophies like <a href="https://en.wikipedia.org/wiki/KISS_principle" title="KISS principle - Wikipedia">KISS</a> (Keep It Simple Stupid), <a href="https://en.wikipedia.org/wiki/SOLID" title="SOLID - Wikipedia">SOLID</a>, or even <a href="https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it" title="You Ain't Gonna Need It - Wikipedia">YAGNI</a> (You Ain't Gonna Need It).</p>
<h2 id="but-most-times-i-dont">...but most times I don't</h2>
<p><strong>TDD is bad when it gets in the way of tinkering.</strong></p>
<p>There are times when I'm writing <em>experimental code</em>. Writing <em>test code</em> for <em>experimental code</em> is not wise as the code may be deleted later.</p>
<p>I consider most of the code I write as experimental; I don't know the final structure I would choose when I start writing code. Most times I just plan on paper and just jump into code right after: I don't see why I should do otherwise.</p>
<p>I'm not saying that you should not plan when writing code. I'm just saying that it is okay to <em>not</em> use TDD. Sometimes, I even write the tests after I finished writing the code. </p>
<p><strong>I guess the main problem with TDD for me is that I have to write test code for code that I'm not sure is going to stay in the project.</strong> That's <em>way</em> more code than I'm willing to write.</p>
<h2 id="what-is-the-alternative">What is the alternative?</h2>
<p>Simple. <strong>Write the code first, then write the test code.</strong> A foolproof solution that has been working for years for me. That way when I <em>do</em> write test code, it's more likely to <em>stay</em> in the codebase.</p>
<p>(I know, TDD purists would argue I deserve death by lethal injection for making such a claim but they're have to catch me first! 🙃)</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>I use TDD when:</p>
<ul>
<li>I already know exactly how the resulting API should look.</li>
<li>I'm in a corporate setting, where a lot of planning is done ahead of time.</li>
<li>I know how the new code would interact with the current codebase.</li>
<li>I'm adding features to an existing codebase (especially one where some tests have already been written).</li>
</ul>
<p>I don't when:</p>
<ul>
<li>I'm tinkering.</li>
<li>I want to be free and control how I write my software (which is <em>almost</em> always).</li>
</ul>
<p>In conclusion, <strong>don't let anyone tell you how to write code. Hone your craft; choose the practices that work for you.</strong></p>]]></description>
      <pubDate>Fri, 13 Dec 2024 11:23:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/thoughts-on-tdd</guid>
    </item>
    <item>
      <title>Programming is poetical science</title>
      <link>https://www.mmhq.me/posts/programming-is-poetical-science</link>
      <description><![CDATA[<p><picture><img alt="Laptop screen with code" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/coding.webp" srcset="/static/data/images/360w/coding.webp 360w, /static/data/images/640w/coding.webp 640w, /static/data/images/1080w/coding.webp 1080w, /static/data/images/1280w/coding.webp 1280w" title="Code"></picture></p>
<blockquote class="quote" cite="https://somethinkofvalue.com/ada-lovelace-quotes/">
    <p>If you can’t give me poetry, can’t you give me poetical science?</p>
    <cite>Ada Lovelace</cite>
</blockquote>

<p>Today I read a couple articles on <a href="https://en.wikipedia.org/wiki/Ada_Lovelace" title="Ada Lovelace - Wikipedia">Ada Lovelace</a>. She was the first programmer ever, which makes her the <em>grandfather</em> of my profession, programming 🤓 (a real G 😉). But she wasn't only a programmer, she was also a <em>prophet</em>.</p>
<p>Long before the formalization of universal computing by Alan Turing a century later, Ada predicted that <a href="https://historyoftheworlds.com/2024/11/20/adas-code-the-enigmatic-legacy-of-lovelace/" title="Ada's code - History of the Worlds">computers would be used to create music, generate graphics, and even perform tasks beyond just mathematical operations</a>.</p>
<p>What fascinated me about Ada Lovelace the most was the fact that she claimed that <a href="https://theconversation.com/scientists-and-poets-are-more-alike-than-you-might-think-116326" title="Scientists and Poets are More Alike Than You Might Think - The Conversation">her knowledge of poetry helped her to make that prediction</a>. She also coined the term <a href="https://www.jhunewsletter.com/article/2019/10/ada-lovelace-found-poetry-in-computer-algorithms" title="Ada Lovelace found poetry in computer algorithms">poetical science</a>.</p>
<h2 id="what-is-poetical-science">What is poetical science?</h2>
<p>Ada Lovelace didn't explicitly define the term <em>poetical science</em>, but she used the term to describe her unique approach to mathematics and science. She believed that <strong>imagination and insight can be paired with science to unlock new discoveries</strong>.</p>
<h2 id="how-is-programming-poetical-science">How is programming <em>poetical science</em>?</h2>
<blockquote class="quote" cite="https://en.wikiquote.org/wiki/Ada_Lovelace">
    <p>We may say most aptly that the Analytical Engine weaves algebraical patterns just as the Jacquard-loom weaves flowers and leaves.</p>
    <cite>Ada Lovelace, a display of her mastery of metaphor</cite>
</blockquote>

<p>Programming is essentially instructing a computer on what to do. However, like Ada described, when we program, we don't program by explicitly flipping switches on an electronic board (which is what essentially the transistors in all computers do); we program using a human-like language.</p>
<p>For instance, in object-oriented programming, we use <em>objects</em>. These objects are not real, just metaphors; they are representations of objects in real life. So a <em>file</em> in a program is not "a folder or box for holding loose papers", but a sequence of bytes that represents data in the system.</p>
<p>In Python, to <em>open</em> and <em>read</em> a text file called <code>doc.txt</code>, we could run the following code:</p>
<div class="codehilite"><pre><span></span><code><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"doc.txt"</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
</code></pre></div>

<p>Did you catch that? I said <em>open</em> and <em>read</em> even though the computer is just <em>manipulating</em> and <em>transforming</em> a sequence of bytes you call a <em>file</em>. It's all metaphor.</p>
<p><strong>When you call <code>open()</code>, you are not really <em>opening a file</em> or opening a folder with documents inside; you are <em>manipulating</em> some bytes. And when you call <code>read()</code>, you are not really <em>reading a file</em> or deciphering text on a sheet of paper in a folder; you are <em>transforming</em> bytes to alphanumeric characters and rendering them on a screen.</strong></p>
<p>As much as we think what we are doing as programmers is scientific, there is a lot of <em>poetry</em> that is mixed in.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>Looking from Ada's perspective, we can conclude that <strong>programmers are machine poets; we tell the computer sweet nothings in rhyme and meter and she rewards us with her virtual innards.</strong></p>
<p>It's nice to know that poetry lies at the very foundation of this art called programming; I need to read more Shakespeare to improve my coding skills 🙃.</p>]]></description>
      <pubDate>Sun, 08 Dec 2024 13:57:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/programming-is-poetical-science</guid>
    </item>
    <item>
      <title>New blog feature rollout</title>
      <link>https://www.mmhq.me/posts/new-blog-feature-rollout</link>
      <description><![CDATA[<p><picture><img alt="Plain pink background with paper cutout of rectangular speech bubble" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/comment.webp" srcset="/static/data/images/360w/comment.webp 360w, /static/data/images/640w/comment.webp 640w, /static/data/images/1080w/comment.webp 1080w, /static/data/images/1280w/comment.webp 1280w" title="New feature"></picture></p>
<blockquote class="scripture" cite="https://www.goodreads.com/quotes/568877-i-choose-a-lazy-person-to-do-a-hard-job">
    <p>I choose a lazy person to do a hard job. Because a lazy person will find an easy way to do it.</p>
    <cite>Bill Gates, founder of Microsoft</cite>
</blockquote>

<p>You may not have noticed, but my blog is missing <em>a lot of features</em> 😆. I am well aware of these omissions. They exist because I'm building this blog progressively: I add features as I need them.</p>
<p>Also, it doesn't help that I start all my HTML and CSS files for this blog from an blank page (as opposed to using various <em>often bloated</em> web frameworks and toolkits 🤮).</p>
<p>I do this because I prefer to learn every bit of the web without too many abstractions; abstractions can blind you from a lot of things. (It's part of what they are created to do.)</p>
<p><strong><em>So what is this blatantly missing feature that every blog should have?</em></strong> <strong>A comment section of course 😆!</strong></p>
<p>I need feedback so that I can have my ideas validated and challenged. I am willing to hear what anyone interested has to say.</p>
<h2>The plan</h2>
<p><strong>I planned to do it the lazy way.</strong></p>
<p>Since I lacked a comment section, <strong>I set up a separate email to respond to replies, comments, criticisms etc.</strong></p>
<p>Email has been supported by the web for such a long time that it was a no-brainer. Everybody has one these days, and it costs absolutely nothing. Sounds like an accessible medium to me 😉.</p>
<p>With this goal in mind, I had to make a couple changes to my website code.</p>
<h2>The HTML code</h2>
<p>The ease of the web is unfathomable sometimes. Sometimes, all it literally takes is <em>one line</em>:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">p</span> <span class="na">class</span><span class="o">=</span><span class="s">"reply-request"</span><span class="p">&gt;</span>If you would like to reply to or comment on this blog post, feel free to email me at <span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">"mailto:efe@mmhq.me?subject=Re: {{ post.title }}"</span><span class="p">&gt;</span>efe@mmhq.me<span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>.<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
</code></pre></div>

<p>That's it! Let's break it down:</p>
<ul>
<li>
<code>&lt;p&gt;</code>: Represents the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p" title="Paragraph element - MDN">paragraph element</a> in HTML and instructs the browser to create a new paragraph. The <code>class</code> attribute is set to <code>reply-request</code> so that it could be referenced in CSS. (More on that later.)</li>
<li>
<code>&lt;a&gt;</code>: Represents the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a" title="Anchor element - MDN">anchor element</a> in HTML and instructs the browser to create a new <a href="https://en.wikipedia.org/wiki/Hyperlink" title="Hyperlink - Wikipedia">hyperlink</a> or <em>link</em> for short. The magic here is what this specific link does. The key to its functionality is the <code>href</code> attribute's setting starting with <code>mailto</code>. (More on that later.)</li>
</ul>
<p>These two HTML elements are sufficient to add commenting the lazy way. <strong>Clicking on the link at the bottom of this page would <em>automagically</em> open your default email app with the subject title set to "Re: New blog feature rollout" and the email recipient set to my email, <em>efe@mmhq.me</em>.</strong></p>
<p><strong><em>How?</em></strong> <strong>With the magic of <a href="https://en.wikipedia.org/wiki/Mailto" title="mailto - Wikipedia"><code>mailto</code></a></strong>, or more specifically, <code>mailto:efe@mmhq.me?subject=Re: {{ post.title }}</code>. Let's break it down:</p>
<ul>
<li>
<code>mailto:</code>: A powerful <a href="https://en.wikipedia.org/wiki/Uniform_Resource_Identifier" title="Uniform Resource Locator - Wikipedia">URI</a> scheme for email addresses. This instructs the browser to open your email app when the link is clicked.</li>
<li>
<code>efe@mmhq.me</code>: The email address to send to.</li>
<li>
<code>?</code>: Syntax token that denotes the beginning of a query. The text after this would be read as a series of attribute-value pairs for the <code>mailto</code> scheme.</li>
<li>
<code>subject=</code>: An attribute for <code>mailto</code> called <code>subject</code>. Tells the browser to use whatever value that follows as the subject of the email.</li>
<li>
<code>Re: {{ post.title }}</code>: The subject of the email. <code>Re:</code> denotes that its a reply to a post, and <code>{{ post.title }}</code> is the <a href="https://jinja.palletsprojects.com/en/stable/templates/#variables" title="Variables - Jinja2">Jinja2</a> way of saying "Replace with my post title here". When the final HTML document is created on my server, the <code>{{ post.title }}</code> becomes the title of the blog post. (For example, <code>Re: New blog feature rollout</code> for this post you're currently reading.)</li>
</ul>
<p><em>Simple right?</em> With everything working almost perfectly<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>.</p>
<p>This is a known feature but not celebrated enough. It's not even new. This has been supported by browsers for a long time (maybe even since Web 1.0).</p>
<p>And this is why I love the web, I could be lazy and add this feature now until I am ready to finally upgrade to a <em>killer</em> comment section.</p>
<p>Till then, I can get back to what's important: 😴.</p>
<h2>The CSS code</h2>
<p>Not much was needed to style the added paragraph:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">reply-request</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">margin-block-start</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--space-l</span><span class="p">);</span>
<span class="w">    </span><span class="k">font-size</span><span class="p">:</span><span class="w"> </span><span class="nf">var</span><span class="p">(</span><span class="nv">--step--</span><span class="mi">1</span><span class="p">);</span>
<span class="w">    </span><span class="k">font-style</span><span class="p">:</span><span class="w"> </span><span class="kc">italic</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

<ul>
<li>
<code>.reply-request</code>: References the <code>&lt;p&gt;</code> element created in HTML.</li>
<li>
<code>margin-block-start: var(--space-l)</code>: Instructs the browser to set the top margin of the paragraph to my <em>large space</em> setting, a variable I've defined in my root <code>style.css</code> file.<sup id="fnref:2"><a class="footnote-ref" href="#fn:2">2</a></sup>
</li>
<li>
<code>font-size: var(--step--1)</code>: Instructs the browser to set the font size to <em>Step -1</em>, a variable I've set in my root <code>style.css</code> file. This sets the font to a size a little smaller than my base font size, <em>Step 0</em>.<sup id="fnref:3"><a class="footnote-ref" href="#fn:3">3</a></sup>
</li>
<li>
<code>font-style: italic</code>: Instructs the browser to render the text in italics.</li>
</ul>
<p>That's it! No JavaScript required 👌.</p>
<h2>Bottom line</h2>
<p><strong>Build progressively when you build for the web.</strong> It's a feature of the web, not a bug 🤩.</p>
<p>Your laziness is welcome 😄.</p>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>One issue I saw with this addition is that the added paragraph goes <em>under</em> the footer instead of on top. This happens only with blog posts with footnotes, like this one 😆. I plan to fix it some day, with a self-built Python Markdown extension on my server. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>I use <a href="https://utopia.fyi" title="Utopia - Fluid Responsive Design">Utopia</a> conventions BTW. <a class="footnote-backref" href="#fnref:2" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p><a href="https://utopia.fyi" title="Utopia - Fluid Responsive Design">Utopia</a> conventions yet again! <a class="footnote-backref" href="#fnref:3" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Thu, 05 Dec 2024 12:21:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/new-blog-feature-rollout</guid>
    </item>
    <item>
      <title>Eat the fruit</title>
      <link>https://www.mmhq.me/posts/eat-the-fruit</link>
      <description><![CDATA[<p><picture><img alt="Table of a variety of fruit, some whole, some cut open" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/fruit.webp" srcset="/static/data/images/360w/fruit.webp 360w, /static/data/images/640w/fruit.webp 640w, /static/data/images/1080w/fruit.webp 1080w, /static/data/images/1280w/fruit.webp 1280w" title="Rainbow of fruit"></picture></p>
<blockquote class="quote" cite="https://www.youtube.com/@OshayDukeJackson">
    <p>The buffoonery is at an all-time high.</p>
    <cite>O'shea Duke Jackson, YouTuber</cite>
</blockquote>

<p>I was shopping for some items at CVS today when I stumbled upon something surprising on the shelf. In the "Diet Needs" section for the store, there lied different supplements.</p>
<p>That's normal; I can understand if people need supplements. I personally take Vitamin D supplements because I can't get enough Vitamin D from the sun.</p>
<p>But what really shocked me was that I found supplements for fiber.</p>
<p>This may not seem like a big deal, but think about it: <strong><em>is there any other place you can get fiber from?</em></strong></p>
<p>Yes, there is. <strong>Fruits</strong>. <strong>Vegetables</strong>. <strong>Nuts</strong>. <strong>Seeds</strong>. All of which are very abundant on Planet Earth and needed by the body.</p>
<p>Yet, people are comfortable buying supplements for vitamins, minerals and nutrients that can easily (and preferably, if you ask the body) be absorbed from fruits, vegetables, nuts and seeds.</p>
<p>In other words:</p>
<blockquote>
<p>All you need to do is eat the fruit.</p>
</blockquote>
<p>You do not need to supplement everything. There are <strong>advantages of eating the fruit over supplements</strong>:</p>
<ul>
<li>
<strong>Fruits contain more that just fiber. They contain vitamins, minerals and nutrients your body would thank you for.</strong> The supplements just contain fiber, and some other chemicals I can't pronounce or have any clue what they are or what they look like. Let's not even talk about what it could possibly do to your body.</li>
<li>
<strong>It is hard to overdose on minerals and vitamins when you eat a variety of fruit.</strong> I do not advise eating more than the recommended dosage on the package of the supplements, but even if you don't, we all have different <em>biologies</em>; the way my body reacts to one supplement is different from yours, which is different from John Doe.</li>
<li>
<strong>Fruits just taste better.</strong> Pills barely have any taste, and the taste of gummies can't even be compared to the taste of an overripe banana.</li>
<li>
<strong>Fruits come in different colors and are aesthetically pleasing.</strong> I believe that their colors symbolize their function, sometimes. An example is beets — their red in color and they help to produce nitric oxide, which promotes blood flow. Don't ask me how I know. (Ask ChatGPT instead.)</li>
<li>
<strong>Fruits can be prepared in a variety of ways: as a smoothie, as juice, as jelly etc.</strong> allowing you to create your meal or beverage. Supplements are in their final form pretty much.</li>
</ul>
<p><strong>So forget the supplement pills and gummies. Eat the fruit. That's all you need.</strong></p>]]></description>
      <pubDate>Sat, 23 Nov 2024 20:22:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/eat-the-fruit</guid>
    </item>
    <item>
      <title>Dancing on the grave of Web SQL</title>
      <link>https://www.mmhq.me/posts/dancing-on-the-grave-of-web-sql</link>
      <description><![CDATA[<p><picture><img alt="Groups of men and women dancing with each other" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/dancing-crowd.webp" srcset="/static/data/images/360w/dancing-crowd.webp 360w, /static/data/images/640w/dancing-crowd.webp 640w, /static/data/images/1080w/dancing-crowd.webp 1080w, /static/data/images/1280w/dancing-crowd.webp 1280w" title="Dancing crowd"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-11-7_11-9/">
    <p>Go to, let us go down, and there confound their language, that they may not understand one another's speech.</p>
    <cite>Genesis 11:7, The Bible</cite>
</blockquote>

<p>I was wandering round the web recently and stumbled upon an article about the <a href="https://developer.chrome.com/blog/deprecating-web-sql" title="Deprecating Web SQL">death of Web SQL</a>. I couldn't ask for a better article.</p>
<p>In this blog post, I would like to <strong>dissect the downfall of <em>Web SQL</em>.</strong></p>
<h2 id="web-sql-almost-made-it">Web SQL almost made it</h2>
<p>Every other (relevant) browser had implemented Web SQL already. Google Chrome was first and then Safari. <strong>But there was one stubborn one: Mozilla.</strong> Thankfully, they stood out and said "No, thanks" to SQL.</p>
<p>Why? A couple reasons:</p>
<h3 id="there-were-many-implementations-of-sql">There were many implementations of SQL</h3>
<p>There is no true agreed-upon standard. This would cause frequent changes to APIs on the web, which is a horrible experience for developers and progressive learners (like me).</p>
<p>Imagine having to update your code every couple months because the standard changed, as opposed to once and never again. You might as well you JavaScript frameworks. 😒 </p>
<h3 id="it-suffered-from-callback-hell">It suffered from <em>callback hell</em>
</h3>
<p>I don't think we would miss code like this on the web (sometimes referred to as <a href="http://callbackhell.com/" title="Callback Hell">callback hell</a>):</p>
<div class="codehilite"><pre><span></span><code><span class="nx">openDatabase</span><span class="p">(</span>
<span class="w">  </span><span class="c1">// Name</span>
<span class="w">  </span><span class="s1">'mydatabase'</span><span class="p">,</span>
<span class="w">  </span><span class="c1">// Version</span>
<span class="w">  </span><span class="mf">1</span><span class="p">,</span>
<span class="w">  </span><span class="c1">// Display name</span>
<span class="w">  </span><span class="s1">'mydatabase'</span><span class="p">,</span>
<span class="w">  </span><span class="c1">// Estimated size</span>
<span class="w">  </span><span class="mf">5000000</span><span class="p">,</span>
<span class="w">  </span><span class="c1">// Creation callback</span>
<span class="w">  </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">db</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="nx">db</span><span class="p">.</span><span class="nx">transaction</span><span class="p">(</span>
<span class="w">      </span><span class="c1">// Transaction callback</span>
<span class="w">      </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">tx</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">        </span><span class="c1">// Execute SQL statement</span>
<span class="w">        </span><span class="nx">tx</span><span class="p">.</span><span class="nx">executeSql</span><span class="p">(</span>
<span class="w">          </span><span class="c1">// SQL statement</span>
<span class="w">          </span><span class="s1">'create table rainstorms (mood text, severity int)'</span><span class="p">,</span>
<span class="w">          </span><span class="c1">// Arguments</span>
<span class="w">          </span><span class="p">[],</span>
<span class="w">          </span><span class="c1">// Success callback</span>
<span class="w">          </span><span class="kd">function</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w">            </span><span class="c1">// Execute SQL statement</span>
<span class="w">            </span><span class="nx">tx</span><span class="p">.</span><span class="nx">executeSql</span><span class="p">(</span>
<span class="w">              </span><span class="c1">// SQL statement</span>
<span class="w">              </span><span class="s1">'insert into rainstorms values (?, ?)'</span><span class="p">,</span>
<span class="w">              </span><span class="c1">// Arguments</span>
<span class="w">              </span><span class="p">[</span><span class="s1">'somber'</span><span class="p">,</span><span class="w"> </span><span class="mf">6</span><span class="p">],</span>
<span class="w">              </span><span class="c1">// Success callback</span>
<span class="w">              </span><span class="kd">function</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w">                </span><span class="c1">// Execute SQL statement</span>
<span class="w">                </span><span class="nx">tx</span><span class="p">.</span><span class="nx">executeSql</span><span class="p">(</span>
<span class="w">                  </span><span class="c1">// SQL statement</span>
<span class="w">                  </span><span class="s1">'select * from rainstorms where mood = ?'</span><span class="p">,</span>
<span class="w">                  </span><span class="c1">// Arguments</span>
<span class="w">                  </span><span class="p">[</span><span class="s1">'somber'</span><span class="p">],</span>
<span class="w">                  </span><span class="c1">// Success callback</span>
<span class="w">                  </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">tx</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">                    </span><span class="c1">// Do something with the result</span>
<span class="w">                    </span><span class="kd">var</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">rows</span><span class="p">.</span><span class="nx">item</span><span class="p">(</span><span class="mf">0</span><span class="p">);</span>
<span class="w">                    </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span>
<span class="w">                      </span><span class="s1">'rainstorm severity: '</span><span class="w"> </span><span class="o">+</span>
<span class="w">                        </span><span class="nx">row</span><span class="p">.</span><span class="nx">severity</span><span class="w"> </span><span class="o">+</span>
<span class="w">                        </span><span class="s1">',  my mood: '</span><span class="w"> </span><span class="o">+</span>
<span class="w">                        </span><span class="nx">row</span><span class="p">.</span><span class="nx">mood</span><span class="p">,</span>
<span class="w">                    </span><span class="p">);</span>
<span class="w">                  </span><span class="p">},</span>
<span class="w">                </span><span class="p">);</span>
<span class="w">              </span><span class="p">},</span>
<span class="w">            </span><span class="p">);</span>
<span class="w">          </span><span class="p">},</span>
<span class="w">        </span><span class="p">);</span>
<span class="w">      </span><span class="p">},</span>
<span class="w">      </span><span class="c1">// Error callback</span>
<span class="w">      </span><span class="kd">function</span><span class="w"> </span><span class="p">(</span><span class="nx">err</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w">        </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Transaction failed!: '</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">err</span><span class="p">);</span>
<span class="w">      </span><span class="p">},</span>
<span class="w">      </span><span class="c1">// Success callback);</span>
<span class="w">      </span><span class="kd">function</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<span class="w">        </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Transaction succeeded!'</span><span class="p">);</span>
<span class="w">      </span><span class="p">},</span>
<span class="w">    </span><span class="p">);</span>
<span class="w">  </span><span class="p">},</span>
<span class="p">);</span>
</code></pre></div>

<p>Enough said.</p>
<h3 id="most-sql-implementations-end-up-buried-in-another-interface">Most SQL implementations end up buried in another interface</h3>
<p>After SQL is used as a foundation for your database architecture, a common pattern found among developers is to create another layer (e.g an object-relational model or <em>ORM</em>) or library over the SQL layer. In a case like this, it may benefit developers more if the API exposed was more high-level than raw SQL.</p>
<p>Working with a single layer is easier to maintain, instead of working with SQL and another layer on top of it.</p>
<h3 id="mozilla-failed-to-see-its-usefulness">Mozilla failed to see its usefulness</h3>
<p>Mozilla refused to implement the feature in Firefox stating:</p>
<blockquote cite="https://developer.chrome.com/blog/deprecating-web-sql">
    <p>"We don't think [SQLite] is the right basis for an API exposed to general web content, not least of all because there isn't a credible, widely accepted standard that subsets SQL in a useful way. Additionally, we don't want changes to SQLite to affect the web later, and don't think harnessing major browser releases (and a web standard) to SQLite is prudent."</p>
</blockquote>

<p>Wise words from a decent browser vendor.</p>
<h2 id="so-what-can-we-use-instead">So what can we use instead?</h2>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API" title="IndexedDB API - Mozilla Developer Network">IndexedDB</a> is the answer. I haven't really used it myself, but I don't think it would be more difficult than SQL.</p>
<p>Of course, for people that still want to use SQL, there is the <a href="https://developer.chrome.com/blog/sqlite-wasm-in-the-browser-backed-by-the-origin-private-file-system" title="Web SQL in WASM">WASM option available</a> maintained by the open-source community. 😒 </p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>If the web can cut out bloat, so can you. Get rid of something you don't need today.</p>
<p>Bloat always falls off like how Adobe Flash and Silverlight did on the web. <strong>Dispose of it before it sinks your ship.</strong></p>
<h2 id="more-resources">More resources</h2>
<ul>
<li>
<a href="https://web.archive.org/web/20090412154147/http://blog.vlad1.com/2009/04/06/html5-web-storage-and-sql/" title="Web Storage and SQL - Vladimir Vukićević's blog - Web Archive">Web Storage and SQL</a> - Vladimir Vukićević</li>
<li>
<a href="https://nolanlawson.com/2014/04/26/web-sql-database-in-memoriam/" title="Web SQL in Memoriam - Nolan Lawson">Web SQL in Memoriam</a> - Nolan Lawson</li>
<li>
<a href="https://www.w3.org/TR/IndexedDB/" title="W3 Working Draft for IndexedDB - w3.org">IndexedDB</a> - W3 working draft</li>
</ul>]]></description>
      <pubDate>Thu, 24 Oct 2024 11:07:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/dancing-on-the-grave-of-web-sql</guid>
    </item>
    <item>
      <title>Exciting features coming to the web</title>
      <link>https://www.mmhq.me/posts/exciting-features-coming-to-the-web</link>
      <description><![CDATA[<p><picture><img alt="Mac computer glowing in a dark room" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/glowing-mac-computer.webp" srcset="/static/data/images/360w/glowing-mac-computer.webp 360w, /static/data/images/640w/glowing-mac-computer.webp 640w, /static/data/images/1080w/glowing-mac-computer.webp 1080w, /static/data/images/1280w/glowing-mac-computer.webp 1280w" title="The new web"></picture></p>
<p>I watched a couple videos from the <a href="https://www.youtube.com/watch?v=WsEQjeZoEng" title="Google IO '24 - YouTube">Google I/O '24</a> on YouTube and had a blast. In this blog post, I would like to <strong>highlight some of the features</strong> that I learned about.</p>
<h2 id="the-new-features">The new features</h2>
<ul>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries" title="Container queries - MDN">Size container queries</a></p>
<ul>
<li>
<strong>What's it for:</strong> Used to apply styles to an element based on the size of the element's container</li>
<li>
<strong>Why I care:</strong> Can be used as an alternative to media queries</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:has" title=":has() - MDN"><code>:has()</code></a></p>
<ul>
<li>
<strong>What is it:</strong> Selector that targets elements based on whether they contain specific child elements or selectors</li>
<li>
<strong>Why I care:</strong> Easier way to select elements</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Subgrid" title="Subgrid - MDN">Subgrid</a></p>
<ul>
<li>
<strong>What's it for:</strong> Allows child elements to inherit a grid layout from their parent, creating a more flexible and efficient grid system</li>
<li>
<strong>Why I care:</strong> More control over the layout of child elements in a grid</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting" title="CSS nesting - MDN">CSS nesting</a></p>
<ul>
<li>
<strong>What's it for:</strong> Allows you to style elements within other elements, creating a more organized and efficient stylesheet</li>
<li>
<strong>Why I care:</strong> Shorter and better organized CSS code</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/search" title="Search element - MDN"><code>&lt;search&gt;</code></a></p>
<ul>
<li>
<strong>What is it:</strong> Custom element used to define a search field or input element</li>
<li>
<strong>Why I care:</strong> Better accessibility (no need to input ARIA to specify search elements)</li>
</ul>
</li>
<li>
<p>Responsive <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video" title="Video element - MDN"><code>&lt;video&gt;</code></a> (using <code>&lt;source&gt;</code>)</p>
<ul>
<li>
<strong>What's it for:</strong> Allows you to support various media types in the same video element (just like <code>&lt;audio&gt;</code>)</li>
<li>
<strong>Why I care:</strong> More control over <code>&lt;video&gt;</code>
</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inert" title="inert attribute - MDN"><code>inert</code> attribute</a></p>
<ul>
<li>
<strong>What is it:</strong> HTML attribute used to temporarily disable an element, preventing it from interacting with user events</li>
<li>
<strong>Why I care:</strong> Easy way to disable elements</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix" title="color-mix() - MDN"><code>color-mix()</code></a></p>
<ul>
<li>
<strong>What is it:</strong> CSS function used to blend multiple colors together, creating new colors based on specified mixing modes and ratios</li>
<li>
<strong>Why I care:</strong> More colors to mesmerize site visitors</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:user-valid" title=":user-valid - MDN"><code>:user-valid</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:user-invalid" title=":user-invalid - MDN"><code>:user-invalid</code></a></p>
<ul>
<li>
<strong>What is it:</strong> Pseudo-class used to style elements that have been marked as valid/invalid by the user</li>
<li>
<strong>Why I care:</strong> Easier form validation</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API" title="Compression streams - MDN">Compression streams</a></p>
<ul>
<li>
<strong>What is it:</strong> JavaScript objects that allow you to efficiently compress or decompress data in real-time, without having to buffer the entire data set in memory</li>
<li>
<strong>Why I care:</strong> Easier audio manipulation, when I eventually get the time</li>
</ul>
</li>
<li>
<p><a href="https://web.dev/articles/declarative-shadow-dom" title="Declarative shadow DOM - web.dev">Declarative shadow DOM</a></p>
<ul>
<li>
<strong>What is it:</strong> Method that allows developers to create a ShadowRoot without using JavaScript</li>
<li>
<strong>Why I care:</strong> Easier way to incorporate web components into my designs</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover" title="popover - MDN"><code>popover</code> attribute</a></p>
<ul>
<li>
<strong>What is it:</strong> Customizable overlay element that appears on top of the page, often used to display information or options</li>
<li>
<strong>Why I care:</strong> Can finally create tooltips, <a href="https://developer.android.com/reference/android/widget/Toast?hl=en" title="Toast - Android Developers">toasts</a>, <a href="https://developer.android.com/reference/com/google/android/material/snackbar/Snackbar" title="Snackbar - Android Developers">snackbars</a> and popups with ease (no more <code>z-index</code> battles!)</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_scroll-driven_animations" title="CSS scroll-driven animations - MDN">Scroll-driven animations</a></p>
<ul>
<li>
<strong>What is it:</strong> Animations that trigger or change based on the user's scrolling position on the page</li>
<li>
<strong>Why I care:</strong> Easy <a href="https://flourish.studio/blog/no-code-scrollytelling" title="Scrollytelling - Flourish">scrollytelling</a>, all handled in CSS</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API" title="View transitions API - MDN">View transitions</a></p>
<ul>
<li>
<strong>What's it for:</strong> Allow you to animate changes between different views or layouts on a webpage</li>
<li>
<strong>Why I care:</strong> Cross document view transitions</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_anchor_positioning" title="CSS anchor positioning - MDN">Anchor positioning</a></p>
<ul>
<li>
<strong>What is it:</strong> Placement of an element relative to a specific anchor point, such as the top-left corner of the browser window or the parent element</li>
<li>
<strong>Why I care:</strong> Easier positioning of elements on the page (reminds me of <a href="https://doc.qt.io/qt-6/qtquick-index.html" title="Qt Quick - Qt docs">Qt Quick</a>, which also uses <a href="https://doc.qt.io/qt-6/qtquick-positioning-anchors.html" title="Positioning with Anchors - Qt docs">anchors</a>)</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select" title="Select element - MDN"><code>&lt;select&gt;</code></a></p>
<ul>
<li>
<strong>What is it:</strong> Element used to create a dropdown list of options for users to choose from</li>
<li>
<strong>Why I care:</strong> Can customize dropdowns easily</li>
</ul>
</li>
</ul>
<h2 id="features-not-quite-ready-yet">Features not quite ready yet</h2>
<ul>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Masonry_layout" title="Masonry layout - MDN">The <code>masonry</code> layout</a></p>
<ul>
<li>
<strong>What is it:</strong> Layout technique that arranges elements in a staggered, multi-column grid, similar to the bricks in a masonry wall</li>
<li>
<strong>Why I care:</strong> More eye candy for site visitors</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/Privacy/Third-party_cookies" title="Third-party cookies - MDN">Third-party cookie deprecation</a></p>
<ul>
<li>
<strong>What is it:</strong> Process of phasing out cookies set by websites other than the one being visited, aiming to protect user privacy and limit targeted advertising</li>
<li>
<strong>Why I care:</strong> Cripples advertising, protects users</li>
</ul>
</li>
<li>
<p>Scoped transitions</p>
<ul>
<li>
<strong>What is it:</strong> Allows you to limit the scope of animations to specific elements, preventing them from affecting other elements on the page</li>
<li>
<strong>Why I care:</strong> More control</li>
</ul>
</li>
<li>
<p>Gesture-driven transitions</p>
<ul>
<li>
<strong>What is it:</strong> Transitions that occur based on user gestures like swiping, pinching, or tapping.</li>
<li>
<strong>Why I care:</strong> More control</li>
</ul>
</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@scope" title="Third-party cookies - MDN"><code>@scope()</code></a></p>
<ul>
<li>
<strong>What's it for:</strong> Simplifies element selection by targeting specific DOM subtrees, avoiding overly specific selectors and reducing DOM coupling.</li>
<li>
<strong>Why I care:</strong> Namespaces are finally in CSS, goodbye <a href="https://getbem.com/introduction/" title="Introduction - BEM">BEM</a>!</li>
</ul>
</li>
</ul>
<h2 id="issues">Issues</h2>
<p>My only issue with these features is that browser support is not universal yet. It may take a couple years 😢.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>The web rocks. I'm happy to watch its growth and to be a contributor.</p>
<p><strong>Long live the Wild Wild Web!</strong></p>
<h2>More resources</h2>
<ul>
<li>
<a href="https://www.youtube.com/watch?v=_-6LgEjEyzE" title="The latest in Web UI (Google I/O '24) - YouTube">The latest in Web UI</a> - Una Kravets</li>
<li>
<a href="https://www.youtube.com/watch?v=W8bokbLn1G8" title="What's new in the web (Google I/O '24) - YouTube">What's new in the Web</a> - Rachel Andrews</li>
</ul>]]></description>
      <pubDate>Fri, 04 Oct 2024 18:53:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/exciting-features-coming-to-the-web</guid>
    </item>
    <item>
      <title>The rhyme and rhythm of Thesaurus</title>
      <link>https://www.mmhq.me/posts/the-rhyme-and-rhythm-of-thesaurus</link>
      <description><![CDATA[<p><picture><img alt="A little oxford thesaurus placed on a table" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/oxford-thesaurus.webp" srcset="/static/data/images/360w/oxford-thesaurus.webp 360w, /static/data/images/640w/oxford-thesaurus.webp 640w, /static/data/images/1080w/oxford-thesaurus.webp 1080w, /static/data/images/1280w/oxford-thesaurus.webp 1280w" title="Thesaurus"></picture></p>
<blockquote cite="https://www.youtube.com/watch?v=ACHPN5doI7M">
<pre>
Tell whoever's champ that next year, name the place and time
And warn that motherf****r I'm coming for the chain that's mine
</pre>
    <cite>Peter Morris, battle rapper</cite>
</blockquote>

<p><strong>Peter Morris, also known as Thesaurus, is one of my favorite battle rappers in the game.</strong> I like his style a lot because I can hear a lot of poetry influences in his bars.</p>
<p>Let's take a glimpse of his poetic genius by analyzing some of his music.</p>
<h2 id="this-is-the-beginning-of-the-end">This is the beginning of the end</h2>
<p><strong>Although Thesaurus is mostly known for his legendary battle rap performances, he has released a couple songs on YouTube.</strong> One that stood out to me is a song called <a href="https://www.youtube.com/watch?v=hYNg6HWtKes" title="This is The Beginning of the End - Thesaurus">This is the beginning of the end</a> on his album, <em>All I Know Is That</em>.</p>
<p><strong>All the poetic devices masterfully used by Thesaurus are worth analyzing, but let's focus on the rhythm and rhyme.</strong></p>
<h2 id="first-verse-snippet">First verse snippet</h2>
<p>In the first four bars of the first verse, Thesaurus kicks off with some smooth rhymes:</p>
<pre class="poem">
I'm speaking languages more lethal than you may assume
A secret play they have to keep in a containment room
I'm the seed of Satan sleeping in an ancient tomb
Once the beast awakens you'll be meeting with your maker soon
</pre>

<p>Beautifully constructed verse. Let's break it down.</p>
<h3 id="the-rhythm-first-verse-snippet">The rhythm</h3>
<p><strong>The rhythm used by Thesaurus is a common meter in poetry, <em>so</em> common that the meter is literally called <em>common meter</em></strong>. Common meter is a popular rhythm used in poetry (thus the name) called a <strong><em>iambic heptameter</em></strong>, or a <strong><em>fourteener</em></strong>. This rhythm is defined by having 7 (<em>hepta-</em>) iambs per line. An <a href="https://literarydevices.net/iamb" title="Iamb definition - literarydevices.net">iamb</a> is a weak syllable and a strong syllable in succession, kind of like a heart beat (the <em>da-DUM</em> sound). 7 iambs totals up to 14 syllables per line.</p>
<p>Let's break down the rhythm into weak and strong beats:</p>
<pre class="poem">
<span class="meter weak">I'm</span> <span class="meter strong">speak</span><span class="meter weak">ing</span> <span class="meter strong">lan</span><span class="meter weak">gua</span><span class="meter strong promotion">ges</span> <span class="meter weak">more</span> <span class="meter strong">le</span><span class="meter weak">thal</span> <span class="meter strong">than</span> <span class="meter weak">you</span> <span class="meter strong">may</span> <span class="meter weak">as</span><span class="meter strong">sume</span>
<span class="meter weak">A</span> <span class="meter strong">se</span><span class="meter weak">cret</span> <span class="meter strong">play</span> <span class="meter weak">they</span> <span class="meter strong">have</span> <span class="meter weak">to</span> <span class="meter strong">keep</span> <span class="meter weak">in</span> <span class="meter strong promotion">a</span> <span class="meter weak">con</span><span class="meter strong">tain</span><span class="meter weak">ment</span> <span class="meter strong">room</span>
<span class="meter weak">I'm</span> <span class="meter weak">the</span> <span class="meter strong">seed</span> <span class="meter weak">of</span> <span class="meter strong">Sa</span><span class="meter weak">tan</span> <span class="meter strong">sleep</span><span class="meter weak">ing</span> <span class="meter strong promotion">in</span> <span class="meter weak">an</span> <span class="meter strong">an</span><span class="meter weak">cient</span> <span class="meter strong">tomb</span>
<span class="meter strong">Once</span> <span class="meter weak">the</span> <span class="meter strong">beast</span> <span class="meter weak">a</span><span class="meter strong">wa</span><span class="meter weak">kens</span> <span class="meter strong">you'll</span> <span class="meter weak">be</span> <span class="meter strong">meet</span><span class="meter weak">ing</span> <span class="meter strong promotion">with</span> <span class="meter weak">your</span> <span class="meter strong">ma</span><span class="meter weak">ker</span> <span class="meter strong">soon</span>
</pre>

<p>As displayed, the rhythm is regular and the bars scan well (a little too well if you ask me).</p>
<p>A lot of poets (like Emily Dickinson) used this meter. It's also called the <strong><em>hymnal meter</em></strong> because it was frequently used in hymns. Thesaurus masterfully repurposes the meter to craft an elegant verse.</p>
<p>Let's look at the rhyme next.</p>
<h3 id="the-rhyme-first-verse-snippet">The rhyme</h3>
<pre class="poem">
I'm <span class="rhyme A">speak</span>ing <span class="rhyme B">lan</span>guages more <span class="rhyme A">le</span>thal than you <span class="rhyme C">may</span> as<span class="rhyme D">sume</span>
A <span class="rhyme A">se</span>cret <span class="rhyme C">play</span> they <span class="rhyme B">have</span> to <span class="rhyme A">keep</span> in a con<span class="rhyme C">tain</span>ment <span class="rhyme D">room</span>
I'm the <span class="rhyme A">seed</span> of <span class="rhyme C">Sa</span>tan <span class="rhyme A">sleep</span>ing in an <span class="rhyme C">an</span>cient <span class="rhyme D">tomb</span>
Once the <span class="rhyme A">beast</span> a<span class="rhyme C">wa</span>kens you'll be <span class="rhyme A">meet</span>ing with your <span class="rhyme C">ma</span>ker <span class="rhyme D">soon</span>
</pre>

<p>In this <a href="http://www.shadowpoetry.com/resources/wip/quatrain.html" title="Quatrain definition - Poetry Base">quatrain</a>, you can see how <strong>Thesaurus cleverly gets each line to rhyme at multiple spots</strong>, and not just relying on the end rhyme. This makes his bars tight and more pronounced.</p>
<h2 id="the-rhyme-second-verse-snippet">Second verse snippet</h2>
<p>Thesaurus doesn't stop there. He continues to spit flames in the second verse.</p>
<p>Here's a quatrain embedded somewhere in the second verse:</p>
<pre class="poem">
I've redefined the standards that were set before me
'Cause my predecessors exercised their methods poorly
I'm just the guy to execute a plan
I'll always get the best of you unless you prove I can't
</pre>

<p>Once again, let's break it down.</p>
<h3 id="the-rhythm-second-verse-snippet">The rhythm</h3>
<p>As you can see, Thesaurus grabs reach of common meter once more, keeping each line about 14 syllables in length:</p>
<pre class="poem">
<span class="meter weak">I've</span> <span class="meter strong">re</span><span class="meter weak">de</span><span class="meter strong">fined</span> <span class="meter weak">the</span> <span class="meter strong">stan</span><span class="meter weak">dards</span> <span class="meter strong">that</span> <span class="meter weak">were</span> <span class="meter strong">set</span> <span class="meter weak">be</span><span class="meter strong">fore</span> <span class="meter weak">me</span>
<span class="meter strong">'Cause</span> <span class="meter weak">my</span> <span class="meter strong">pre</span><span class="meter weak">de</span><span class="meter strong">ce</span><span class="meter weak">ssors</span> <span class="meter strong">ex</span><span class="meter weak">er</span><span class="meter strong promotion">cised</span> <span class="meter weak">their</span> <span class="meter strong">me</span><span class="meter weak">thods</span> <span class="meter strong">poor</span><span class="meter weak">ly</span>
<span class="meter weak">I'm</span> <span class="meter strong">just</span> <span class="meter weak">the</span> <span class="meter strong">guy</span> <span class="meter weak">to</span> <span class="meter strong">e</span><span class="meter weak">xe</span><span class="meter strong promotion">cute</span> <span class="meter weak">a</span> <span class="meter strong">plan</span>
<span class="meter weak">I'll</span> <span class="meter strong">al</span><span class="meter weak">ways</span> <span class="meter strong">get</span> <span class="meter weak">the</span> <span class="meter strong">best</span> <span class="meter weak">of</span> <span class="meter strong">you</span> <span class="meter weak">un</span><span class="meter strong">less</span> <span class="meter weak">you</span> <span class="meter strong">prove</span> <span class="meter weak">I</span> <span class="meter strong">can't</span>
</pre>

<p>There is a break in the normal line length on line 3, where he uses an <strong><em>iambic pentameter</em></strong> instead, another typical poetic meter. This variation revitalizes the quatrain.</p>
<h3 id="the-rhyme-second-verse-snippet">The rhyme</h3>
<p>Thesaurus has a way with rhyme and this song is an example of flawless execution:</p>
<pre class="poem">
I've <span class="rhyme A">re</span>defined the <span class="rhyme B">stand</span>ards <span class="rhyme B">that</span> were set be<span class="rhyme C">fore</span> <span class="rhyme A">me</span>
'Cause my <span class="rhyme D">pre</span>decessors <span class="rhyme D">e</span>xercised their <span class="rhyme D">me</span>thods <span class="rhyme C">poor</span><span class="rhyme A">ly</span>
I'm just the guy to <span class="rhyme D">e</span>xe<span class="rhyme E">cute</span> a <span class="rhyme F">plan</span>
I'll always <span class="rhyme D">get</span> the <span class="rhyme D">best</span> of <span class="rhyme E">you</span> un<span class="rhyme D">less</span> <span class="rhyme E">you</span> <span class="rhyme E">prove</span> I <span class="rhyme F">can't</span>
</pre>

<p>As you can see, he once again uses a lot of <a href="https://www.litcharts.com/literary-devices-and-terms/internal-rhyme" title="Internal rhyme definition - LitCharts">internal rhyme</a> and <a href="https://www.litcharts.com/literary-devices-and-terms/assonance" title="Assonance definition - LitCharts">assonance</a>.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>Poetry has a heavy influence on the battle rap community</strong> and it is nice to see people like Thesaurus who know how to use them in new and exciting ways.</p>
<h2 id="more-resources">More resources</h2>
<ul>
<li><a href="https://versetracker.com/rapper/the-saurus" title="Thesaurus on Verse Tracker">His bio</a></li>
<li><a href="https://www.youtube.com/watch?v=hYNg6HWtKes" title="This is The Beginning of the End - Thesaurus">The track</a></li>
<li><a href="https://www.youtube.com/watch?v=ACHPN5doI7M" title="Thesaurus Top Ten Rounds - YouTube">His top ten rounds</a></li>
<li><a href="https://www.youtube.com/@TheSaurusWins" title="Thesaurus Official YouTube channel - YouTube">His YouTube channel</a></li>
<li><a href="https://en.wikipedia.org/wiki/Metre_(hymn)" title="Hymnal meter - Wikipedia">Hymnal meter</a></li>
<li><a href="https://literarydevices.net/iambic-pentameter" title="Iambic pentameter definition - literarydevices.net">Iambic pentameter</a></li>
</ul>]]></description>
      <pubDate>Mon, 16 Sep 2024 06:31:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/the-rhyme-and-rhythm-of-thesaurus</guid>
    </item>
    <item>
      <title>Build step obsession</title>
      <link>https://www.mmhq.me/posts/build-step-obsession</link>
      <description><![CDATA[<p><picture><img alt="Welder with face covered crafting with a tool that sparks" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/welding.webp" srcset="/static/data/images/360w/welding.webp 360w, /static/data/images/640w/welding.webp 640w, /static/data/images/1080w/welding.webp 1080w, /static/data/images/1280w/welding.webp 1280w" title="Welding"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Hosea-6-6/">
    <p>For I desired mercy, and not sacrifice; and the knowledge of God more than burnt offerings.</p>
    <cite>Hosea 6:6, The Bible</cite>
</blockquote>

<p><strong>Building websites today has become easier than it's ever been.</strong> All you need is a text editor and a browser, two programs that almost every home computer possesses today (and most times, right out the box).</p>
<p>To make your first webpage, you can create an <code>index.html</code> file anywhere on your computer, stuff it with the following content, and open the file in a browser:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello, world<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</code></pre></div>

<p>And voila! You've made your first webpage. Slap on a domain name and throw it on a hosting service and you are good to go.</p>
<p><strong>So why do we need <em>build steps</em> on the web?</strong></p>
<p>That question reminds me of a story in the Bible.</p>
<h2 id="starving-on-the-sabbath">Starving on the Sabbath</h2>
<p>Jesus was walking through a field of corn with his disciples one Sabbath day. His disciples were hungry, so they plucked ears of corn from the field and ate them. The Pharisees saw them and told Jesus that his disciples are doing what is unlawful on the Sabbath.</p>
<p>What was Jesus' response?</p>
<blockquote cite="https://www.kingjamesbibleonline.org/Mark-2-27/">
    <p>And he said unto them, The sabbath was made for man, and not man for the sabbath:</p>
    <cite>Mark 2:27, The Bible</cite>
</blockquote>

<p>Huh? What was Jesus saying?</p>
<p>Jesus was telling the Pharisees that <strong>God created the Sabbath to <em>serve man</em></strong> (by giving him rest) <strong>and not so that man <em>serves the Sabbath</em></strong>. In other words, instead of focusing on the <em>work</em> others are doing, <em>rest</em> (like God did on the seventh day of creation).</p>
<p>In this analogy, <em>sabbath</em> can be replaced with <em>web</em>. <strong>The <em>web</em> was made for man, and not man for the <em>web</em>.</strong></p>
<p>But today, with so many tools on the web, web developers tend to focus on <em>work</em> (i.e. <em>build steps</em>) and tend to do more work than necessary.</p>
<h2 id="why-are-build-steps-bad">Why are build steps bad?</h2>
<p>When I say <strong><em>build step</em></strong>, I mean <strong>any step that needs to be performed before deploying your website</strong>.</p>
<p>As innocuous as it sounds, choosing the wrong build steps can affect 3 areas every web developer should care about:</p>
<ul>
<li>👤 <strong>User experience (UX)</strong>: The overall experience of a site visitor when using your website.</li>
<li>♿ <strong>Accessibility (a11y)</strong>: The degree to which your website is usable by as many people as possible, including disabled people.</li>
<li>👨‍💻 <strong>Developer experience (DX)</strong>: The overall experience of the developer when building the website.</li>
</ul>
<p>Let's explore some popular build steps on the web and measure how each listed area is affected.</p>
<h2 id="the-transpilation-build-step">The transpilation build step</h2>
<p>This involves converting JSX, TSX, TypeScript, SCSS, SASS, Svelte templating language etc. into HTML that browsers can render.</p>
<h3>Advantages</h3>
<ul>
<li>You get to write lots and lots of JavaScript/TypeScript or whatever language and no HTML. Every developer's dream I suppose 😒.</li>
<li>You get to place your code in separable components that can never be effectively reused outside of the project.</li>
<li>You don't repeat yourself.</li>
<li>You write shorter code.</li>
</ul>
<h3>Disadvantages</h3>
<ul>
<li>👤 <strong>The browser has to execute JavaScript first, which could fail and cause the screen to remain blank.</strong> </li>
<li>👤 <strong>You are going from HTML to JavaScript, back to HTML.</strong> This slows down the rendering. </li>
<li>♿ <strong>The code that is converted to HTML is often not accessible</strong>, as the transpiler lacks context of the content on the page. </li>
<li>👨‍💻 <strong>You have to write lots of JavaScript/TypeScript or whatever language you are using.</strong> Whatever language that is chosen <strong>will not be safer than HTML</strong>, meaning you should expect more issues than usual.</li>
<li>👨‍💻 <strong>Iterations are slower because you have to build every time</strong> .</li>
<li>👨‍💻 <strong>JSX sucks!</strong> It is not as pleasant to write as plain JavaScript. Or plain HTML. (The developer suffers.)</li>
<li>👨‍💻 <strong>If I have to <em>build</em> HTML, what is the point?</strong>
</li>
</ul>
<h2 id="the-minification-build-step">The minification build step</h2>
<p>This step involves removing all the unneeded white space and sometimes obfuscating the data in a CSS or JS file to reduce the size of the data that is sent to the browser.</p>
<p>This sounds like a wonderful idea.</p>
<h3>Advantages</h3>
<ul>
<li>You get to remove the white spaces and save 0.001 KB of wasted data. Hooray 😒.</li>
<li>You get to obfuscate your code, save space and contributing to the 0.001 KB saved 😒.</li>
<li>You get to obfuscate your code, making it harder for people that have capable browsers to study it 😒.</li>
<li>You get a false sense of achievement that you have saved a lot of bytes sent for the user 😒.</li>
</ul>
<h3>Disadvantages</h3>
<ul>
<li>👨‍💻 <strong>Contrary to popular belief, 0.001 KB of data is not a lot saved.</strong> You get the best savings when you use <code>gzip</code> to transfer your website (supported on the web as of HTTP 1.1).</li>
<li>👨‍💻 <strong>If it breaks someday</strong> (maybe due to updates in HTML or CSS syntax), <strong>you can't deploy</strong>.</li>
<li>👨‍💻 <strong>A different set of code sent to the browser makes debugging a Herculean task</strong> (though web developers love this pain).</li>
<li>👨‍💻 <strong>If your build step has to <em>modify your CSS or JS</em> and can't send it <em>as is</em>, what's the point?</strong>
</li>
</ul>
<p>Could be wrong on this one; it seems like the advantages are more here. 😒</p>
<h2 id="the-webpack-build-step">The Webpack build step</h2>
<p>Webpack is a powerful tool used to bundle modules together. A <em>module</em> is any file that processed by Webpack. In the case of Webpack, we're talking HTML files, CSS files, JavaScript files, images etc.</p>
<p><strong>NOTE:</strong> This also includes running <code>npm run build</code>.</p>
<h3>Advantages</h3>
<ul>
<li>Module bundling for easier optimization</li>
<li>Code splitting</li>
<li>Dependency management</li>
<li>Development tools and enhancements like hot module reload and source maps</li>
<li>Asset optimization like image compression, tree shaking (i.e. removing unused code), CSS and JS minification</li>
<li>Loaders and plugins for processing different files</li>
<li>Environment-specific builds</li>
<li>Easy framework integration</li>
<li>Long term caching</li>
<li>Community and ecosystem</li>
</ul>
<h3>Disadvantages</h3>
<ul>
<li>👨‍💻 <strong>Modules.</strong> (I want my HTML, CSS and JavaScript files to be considered unique and separate, thank you 😒.)</li>
<li>👨‍💻 <strong>Code splitting is unnecessary for plain HTML because the browser needs the whole HTML to render a webpage properly.</strong>
</li>
<li>👨‍💻 <strong>Dependency management is unnecessary for plain HTML because if you only use HTML and CSS</strong> (and build from scratch), <strong>you would have very few dependencies</strong>.</li>
<li>👨‍💻 <strong>Hot module reload is unnecessary for plain HTML because you could just refresh the webpage.</strong>
</li>
<li>👨‍💻 <strong>Source maps are unnecessary for plain HTML because the code sent from the server is the same code seen in the browser.</strong>
</li>
<li>👨‍💻 <strong>Tree shaking is unnecessary for plain HTML because all the code in HTML is used.</strong> The CSS code can be cleaned up manually.</li>
<li>👨‍💻 <strong>Minification is useless</strong>, as I highlighted in the previous section.</li>
<li>👨‍💻 <strong>Loaders and plugins are unnecessary for plain HTML because the browser handles everything for us</strong>. We just need to provide the HTML and CSS.</li>
<li>👨‍💻 <strong>Webpack has to be aware of the type of build.</strong> Unlike Webpack, HTML and CSS have no control over your environment. They are just languages. (Thank God.)</li>
<li>👨‍💻 <strong>Framework integration is unnecessary for plain HTML if you are not using any frameworks.</strong>😜</li>
<li>👨‍💻 <strong>Who needs long term caching when you have <code>Cache-Control</code> and cache-busting techniques?</strong>
</li>
<li>👨‍💻 <strong>Sadly, you have a lot of people <em>using</em> HTML and CSS but not a lot of people <em>writing</em> it.</strong> However, you can navigate the web world if you are willing to read documentation and answers online.</li>
</ul>
<p>Am I the only one that notices that half of the advantages are solutions to the problems caused by Webpack itself? Maybe it's just me. 😒</p>
<h2 id="the-ssg-build-step">The SSG build step</h2>
<p>According to ChatGPT:</p>
<blockquote cite="https://chatgpt.com">
    <p>An SSG stands for Static Site Generator. It is a tool that generates static HTML pages from source files, usually using templates and content written in a markup language like Markdown. SSGs are widely used in web development for creating fast, secure, and SEO-friendly websites.</p>
</blockquote>

<h3>Advantages</h3>
<ul>
<li>Faster load times</li>
<li>CDN compatibility</li>
<li>Reduced attack surface</li>
<li>No server-side processing</li>
<li>Simple to scale</li>
<li>Efficient resource use</li>
<li>Lower hosting costs</li>
<li>Content management</li>
<li>Template based design</li>
<li>Community support</li>
<li>Plugins and extensions</li>
<li>Environmental and deployment flexibility </li>
</ul>
<h3>Disadvantages</h3>
<ul>
<li>👨‍💻 <strong>No real-time content.</strong> You can't easily make changes once an update to older content has been made.</li>
<li>👨‍💻 <strong>Workarounds for interactivity.</strong> Because it's HTML-focused, it makes it easier to extend your code. This makes it less scalable.</li>
<li>👨‍💻 <strong>Slow build times for large sites.</strong>
</li>
<li>👨‍💻 <strong>Incremental builds, complex to configure.</strong>
</li>
<li>👨‍💻 <strong>Steep learning curve</strong>; Contrary to popular belief, I don't think it's easier than just learning things properly</li>
<li>👨‍💻 <strong>Dependency on build tools.</strong> And you need to keep updating them.</li>
<li>👨‍💻 <strong>Updating your build pipeline.</strong> This could break things.</li>
<li>👨‍💻 <strong>Third-party dependence for advance features.</strong> Limited by what is available.</li>
<li>👨‍💻 <strong>Inflexibility for certain projects.</strong> For e-commerce or similar, forget about it.</li>
<li>👤 <strong>Third-party libraries used may have a different look-and-feel</strong> than the main theme library. </li>
</ul>
<h2 id="the-ssr-build-step">The SSR build step</h2>
<p>Once again, educate us ChatGPT:</p>
<blockquote cite="https://chatgpt.com">
    <p>Server-Side Rendering (SSR) is a web development technique where the server generates the full HTML for a web page and sends it to the client (usually a browser) in response to a request.</p>
</blockquote>

<p>Did you catch the fallacy? <em>Rendering</em> only happens at the browser, not on the server. Server-side rendering is really a myth.</p>
<p>The server's job is to <strong>serve HTML, not to render it</strong>. But I digress 😒.</p>
<h3>Advantages</h3>
<ul>
<li>Improved SEO</li>
<li>Faster initial page load</li>
<li>Better performance on low-powered devices</li>
<li>Consistent content, the server sends the same pre-rendered HTML</li>
<li>Increased server load. Though this is usually a disadvantage, load on the server is generally better than load on the client. The website becomes more accessible.</li>
</ul>
<h3>Disadvantages</h3>
<ul>
<li>👤 <strong>Slower interaction time</strong>, because at least all of the HTML must be rendered before interaction can take place. In comparison to the alternative, this is not as bad as it sounds.</li>
<li>👨‍💻 <strong>Complexity</strong>. Using frameworks where you have to switch between server-side rendering and client-side rendering already sounds like a headache.</li>
<li>👨‍💻 <strong>Caching challenges</strong>, because static sites are easier to cache than dynamic sites. That's not too bad if you know how to use <code>Cache-Control</code> and cache busting.</li>
</ul>
<p>Maybe we should stick to servers <em>serving</em> HTML and not <em>rendering</em> it. 🤔</p>
<h2 id="so-what-is-the-ideal-process">So what is the ideal process?</h2>
<p>The ideal process is <strong>no build steps!</strong> That's it! You just need to run your code in the browser.</p>
<p>To host your code online, just copy it from your computer to the server. It should be <em>that</em> simple.</p>
<h2 id="why-is-rest-important">Why is rest important?</h2>
<p>Jesus wanted to do all the work for us and wanted us to rest. The same is true for the web.</p>
<p>Tim Burners-Lee (TBL) made the web simple so that everybody can contribute. <strong>When you make things harder for people to do, you are working against the principles of the web.</strong></p>
<p>It is only in <em>rest</em> that you can fully appreciate what TBL and contributors to the web have done. It allows you to focus on real problems on the web, and not the many build steps that don't improve the quality of what is delivered.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>Ditch the build steps.</strong> 🛠️❌ Become familiar and well-acquainted with HTML, CSS and JS. Unlike all the web frameworks and fanciful build steps, those languages are not going anywhere.</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.kingjamesbibleonline.org/Mark-2-23/" title="Jesus is challenged on the Sabbath">Mark 2:23-28</a></li>
</ul>]]></description>
      <pubDate>Mon, 09 Sep 2024 02:40:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/build-step-obsession</guid>
    </item>
    <item>
      <title>My web design toolkit</title>
      <link>https://www.mmhq.me/posts/my-web-design-toolkit</link>
      <description><![CDATA[<p><picture><img alt="Tools placed together on a table" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/toolkit.webp" srcset="/static/data/images/360w/toolkit.webp 360w, /static/data/images/640w/toolkit.webp 640w, /static/data/images/1080w/toolkit.webp 1080w, /static/data/images/1280w/toolkit.webp 1280w" title="Toolkit"></picture></p>
<p><strong>As an aspiring webmaster 🕸️, I spend most of my free time designing, developing and maintaining websites.</strong> 🌐 To ease the process, I ensure that I choose the best tools available on the market.</p>
<p><strong>Choosing the wrong tools could lead to you doing the wrong work</strong> (like fixing issues caused by interfacing layers) <strong>or more work than necessary</strong> 🐢 (like having to satisfy the requirements of some framework. Yes, I'm looking at you <em>TypeScript</em>).</p>
<p>On the other hand, <strong>choosing the right tools can help you get things done much faster and with simpler and scalable results.</strong>🦸</p>
<h2 id="what-makes-a-good-tool">What makes a good tool?</h2>
<p>When I'm choosing a tool, I make sure that it is:</p>
<ul>
<li>
<strong>Simple</strong> 🔶: Not to be confused with <em>easy</em>, but it needs to be primitive, like shapes. Simple shapes can be used to create any drawing. I need the tool to do the same.</li>
<li>
<strong>Free (or low cost)</strong> 🆓: This may be the most important. Being able to scale is directly tied to how cheap everything is.</li>
<li>
<strong>Configurable</strong> ⚙️: Can I make it do whatever I want?</li>
<li>
<strong>Minimal</strong> 🫓: Can I run the tool on minimal hardware, or do I need to buy a gaming PC just to run the program? Does it solve mainly one problem and does it solve it well?</li>
</ul>
<p>There are other factors, but the ones listed have the highest priority to me.</p>
<h2 id="what-are-the-tools-for">What are the tools for?</h2>
<p>I use the tools for what I call the <strong><em>Five Fingers of Web Design</em></strong>:</p>
<ul>
<li>Strategy</li>
<li>Design</li>
<li>Development</li>
<li>Deployment</li>
<li>Analytics/marketing</li>
</ul>
<p>I group my tools in to those five categories.</p>
<h2 id="tools-for-strategy">Tools for strategy</h2>
<p>I use these tools to research and discover the target audience, then plan the next steps of execution.</p>
<ul>
<li>
<strong>Google Meet</strong> 🎥: As you would expect, I use this to communicate with clients and to interview their customers too to get a glimpse of the problems they're facing.</li>
<li>
<strong>GitHub</strong> 💼: I use a <a href="https://github.com" title="GitHub Home page">kanban on GitHub</a> for planning the various stages.</li>
</ul>
<h2 id="tools-for-design">Tools for design</h2>
<p>I use these tools to craft my designs.</p>
<ul>
<li>
<strong>Pen and paper</strong> 📝: This is not software but just as important as any other tool. I use it to create wireframes that would be recreated with software.</li>
</ul>
<p>Tools I run on my browser:</p>
<ul>
<li>
<strong>Penpot</strong> 🎨: A <a href="https://penpot.app" title="Penpot design tool">design and prototyping tool</a>. This is where all my mockups reside. It is an open-source alternative to Figma.</li>
<li>
<strong>Dribbble</strong> 🖼️: A <a href="https://dribbble.com" title="Dribbble home page">social media platform</a> where design professionals share their work. I go there for inspiration (and to steal ideas).</li>
<li>
<strong>Chromora</strong> 🌈: I use <a href="https://chromora.com" title="Chromora - Color palette generator">Chromora</a> to create color palettes.</li>
<li>
<strong>Boxicons</strong> 📦: I download all my free SVG icons at <a href="https://boxicons.com" title="Boxicons - Free SVG icons">Boxicons</a>.</li>
<li>
<strong>Typescale</strong> 🔤: I use <a href="https://typescale.com" title="Typescale">this website</a> to choose typographic scales.</li>
</ul>
<p>Tools I install on my computer:</p>
<ul>
<li>
<strong>Inkscape</strong> 🖌️: A <a href="https://inkscape.org" title="Inkscape official website">free and open-source cross-platform vector graphics editor</a> similar to Adobe Illustrator. I use it to make interactive icons and images.</li>
<li>
<strong>GNU Image Manipulation Program (GIMP)</strong> 🖌️: A <a href="https://gimp.org" title="GIMP official website">free and open-source cross-platform image editor</a> similar to Adobe Photoshop. I use it to crop backgrounds out of images.</li>
</ul>
<h2 id="tools-for-development">Tools for development</h2>
<p>I use these tools to bring my designs to life. (Mostly frontend work.)</p>
<p>Tools I install on my computer:</p>
<ul>
<li>
<strong>Firefox</strong> 🌐: I use <a href="https://firefox.com" title="Firefox browser">Firefox</a> as a test browser.</li>
<li>
<strong>Brave</strong> 🌐: I use <a href="https://brave.com" title="Brave browser">Brave</a> as a test browser.</li>
</ul>
<p>Tools I run on my browser:</p>
<ul>
<li>
<strong>Penpot</strong> 🎨: To view my created mockups.</li>
<li>
<strong>Google Webfonts Helper</strong> 🔠: This <a href="https://gwfh.mranftl.com" title="Google Webfonts Helper">website</a> helps to provide Google fonts as WOFF2 files and stripped of unnecessary (or commonly unused) glyphs.</li>
<li>
<strong>Utopia</strong> 📏: I use <a href="https://utopia.fyi" title="Utopia - Fluide Responsive Design">this tool</a> to choose a fluid typographic scale and spacing scale.</li>
<li>
<strong>Mozilla Developer Network (MDN)</strong> 📜: I visit <a href="https://developer.mozilla.org" title="Web documentation">here</a> when I'm confused (which means everyday).</li>
<li>
<strong>HTML, CSS and JavaScript</strong> 👨‍💻: Of course, the languages of the web!</li>
</ul>
<p>Tools I run in my terminal:</p>
<ul>
<li>
<strong>dyetide</strong> 👕: I use <a href="https://github.com/tomit4/dyetide" title="Dyetide - a color conversion tool in Bash - GitHub repo">dyetide</a> to convert colors from RGB and hex to HSL (the <a href="/posts/hsl-over-rgb-and-hex" title="HSL over RGB and hex - Mind Matters">human-comprehensible version</a> of color).</li>
<li>
<strong>jq</strong> 🔍 : I use <a href="https://jqlang.github.io/jq/" title="jq - a lightweight and flexible command-line JSON processor">jq</a> to transform, query and filter JSON files.</li>
<li>
<strong>xmllint</strong> 🔍: I use <a href="https://gnome.pages.gitlab.gnome.org/libxml2/xmllint.html" title="command line XML tool">xmllint</a> to query XML and (X)HTML files.</li>
<li>
<strong>htmlq</strong> 🔍: I use <a href="https://github.com/mgdm/htmlq" title="htmlq - Just like jq, but for HTML - GitHub repo">htmlq</a> to query HTML files.</li>
<li>
<strong>vim</strong> ✍️: I use <a href="https://www.vim.org/" title="Vim - the ubiqutous text editor">vim</a> as an editor.</li>
<li>
<strong>ssm</strong> 📋: I use <a href="https://github.com/obeezzy/ssm" title="ssm - SVG spritesheet maker - GitHub repo">ssm</a> to create SVG spritesheets.</li>
</ul>
<p>Tools I want to try:</p>
<ul>
<li>
<strong>Emmet</strong> ✒️: This <a href="https://emmet.io/" title="Emmet official website">tool</a> is for writing HTML faster through typing shortcuts.</li>
</ul>
<h2 id="tools-for-deployment">Tools for deployment</h2>
<p>I use these tools after the website has been deployed to the server. (Mostly backend work.)</p>
<ul>
<li>
<strong>Python</strong> 🐍: <a href="https://python.org" title="Python official website">Language</a> of choice.</li>
<li>
<strong>Flask</strong> 🏢: <a href="https://flask.palletsprojects.com" title="Flask official website">Web framework</a> of choice.</li>
<li>
<strong>uWSGI</strong> 🛎️: <a href="https://uwsgi-docs.readthedocs.io/en/latest" title="uWSGI official documentation">Web server</a> of choice.</li>
<li>
<strong>nginx</strong> 🛎️: <a href="https://nginx.org" title="Nginx official website">Proxy server</a> of choice.</li>
<li>
<strong>Debian</strong> 🤖: <a href="https://debian.org" title="Debian official website">OS</a> of choice.</li>
<li>
<strong>Vultr</strong> 🦅: <a href="https://vultr.com" title="Vultr official website">VPS</a> of choice.</li>
<li>
<strong>Cloudflare</strong> 🌎: <a href="https://cloudflare.com" title="Cloudflare official website">CDN</a> of choice.</li>
<li>
<strong>ssh</strong> 📶: For securely accessing the server.</li>
<li>
<strong>rsync</strong> 📶: For syncing data with my server.</li>
<li>
<strong>Let's Encrypt</strong> 🔒: For generating <strong>free</strong> SSL certificates.</li>
</ul>
<h2 id="tools-for-analytics-and-marketing">Tools for analytics/marketing</h2>
<p>These tools are used to monitor your impact or keep my client's customers coming back.</p>
<p>For any of my clients:</p>
<ul>
<li>
<strong>Beacon API</strong> 🐔: This <a href="https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API" title="Beacon API - MDN">API</a> is used to keep monitor the users patterns by sending data concerning the use of the website.</li>
<li>
<strong>Mailer Lite</strong> 📨: This <a href="https://mailerlite.com" title="Mailer Lite">website</a> helps with automation for email marketing.</li>
</ul>
<p>For my websites:</p>
<ul>
<li>
<strong>goaccess</strong> 👓: A <a href="https://goaccess.io" title="GoAccess - Visual Web Log Analyzer">web analytics application</a> for Unix-like systems. I use it to check traffic on all my websites.</li>
</ul>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>My goal is to employ as little tools as necessary to get the job done when creating websites.</strong> This benefits everyone:</p>
<ul>
<li>My client's customers (i.e. the site visitors) get to <strong>enjoy a simple, lightweight, accessible website with a pleasant user experience</strong> 🏖️ because there is not a lot of bloat and unnecessary code.</li>
<li>
<strong>My client doesn't have to break the bank to run a website.</strong> 🪙 Pricing can be controlled better, since it's not dependent on website builders.</li>
<li>I get to <strong>solve problems</strong> 🔧 (with design and code) <strong>and have fun doing it!</strong> 🕺</li>
</ul>
<p>Now that's something I can scale! ⚖️</p>]]></description>
      <pubDate>Thu, 05 Sep 2024 13:48:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/my-web-design-toolkit</guid>
    </item>
    <item>
      <title>From web peasant to land chad to Spider-Man</title>
      <link>https://www.mmhq.me/posts/from-web-peasant-to-land-chad-to-spider-man</link>
      <description><![CDATA[<p><picture><img alt="Spider-Man in leather jacket" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/spider-man-in-leather-jacket.webp" srcset="/static/data/images/360w/spider-man-in-leather-jacket.webp 360w, /static/data/images/640w/spider-man-in-leather-jacket.webp 640w, /static/data/images/1080w/spider-man-in-leather-jacket.webp 1080w, /static/data/images/1280w/spider-man-in-leather-jacket.webp 1280w" title="Spider-Man"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Proverbs-22-29/">
    <p>Seest thou a man diligent in his business? he shall stand before kings; he shall not stand before mean men.</p>
    <cite>Proverbs 22:29, The Bible</cite>
</blockquote>

<p>There are only 3 types of people on the web: <strong>web peasants</strong>, <strong>land chads</strong>, and <strong>Spider-Men</strong>. I have been privileged to live in each person's shoes.</p>
<p>Here are my experiences.</p>
<h2 id="life-as-a-web-peasant">Life as a web peasant</h2>
<p>I started as a <strong><em>web peasant</em></strong>. I had no home. <strong>I was a couch surfer; a wanderer on the web. I visited websites that didn't belong to me.</strong></p>
<p>I had a lot of fun at these sites. They all welcomed me with open arms. Well, most of them. Some of them were horrible experiences.</p>
<p>But I had fun. It was nice to have a presence online and be known in the world, even if it was just by a few people.</p>
<p>I opened a Facebook account, then an Instagram account, then a Snapchat account. Pretty much all the social media platforms. These platforms became widespread and soon became an important way to communicate with people.</p>
<p>But then I woke up. And like Neo in The Matrix, I was asked to swallow the <em>red pill</em> or the <em>blue pill</em>. I chose the former.</p>
<p>I instantly realized that I was living in a house of cards. Everything may collapse at any moment.</p>
<p>All my data is owned by a few companies. I own nothing. They have the right to kick me off their platforms and sell my information at any time. Yeah, I use these websites for free, but at what cost?</p>
<p>I could lose it all tomorrow. And it would be fair. I would deserve nothing. Why? Because I'm a <em>web peasant</em>. I don't deserve better.</p>
<p>I voluntarily put myself in this position. As I make my bed, so must I lie in it.</p>
<p>But then the pill digests and I realize there is another path.</p>
<h2 id="life-as-a-land-chad">Life as a land chad</h2>
<p><strong>Instead of letting other people run my digital experiences, I could create them myself.</strong></p>
<p>Owning <em>real estate</em> online is easier and more inexpensive than it's ever been. There are 2 requirements:</p>
<ul>
<li>The <strong>domain registrar</strong>, who is responsible for giving me a domain name that is available for use for a small fee.</li>
<li>The <strong>hosting platform</strong>, who is responsible of hosting my files on a server so visitors can reach my website.</li>
</ul>
<p>Then voila! I owned my first site! Then my second. Then my third.</p>
<p>But as I was enjoying my life as a <strong>landlord on the web</strong>, I started to fall in love with the web even more.</p>
<p>I loved everything about it, especially the philosophy of freedom.</p>
<p>I told myself I wanted to be a part of that freedom. And as I look around, I see that a lot of people have also overlooked the freedom that the web brings.</p>
<p>That's when I knew that swallowing the red pill was not enough; I had to dawn the mask.</p>
<h2 id="life-as-spider-man">Life as Spider-Man</h2>
<p>I eventually reached the pinnacle in the web hierarchy: <strong><em>the webmaster</em></strong> aka <strong><em>Spider-Man</em></strong>.</p>
<p><strong>A webmaster is a person who designs, develops and maintains websites.</strong> This is where I see fulfillment.</p>
<p>I have written software for a very long time, but no other software has been more influential than the software on the web.</p>
<p>In upcoming posts, I will discuss more about my adventure to mastering web design, web development and web marketing. Stay tuned!</p>
<p>By the time I'm through mastering the web, I'll be web-slinging and sticking to walls!</p>
<h2 id="more-resources">More resources</h2>
<ul>
<li>
<a href="https://www.youtube.com/watch?v=bdKZVIGRAKQ" title="Get a Website Now! Don't be a Web Peasant! - Luke Smith video">Get a Website Now! Don't be a Web Peasant</a> by Luke Smith</li>
<li>
<a href="https://www.landchad.net" title="LandChad.net">LandChad.net</a> by Luke Smith</li>
</ul>]]></description>
      <pubDate>Wed, 04 Sep 2024 23:40:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/from-web-peasant-to-land-chad-to-spider-man</guid>
    </item>
    <item>
      <title>I crave the simple</title>
      <link>https://www.mmhq.me/posts/i-crave-the-simple</link>
      <description><![CDATA[<p><picture><img alt="Scrabble pieces that spell 'Keep it Simple'" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/keep-it-simple.webp" srcset="/static/data/images/360w/keep-it-simple.webp 360w, /static/data/images/640w/keep-it-simple.webp 640w, /static/data/images/1080w/keep-it-simple.webp 1080w, /static/data/images/1280w/keep-it-simple.webp 1280w" title="Keep it simple"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Psalms-116-6/">
    <p>The Lord preserves the simple; when I was brought low, he saved me.</p>
    <cite>Psalm 116:6, The Bible</cite>
</blockquote>

<p>I read this quote by Steve Jobs today that says:</p>
<blockquote class="quote" cite="https://thenewstack.io/developers-rail-against-javascript-merchants-of-complexity">
    <p>Simple can be harder than complex: you have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains.</p>
    <cite>Steve Jobs, Apple founder</cite>
</blockquote>

<p>I couldn't agree more. I try to do it in my life everyday:</p>
<ul>
<li>Simple code, no frameworks (except for Flask)</li>
<li>Simple food, mostly unprocessed</li>
<li>Simple meditation, I focus on breathing (though I've missed a lot of sessions recently)</li>
<li>Simple living!</li>
</ul>
<p>When you keep things simple, you can focus on solving the problems that really matter.</p>
<p>Keep it simple.</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li>
<a href="https://gomakethings.com/is-the-tide-finally-turning" title="Is the tide finally turning? - Go Make Things">Is the tide finally turning?</a> by Chris Ferdinandi</li>
<li>
<a href="https://thenewstack.io/developers-rail-against-javascript-merchants-of-complexity" title="Developers Rail Against JavaScript Merchants of Complexity - The New Stack">Developers rail against JavaScript Merchants of Complexity</a> by Richard MacManus</li>
</ul>]]></description>
      <pubDate>Fri, 30 Aug 2024 13:04:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/i-crave-the-simple</guid>
    </item>
    <item>
      <title>Accessibility is a framework problem</title>
      <link>https://www.mmhq.me/posts/accessibility-is-a-framework-problem</link>
      <description><![CDATA[<p><picture><img alt="Accessibility symbol painted on a concrete floor" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/accessibility.webp" srcset="/static/data/images/360w/accessibility.webp 360w, /static/data/images/640w/accessibility.webp 640w, /static/data/images/1080w/accessibility.webp 1080w, /static/data/images/1280w/accessibility.webp 1280w" title="Accessibility"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Leviticus-19-14/">
    <p>Thou shalt not curse the deaf, nor put a stumblingblock before the blind, but shalt fear thy God: I am the LORD.</p>
    <cite>Leviticus 19:14, The Bible</cite>
</blockquote>

<p>Recently, I read an old article by Leslie Cohn-Wein called <a href="https://www.netlify.com/blog/2019/02/25/accessibility-is-not-a-react-problem/" title="Accessibility is not a 'React Problem'">Accessibility is not a "React Problem"</a>. I completely agree with this statement. <strong>Accessibility is <em>not</em> a <em>React problem</em>, it's a <em>framework problem</em>.</strong></p>
<p>What I mean by this is that <strong><em>all</em> JS frameworks have an accessibility problem.</strong> Let's take a look at the issues developers often overlook when creating websites.</p>
<h2 id="what-is-accessibility">What is accessibility?</h2>
<blockquote class="quote" cite="https://www.w3.org/WAI/fundamentals/accessibility-intro#context">
    <p>The power of the Web is in its universality.<br>Access by everyone regardless of disability is an essential aspect.</p>
    <cite>Tim Burners-Lee, W3C Director and inventor of the World Wid Web</cite>
</blockquote>

<p>Accessibility, according to <a href="https://en.wikipedia.org/wiki/Accessibility" title="Accessibility - Wikipedia">Wikipedia</a>, is the design of products, devices, services, vehicles, or environments so as to be usable by people with disabilities.</p>
<p>It has a similar meaning when applied to the web:</p>
<blockquote class="quote" cite="https://www.w3.org/WAI/fundamentals/accessibility-intro#what">
    <p>Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them.</p>
    <cite>W3C, Web Accessibility Initiative</cite>
</blockquote>

<p>In layman terms, it's about designing with careful thought about <em>all possible users</em>.</p>
<p><strong>By ensuring web accessibility, we are indirectly improving the user experience of our websites.</strong> This in turn improves the chances that almost every visitor would enjoy their stay on the site and gets what they need.</p>
<p>The opposite is true when we neglect accessibility. Site visitors suffer for our negligence and this could sometimes lead to early exits and frustration.</p>
<p>However, <strong>React (along with <em>all</em> other JS frameworks) doesn't seem to care.</strong></p>
<h2 id="the-many-overlooked-accessibility-issues-with-react">The many, overlooked accessibility issues with React</h2>
<h3 id="div-soup">
<code>&lt;div&gt;</code> soup</h3>
<p>JS frameworks are notorious for making <code>&lt;div&gt;</code> soup: infinite wrappers of <code>&lt;div&gt;</code>s for some HTML tags on your document created for no beneficial purpose at all.</p>
<p>For example, instead of this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">time</span><span class="p">&gt;</span>10:23:12<span class="p">&lt;/</span><span class="nt">time</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">time</span> <span class="na">datetime</span><span class="o">=</span><span class="s">"2015-03-02"</span><span class="p">&gt;</span>MONDAY, 2 MARCH 2015<span class="p">&lt;/</span><span class="nt">time</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<p>React may create this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>10:23:12<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>MONDAY, 2 MARCH 2015<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<p>It may just be a few extra bytes for a little code, but you can easily see how it can add up and cause problems.</p>
<p>Each site visitor first has to download more HTML code than necessary (the definition of bloat) and the browser has to do more work to process the information. The visitor therefore <em>pays</em> for your incompetence with his battery life (if on mobile) and his time (waiting longer than necessary for information).</p>
<p>Also, notice that in the React example above, every tag on the page is a <code>&lt;div&gt;</code>. There is no easy way for web crawlers to parse the document for times and dates, unlike when using <code>&lt;time&gt;</code>.</p>
<p>There are even times that <a href="https://charandev.com/react-fragments" title="The problem of '&lt;div&gt; Soup' in React">React creates far more bloat</a>:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
            <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
                <span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Yeah, this can really happen!<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>
            <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
        <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
    <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</code></pre></div>

<h3 id="incorrect-html-semantics">Incorrect HTML semantics</h3>
<p>All frameworks lack context so they don't know when to apply <code>&lt;h1&gt;</code> vs <code>&lt;h2&gt;</code> vs <code>&lt;h3&gt;</code> etc. This may seem insignificant, but using the wrong tag can mess up the flow of the document and screen readers.</p>
<p>Take for example a résume. Instead of:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>John Doe<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Electrical engineer on a mission<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Work Experience<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Apple Inc.<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Worked on the iPhone<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Google<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Worked on the Pixel<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Education<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>

<span class="cm">&lt;!-- More info --&gt;</span>
</code></pre></div>

<p>They make this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>John Doe<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Electrical engineer on a mission<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Work Experience<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Apple Inc.<span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Worked on the iPhone<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">h3</span><span class="p">&gt;</span>Google<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">p</span><span class="p">&gt;</span>Worked on the Pixel<span class="p">&lt;/</span><span class="nt">p</span><span class="p">&gt;</span>

<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Education<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>

<span class="cm">&lt;!-- More info --&gt;</span>
</code></pre></div>

<p>Note how <code>&lt;h3&gt;</code> is used before <code>&lt;h2&gt;</code> and <code>&lt;h1&gt;</code> is used repeatedly<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>. Issues like this makes it difficult for bots and screen readers to <em>make sense</em> your website.</p>
<h3 id="inline-styles">Inline styles</h3>
<p>Writing inline CSS can make external stylesheets harder to manage and less predictable.</p>
<p>Compare the generic styling of this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">h3</span> <span class="na">class</span><span class="o">=</span><span class="s">"highlight-color"</span><span class="p">&gt;</span>Title<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
</code></pre></div>

<p>To React using inline styles like this:</p>
<div class="codehilite"><pre><span></span><code><span class="p">&lt;</span><span class="nt">h3</span> <span class="na">style</span><span class="o">=</span><span class="s">"color: green"</span><span class="p">&gt;</span>Title<span class="p">&lt;/</span><span class="nt">h3</span><span class="p">&gt;</span>
</code></pre></div>

<p>Using inline styles overrides <em>all</em> external styles.</p>
<h3 id="broken-focus">Broken focus</h3>
<p>Focus is very easy if you lay out HTML tags properly (which they are by default). Frameworks lack context which makes it hard for them to properly manage focus.</p>
<h3 id="code-held-hostage">Code held hostage</h3>
<p>One of the <a href="https://flylib.com/books/en/2.506.1.34/1/" title="Avoid captive interfaces">tenets of Unix philosophy</a> is to "avoid captive user interfaces". This also applies to frameworks.</p>
<p>Frameworks become <em>captive user interfaces</em> when they prevent you from modifying your <em>own HTML code</em>.</p>
<p>HTML is the foundation of every website. Choosing the right HTML tags becomes difficult when frameworks completely handle this step.</p>
<h3 id="seo-crippling">SEO crippling</h3>
<p>An application that can only run in the client-side cannot serve HTML to crawlers.</p>
<h3 id="speed-and-performance-impact">Speed and performance impact</h3>
<p>If the page is rendered on the client-side, the browser has to do more work to render the page, making loading slower.</p>
<h3 id="maintainability">Maintainability</h3>
<p>Logic is often duplicated between the client and server.</p>
<h3 id="learning-curve">Learning curve</h3>
<p>Because JS frameworks go against web standards, you are always fighting an uphill battle. You have to recreate perfectly working browser functions like refreshing a page.</p>
<p>Methods employed by frameworks are experimental and are constantly changing. Web APIs are a lot more stable.</p>
<h3 id="lack-of-customization">Lack of customization</h3>
<p>You limit the amount of customization you can do with frameworks, since you already have your <a href="/posts/accessibility-is-a-framework-problem#code-held-hostage" title="Code held hostage - Accessibility is a 'framework problem'">HTML held hostage</a>.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>Ditch the frameworks. Learn web standards and why they have been put in place.</strong> Make the web a place everyone can benefit from by caring about users and their experiences.</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.netlify.com/blog/2019/02/25/accessibility-is-not-a-react-problem/" title="Accessibility is not a 'React Problem'">Accessibility is not a "React Problem"</a></li>
<li><a href="https://thenewstack.io/pivoting-from-react-to-native-dom-apis-a-real-world-example" title="Pivoting from React to Native DOM APIs - New Stack">Pivoting from React to Native DOM APIs</a></li>
</ul>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>Every HTML document should have <a href="https://www.a11yproject.com/posts/how-to-accessible-heading-structure/#one-h1" title="Accessible heading structure - a11y Project">only <strong>one</strong> <code>&lt;h1&gt;</code></a>. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Tue, 25 Jun 2024 18:29:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/accessibility-is-a-framework-problem</guid>
    </item>
    <item>
      <title>The music of typography</title>
      <link>https://www.mmhq.me/posts/the-music-of-typography</link>
      <description><![CDATA[<p><picture><img alt="Earphones resting on a sheet of musical notation" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/music-theory.webp" srcset="/static/data/images/360w/music-theory.webp 360w, /static/data/images/640w/music-theory.webp 640w, /static/data/images/1080w/music-theory.webp 1080w, /static/data/images/1280w/music-theory.webp 1280w" title="Music"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Genesis-1-25/">
    <p>And God made the beast of the earth after his kind, and cattle after their kind,
        and every thing that creepeth upon the earth after his kind: and God saw that it was good.</p>
    <cite>Genesis 1:25, The Bible</cite>
</blockquote>

<p>Recently I have been studying a lot about web design and how it affects the user experience. <strong>One topic that has proven to be important is the typography of a website.</strong></p>
<p><strong>If your website is a theater for your site visitors, then typography is the usher.</strong> It greets every visitor and makes them feel comfortable and welcome. Conversely, a poorly comported usher can set the wrong <em>tone</em> and ruin the whole show for the night.</p>
<p>In this blog post, I will be talking about how music is related to typography and how it's used to create a <em>euphonious ambiance</em> in web design.</p>
<h2 id="whats-typography">What's typography?</h2>
<p>According to <a href="https://en.wikipedia.org/wiki/Typography" title="Typography - Wikipedia">Wikipedia</a>, <strong><em>typography</em> is the art and technique of arranging type to make written language legible, readable and appealing when displayed.</strong></p>
<p>Right from the definition, it is pretty obvious how typography can affect a web user's experience. Text that is difficult to read due to arbitrary sizing or weird fonts could be very frustrating and could lead to visitors leaving a website.</p>
<p>Perhaps, what's even stranger is the fact that <strong>irregular typography could do similar damage to a user's experience as well</strong>. It's very similar to how we perceive sound: if a musician plays a wrong note or a singer sings off-key, the music's <em>flow</em> is disrupted.</p>
<p>To remedy the <em>dissonance</em>, web designers turn to <em>typographic scales</em>. But what are <em>scales</em>?</p>
<h2 id="whats-a-scale">What's a scale?</h2>
<p><strong>The word <em>scale</em> originates from the Latin word <em>scala</em>, which means <em>ladder</em> or <em>staircase</em></strong>. These <em>ladders</em> appear <em>everywhere</em>.</p>
<p>We find scales on rulers:</p>
<p><picture><img alt="Fractions of an inch represented on a scale" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/number-scale.svg" srcset="/static/data/images/360w/number-scale.svg 360w, /static/data/images/640w/number-scale.svg 640w, /static/data/images/1080w/number-scale.svg 1080w, /static/data/images/1280w/number-scale.svg 1280w" title="Number scale"></picture></p>
<p>We find scales on the color spectrum:</p>
<div class="rainbow-box"></div>

<p>We find scales in music, like the C major scale:</p>
<p><picture><img alt="A musical keyboard one octave long" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/musical-keyboard-c-major-scale.svg" srcset="/static/data/images/360w/musical-keyboard-c-major-scale.svg 360w, /static/data/images/640w/musical-keyboard-c-major-scale.svg 640w, /static/data/images/1080w/musical-keyboard-c-major-scale.svg 1080w, /static/data/images/1280w/musical-keyboard-c-major-scale.svg 1280w" title="C major scale on a musical keyboard"></picture></p>
<p>That <em>same</em> C major scale can be represented in music notation:</p>
<p><picture><img alt="The C major scale in musical notation" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/c-major-scale.svg" srcset="/static/data/images/360w/c-major-scale.svg 360w, /static/data/images/640w/c-major-scale.svg 640w, /static/data/images/1080w/c-major-scale.svg 1080w, /static/data/images/1280w/c-major-scale.svg 1280w" title="C major scale"></picture></p>
<p>That <em>same</em> C major scale can be played on the piano 🎹:</p>
<p><audio controls=""><source src="/static/data/audio/c-major-scale.mp3" type="audio/mp3"><a href="/static/data/audio/c-major-scale.mp3">C major scale</a></audio></p>
<p><strong>Typography is no different; it follows the <em>ladder pattern</em>.</strong></p>
<h2 id="musical-scales">Musical scales</h2>
<p>In music, intervals are used to build scales. An <em>interval</em> is the distance between two notes.</p>
<p>For example, the interval between <em>C</em> and <em>D</em> on the piano has a distance of 2 notes, because you have to step through 2 piano keys (<em>C</em> to <em>C♯</em>, <em>C♯</em> to <em>D</em>) to get from one to the other:</p>
<p><picture><img alt="A musical keyboard with C, C♯, and D marked" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/musical-keyboard-c-d.svg" srcset="/static/data/images/360w/musical-keyboard-c-d.svg 360w, /static/data/images/640w/musical-keyboard-c-d.svg 640w, /static/data/images/1080w/musical-keyboard-c-d.svg 1080w, /static/data/images/1280w/musical-keyboard-c-d.svg 1280w" title="C and D have a 2-key distance"></picture></p>
<p>However, the interval between <em>E</em> and <em>F</em> has a distance of 1 key (<em>E</em> to <em>F</em>):</p>
<p><picture><img alt="A musical keyboard with E and F marked" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/musical-keyboard-e-f.svg" srcset="/static/data/images/360w/musical-keyboard-e-f.svg 360w, /static/data/images/640w/musical-keyboard-e-f.svg 640w, /static/data/images/1080w/musical-keyboard-e-f.svg 1080w, /static/data/images/1280w/musical-keyboard-e-f.svg 1280w" title="E and F have a 1-key distance"></picture></p>
<p>Each interval has a name:</p>
<table>
<thead>
<tr>
<th>Interval</th>
<th>Key distance</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>unison</td>
<td>0</td>
<td>C</td>
</tr>
<tr>
<td>minor second</td>
<td>1</td>
<td>C to D♭</td>
</tr>
<tr>
<td>major second</td>
<td>2</td>
<td>C to D</td>
</tr>
<tr>
<td>minor third</td>
<td>3</td>
<td>C to E♭</td>
</tr>
<tr>
<td>major third</td>
<td>4</td>
<td>C to E</td>
</tr>
<tr>
<td>perfect fourth</td>
<td>5</td>
<td>C to F</td>
</tr>
<tr>
<td>augmented fourth</td>
<td>6</td>
<td>C to F♯</td>
</tr>
<tr>
<td>perfect fifth</td>
<td>7</td>
<td>C to G</td>
</tr>
<tr>
<td>minor sixth</td>
<td>8</td>
<td>C to A♭</td>
</tr>
<tr>
<td>major sixth</td>
<td>9</td>
<td>C to A</td>
</tr>
<tr>
<td>minor seventh</td>
<td>10</td>
<td>C to B♭</td>
</tr>
<tr>
<td>major seventh</td>
<td>11</td>
<td>C to B</td>
</tr>
<tr>
<td>octave</td>
<td>12</td>
<td>C to C</td>
</tr>
</tbody>
</table>
<p>It's obvious that these intervals can be played on a piano or any musical instrument, but did you know that the <em>same scales</em> are used in typography? Let me explain.</p>
<p>Each interval listed above has a ratio called the <a href="https://en.wikipedia.org/wiki/Just_intonation" title="Just intonation - Wikipedia">just interval</a>, which is the tuning of musical intervals as whole number ratios (such as 3:2 or 4:3) of frequencies.</p>
<table>
<thead>
<tr>
<th>Interval</th>
<th id="just-intervals">Just interval</th>
</tr>
</thead>
<tbody>
<tr>
<td>unison</td>
<td>1:1</td>
</tr>
<tr>
<td>minor second</td>
<td>16:15</td>
</tr>
<tr>
<td>major second</td>
<td>9:8</td>
</tr>
<tr>
<td>minor third</td>
<td>6:5</td>
</tr>
<tr>
<td>major third</td>
<td>5:4</td>
</tr>
<tr>
<td>perfect fourth</td>
<td>4:3</td>
</tr>
<tr>
<td>augmented fourth</td>
<td>45:32</td>
</tr>
<tr>
<td>perfect fifth</td>
<td>3:2</td>
</tr>
<tr>
<td>minor sixth</td>
<td>8:5</td>
</tr>
<tr>
<td>major sixth</td>
<td>5:3</td>
</tr>
<tr>
<td>minor seventh</td>
<td>16:9</td>
</tr>
<tr>
<td>major seventh</td>
<td>15:8</td>
</tr>
<tr>
<td>octave</td>
<td>2:1</td>
</tr>
</tbody>
</table>
<p>Using a little <em>math magic</em>, we can build typographic scales right from music intervals!</p>
<h2 id="scale-math">Scale math</h2>
<p>Mathematics is a method we use to abstract phenomena that occur in reality, so it's no surprise that mathematicians have cooked up a formula for scales. Scales follow a mathematical sequence called the <a href="https://en.wikipedia.org/wiki/Geometric_progression" title="Geometric progression - Wikipedia">geometric sequence</a>:</p>
<math display="block">
    <msub>
        <mi>a</mi>
        <mn>n</mn>
    </msub>
    <mo>=</mo>
    <mi>a</mi>
    <msup>
        <mi>r</mi>
        <mrow>
            <mi>n</mi>
            <mo>-</mo>
            <mn>1</mn>
        </mrow>
    </msup>
</math>

<p>Where <math><mi>a</mi></math> is the <em>first term</em>, <math><mi>n</mi></math> is the <em>number of terms</em>, and <math><mi>r</mi></math> is the <em>common ratio</em>.</p>
<p>In layman's terms, you have to multiply each result by a <em>common ratio</em> to get the next result.</p>
<math display="block">
    <msub>
        <mi>a</mi>
        <mn>n</mn>
    </msub>
    <mo>=</mo>
    <mi>a</mi>
    <mo>,</mo>
    <mi>a</mi>
    <mi>r</mi>
    <mo>,</mo>
    <mi>a</mi>
    <msup>
        <mi>r</mi>
        <mrow>
            <mn>2</mn>
        </mrow>
    </msup>
    <mo>,</mo>
    <mi>a</mi>
    <msup>
        <mi>r</mi>
        <mrow>
            <mn>3</mn>
        </mrow>
    </msup>
    <mo>...</mo>
</math>

<p>For instance, if my scale starts from 1 and my common ratio is 1.5, then the next value on my scale would be:</p>
<math display="block">
    <mn>1</mn>
    <mo>×</mo>
    <mn>1.5</mn>
    <mo>=</mo>
    <mn>1.5</mn>
</math>

<p>The next value on the scale would be:</p>
<math display="block">
    <mn>1.5</mn>
    <mo>×</mo>
    <mn>1.5</mn>
    <mo>=</mo>
    <mn>2.25</mn>
</math>

<p>The third value:</p>
<math display="block">
    <mn>2.25</mn>
    <mo>×</mo>
    <mn>1.5</mn>
    <mo>=</mo>
    <mn>3.375</mn>
</math>

<p>And so on.</p>
<h2 id="lets-build-typographic-scales">Let's build typographic scales 🛠️</h2>
<p>Time for a music and math mixture! First, let's build a typographic scale from the minor third interval.</p>
<p>According to the <a href="/posts/the-music-of-typography#just-intervals" title="Just interval table above">table of just intervals above</a>, the ratio for the minor third interval is 6:5, which is 1.2 in decimal.</p>
<p>Let's start our typographic scale from <code>1rem</code>. In the CSS world, this indicates an element's font size relative to the size of the root element. In reality, this usually defaults to 16 pixels in most browsers, but it may vary.</p>
<p>Using the common ratio of 1.2, let's build the minor third scale:</p>
<div class="typographic-scale">
    <p class="note-5-5 minor-third">
        <span>First note again</span>
        <math>
            <mo>(</mo>
            <mi>1.728rem</mi>
            <mo>x</mo>
            <mi>1.2</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>2.0736rem</mn>
        </math>
    </p>
    <p class="note-4-5 minor-third">
        <span>Fourth note</span>
        <math>
            <mo>(</mo>
            <mi>1.44rem</mi>
            <mo>x</mo>
            <mi>1.2</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>1.728rem</mn>
        </math>
    </p>
    <p class="note-3-5 minor-third">
        <span>Third note</span>
        <math>
            <mo>(</mo>
            <mi>1.2rem</mi>
            <mo>x</mo>
            <mi>1.2</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>1.44rem</mn>
        </math>
    </p>
    <p class="note-2-5 minor-third">
        <span>Second note</span>
        <math>
            <mo>(</mo>
            <mi>1rem</mi>
            <mo>x</mo>
            <mi>1.2</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>1.2rem</mn>
        </math>
    </p>
    <p class="note-1-5 minor-third">
        <span>First note</span>
        <math><mi>1rem</mi></math>
    </p>
</div>

<p>Voila, our first typographic scale! Visual harmony at its finest!<sup id="fnref:mantissa"><a class="footnote-ref" href="#fn:mantissa">1</a></sup></p>
<p>Now that we know how the scale looks like, let's hear how it sounds.</p>
<p>Remember, the minor third interval has a <em>key distance</em> of 3 notes. The musical notation 🎼 for our constructed scale (C - E♭ - G♭ - A - C) would look like this:</p>
<p><picture><img alt="Music notation of scale made up of minor thirds" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/minor-third-scale.svg" srcset="/static/data/images/360w/minor-third-scale.svg 360w, /static/data/images/640w/minor-third-scale.svg 640w, /static/data/images/1080w/minor-third-scale.svg 1080w, /static/data/images/1280w/minor-third-scale.svg 1280w" title="Scale of minor thirds"></picture></p>
<p>The newly constructed scale sounds like this:</p>
<p><audio controls=""><source src="/static/data/audio/minor-third-scale.mp3" type="audio/mp3"><a href="/static/data/audio/minor-third-scale.mp3">Scale of minor thirds</a></audio></p>
<p>This is what site visitors <em>hear</em> 👂 when they see 👁️ this typography.</p>
<p>The minor third scale sounds a little dark. The dark tone is prominent because the notes of the scale are close to each other and therefore cause more tension. Because the distance between the octaves is short (i.e. from <em>C</em> to <em>C</em>), the scale sounds more dissonant and solemn.</p>
<p>An example of a wider interval is the perfect fifth, with an just interval of 3:2 and a common ratio of 1.5. Let's take a look at the first five notes of the scale (C - G - D - A - E):</p>
<p><picture><img alt="Music notation of scale made up of perfect fifths" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/perfect-fifth-scale.svg" srcset="/static/data/images/360w/perfect-fifth-scale.svg 360w, /static/data/images/640w/perfect-fifth-scale.svg 640w, /static/data/images/1080w/perfect-fifth-scale.svg 1080w, /static/data/images/1280w/perfect-fifth-scale.svg 1280w" title="Scale of perfect fifths"></picture></p>
<p>With this interval (following the <a href="https://en.wikipedia.org/wiki/Circle_of_fifths" title="Circle of fifths - Wikipedia">circle of fifths</a>), you get a much higher contrast:</p>
<div class="typographic-scale">
    <p class="note-5-5 perfect-fifth">
        <span>Fifth note...</span>
        <math>
            <mo>(</mo>
            <mi>5.0625rem</mi>
            <mo>x</mo>
            <mi>1.5</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>7.59375rem</mn>
        </math>
    </p>
    <p class="note-4-5 perfect-fifth">
        <span>Fourth note</span>
        <math>
            <mo>(</mo>
            <mi>3.375rem</mi>
            <mo>x</mo>
            <mi>1.5</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>5.0625rem</mn>
        </math>
    </p>
    <p class="note-3-5 perfect-fifth">
        <span>Third note</span>
        <math>
            <mo>(</mo>
            <mi>2.25rem</mi>
            <mo>x</mo>
            <mi>1.5</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>3.375rem</mn>
        </math>
    </p>
    <p class="note-2-5 perfect-fifth">
        <span>Second note</span>
        <math>
            <mo>(</mo>
            <mi>1.5rem</mi>
            <mo>x</mo>
            <mi>1.5</mi>
            <mo>)</mo>
            <mo>=</mo>
            <mn>2.25rem</mn>
        </math>
    </p>
    <p class="note-1-5 perfect-fifth">
        <span>First note</span>
        <math><mi>1rem</mi></math>
    </p>
</div>

<p>What does it sound like?</p>
<p><audio controls=""><source src="/static/data/audio/perfect-fifth-scale.mp3" type="audio/mp3"><a href="/static/data/audio/perfect-fifth-scale.mp3">Scale of perfect fifths</a></audio></p>
<p>Beautiful and melodious!</p>
<p>Notice as the interval widens, the intervals become more <em>happy</em>, spaced out and fewer within an octave; there is more room to breathe.</p>
<p>In fact, there is so much space that the original note (C) does not repeat until 7 octaves later! Talk about space!</p>
<table>
<thead>
<tr>
<th>Scale</th>
<th>Span</th>
</tr>
</thead>
<tbody>
<tr>
<td>minor third</td>
<td>C - E♭ - G♭ - A - C</td>
</tr>
<tr>
<td>perfect fifth</td>
<td>C - G - D - A - E - B - G♭ - D♭ - A♭ - E♭ - B♭ - F - C</td>
</tr>
</tbody>
</table>
<h2 id="bottom-line">Bottom line</h2>
<ul>
<li>Music and typography share interesting traits.</li>
<li>The concept of <em>scale</em> appears across microcosms in the universe.</li>
<li>Every typographic scale that can be <em>seen</em>, can be <em>heard</em>.</li>
<li>Typography sets the <em>visual ambiance</em>:<ul>
<li>High-contrast typographic scales (like the perfect fifth scale) set a bright, happy <em>tone</em> (as it does in music) and are <em>louder</em>.</li>
<li>Medium-contrast typographic scales (like the minor third scale) are a little softer in <em>tone</em> and <em>amplitude</em>.</li>
<li>Low-contrast typograhic scales (like the minor second scale) set a more solemn tone.</li>
</ul>
</li>
<li>I use medium-contrast typography for this website.<sup id="fnref:ignorant-decision"><a class="footnote-ref" href="#fn:ignorant-decision">2</a></sup>
</li>
</ul>
<p><strong>Don't forget to listen to your typography.</strong> How does it sound visually?</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://typescale.com" title="Typescale">Typescale</a></li>
<li>
<a href="https://spencermortensen.com/articles/typographic-scale" title="Typescale">The typographic scale</a> by Spencer Mortensen</li>
<li><a href="https://utopia.fyi" title="Utopia - Fluid Responsive Design">Utopia</a></li>
</ul>
<div class="footnote">
<hr>
<ol>
<li id="fn:mantissa">
<p>Notice the resulting size values do not produce infinite decimal values (like 3.14159265359...). This plays a part as to why its sound is not overly dissonant (like a <a href="https://en.wikipedia.org/wiki/Half_diminished_scale" title="Half-diminished scale - Wikipedia">half-diminished scale</a>). <a class="footnote-backref" href="#fnref:mantissa" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:ignorant-decision">
<p>I made this decision before I knew anything about typographic scales. <a class="footnote-backref" href="#fnref:ignorant-decision" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sat, 08 Jun 2024 15:49:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/the-music-of-typography</guid>
    </item>
    <item>
      <title>How I detect metaphor</title>
      <link>https://www.mmhq.me/posts/how-i-detect-metaphor</link>
      <description><![CDATA[<p><picture><img alt="Scrabble pieces stacked on each other" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/scrabble-stack.webp" srcset="/static/data/images/360w/scrabble-stack.webp 360w, /static/data/images/640w/scrabble-stack.webp 640w, /static/data/images/1080w/scrabble-stack.webp 1080w, /static/data/images/1280w/scrabble-stack.webp 1280w" title="Letters"></picture></p>
<blockquote cite="https://www.wyliecomm.com/writing-tips/how-to-write-creative-content/how-to-write-a-metaphor/quotes-on-how-to-write-a-metaphor/">
    <p>The greatest thing by far is to be a master of metaphor.
    It is the one thing that cannot be learnt from others,
    and it is also a sign of genius.</p>
    <cite>Aristotle, in <em>Poetics</em></cite>
</blockquote>

<details>
<summary>Poem: <em>Rapper date night</em></summary>
<pre class="poem">
She wants punchlines and metaphors
But that's not what I met her for
I just came for the date
On the app she an 8
But in person I met a 4
</pre>
</details>

<p>Metaphors are nothing new: you can find them in movies, music, books and even everyday language. But recently I have become more fond of metaphor: it seems to be even more ubiquitous than it once was (if that's possible 🤔).  </p>
<p>In this blog post, I would like to discuss a method I discovered that makes it easy to detect metaphors.</p>
<h2 id="metaphor-is-all-about-lying">Metaphor is all about lying</h2>
<p>A quote by Terry Pratchett has stuck with me since I first heard it:</p>
<blockquote cite="https://www.goodreads.com/quotes/1258829-a-metaphor-is-a-kind-o-lie-to-help-people#:~:text=Sign%20Up%20Now-,A%20metaphor%20is%20a%20kind%20o'%20lie,help%20people%20understand%20what's%20true.">
    <p>A metaphor is a kind o' lie to help people understand what's true.</p>
    <cite>Terry Pratchett, Wintersmith</cite>
</blockquote>

<p>How you may ask? Well, let's take a look at some metaphors!</p>
<p>What better place to look than the book of Proverbs in the Bible:</p>
<ul>
<li>The king's heart is in the hand of the Lord. (Proverbs 21:1a)</li>
<li>The sluggard is wiser in his own conceit than seven men that can render a reason. (Proverbs 26:16)</li>
<li>The rod and reproof give wisdom: But a child let to himself bringeth his mother to shame. (Proverbs 29:15)</li>
</ul>
<p>Let's examine each closely by asking ourselves questions about each statement:</p>
<ul>
<li>Is the beating heart ❤️ of the king <em>literally</em> in the hand 🫱 of the Lord?</li>
<li>Is the sluggard <em>literally</em> wiser 🧠 than seven men that render reason?</li>
<li>Does the rod 🦯 and reproof <em>literally</em> give wisdom 👴👵?</li>
</ul>
<p>As you can see, asking these questions brings us a little closer to what the author intended to say. Each metaphor raises a question because each metaphor is a lie; they are not <em>literally</em> what they say they are, but imagining them in that sense gives us a deeper way of understanding their meanings.</p>
<h2 id="resolving-the-lies">Resolving the lies</h2>
<p>Now that we have raised questions and discovered some lies, let's figure out the truth:</p>
<ul>
<li>The king's heart is <em>not</em> the Lord's physical hand; the author implies that the Lord can control the intentions of the king.<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup>
</li>
<li>The sluggard is <em>not</em> wiser than seven men, but <em>feels</em> he is because he's lazy; he is incapable of thinking beyond what would cause him discomfort.</li>
<li>The rod and reproof <em>do not</em> <em>give</em> wisdom like a parent handing a gift to his child; wisdom is a <em>product</em> of the <em>rod and reproof</em>. The <em>rod</em> used here is not about the physical rod, but more about what it symbolizes. It symbolizes correction and order.</li>
</ul>
<h2 id="the-bottom-line">The bottom line</h2>
<blockquote cite="https://www.wyliecomm.com/writing-tips/how-to-write-creative-content/how-to-write-a-metaphor/quotes-on-how-to-write-a-metaphor/">
    <p>Metaphor lives a secret life all around us. We utter about six metaphors a minute. Metaphorical thinking is essential to how we understand ourselves and others, how we communicate, learn, discover, and invent. But metaphor is a way of thought before it is a way with words.</p>
    <cite>James Geary, author, <em>I Is an Other: The Secret Life of Metaphor and How It Shapes the Way We See the World</em></cite>
</blockquote>

<p>Sometimes, the overuse of cliché metaphors numbs us to their original effect. Knowing how to detect metaphors can help rejuvenate them in our minds once more and make understanding figurative language a breeze.</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><a href="https://www.wyliecomm.com/writing-tips/how-to-write-creative-content/how-to-write-a-metaphor/quotes-on-how-to-write-a-metaphor/" title="How to Write a Metaphor - Wylie Comm">Quotes on metaphors</a></li>
</ul>
<div class="footnote">
<hr>
<ol>
<li id="fn:1">
<p>This metaphor is a form of <a href="https://www.litcharts.com/literary-devices-and-terms/metonymy" title="Metonymy - Lit Charts">metonymy</a>. <a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>]]></description>
      <pubDate>Sat, 18 May 2024 01:24:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/how-i-detect-metaphor</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 in review</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-in-review</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<blockquote cite="https://www.brainyquote.com/quotes/edgar_allan_poe_107273?src=t_poetry">
    <p>I would define, in brief, the poetry of words as the rhythmical creation of Beauty.</p>
    <cite>Edgar Allan Poe, poet</cite>
</blockquote>

<p><a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a> has finally come to an end. Let's talk about my experience.</p>
<h2>My review of the month</h2>
<ul>
<li>It was fun. I got to write a lot more poems than I thought I was capable of writing. I wasn't able to carve out as much time as I wanted, and it did affect the quality of the poems, but I'm glad I got them out in the end.</li>
<li><strong>I learned that poetry is about beauty. Always aim for beauty when writing poems.</strong></li>
<li>I read <em>a lot</em> of poems. More than I think I have in any other month.</li>
<li>I read <em>a lot</em> of lyrics. From rap, to battle rap, to rhythm and blues, to jazz, to spoken word, I listened to the music and read the lyrics. It's interesting to see how they <em>all</em> obey the <em>laws</em> of poetry and scan well.</li>
<li>I've enjoyed the <a href="https://slate.com/culture/2024/04/drake-kendrick-lamar-diss-beef-rick-ross-future-metro-boomin-j-cole-weeknd-asap-rocky.html" title="The Biggest Names in Hip-Hop Are Embroiled in an Epic Beef. What’s Going On? - Slate">rap beefs</a> between some of my favorite mainstream artists. Very entertaining to see how words can be used to build up and tear down!</li>
</ul>
<h2 id="bottom-line">Bottom line</h2>
<p>I would like to thank <em>you the audience</em>. I'm happy I have a place to share my ideas and poems globally to all who are interested.</p>
<p>I don't really care about how large the audience is, I'm just grateful for the few that visit. Thanks! 😊</p>
<p>More poetry to come!</p>
<h2>Further reading</h2>
<p>Curious in learning classical poetry? Check out these links:</p>
<ul>
<li><a href="https://classicalpoets.org/2012/09/07/writing-classical-poetry-is-easy-technically/" title="Writing classical poetry is easy technically - Society of Classical Poets">Writing Classical Poetry is Easy Technically</a></li>
<li><a href="http://www.poetrybase.info/tips/" title="Tips for writing poetry - Poetry Base">Tips for Better Writing</a></li>
</ul>]]></description>
      <pubDate>Sat, 04 May 2024 13:57:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-in-review</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 30</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-30</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 30 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>, the finale.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/haiku/" title="Haiku - Poem Analysis">haiku</a>.</p>
<h3>NaPoWriMo</h3>
<pre class="poem">
Euphonic stanzas
Meet daily expression —
Timeless magic
</pre>

<h2>Featured poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/ballad/" title="Ballad - Poem Analysis">ballad</a> for the last day. Take the floor, Emily!</p>
<h3>Real</h3>
<p>by Emily Dickinson</p>
<pre class="poem">
I like a look of agony,
Because I know it's true;
Men do not sham convulsion,
Nor simulate a throe.

The eyes glaze once, and that is death.
Impossible to feign
The beads upon the forehead
By homely anguish strung.
</pre>]]></description>
      <pubDate>Tue, 30 Apr 2024 23:43:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-30</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 29</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-29</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 29 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://www.masterclass.com/articles/poetry-101-what-is-a-quatrain-in-poetry-quatrain-definition-with-examples" title="Quatrain - masterclass.com">quatrain</a>, from a <a href="https://www.poetizer.com" title="Poetizer Home Page">Poetizer</a> prompt.</p>
<h3>Ghost parade</h3>
<pre class="poem">
Ghost parade in the night
Seeking souls with which to unite
On the streets, marching through
Trying to find a host to use
</pre>

<h2>Featured poem</h2>
<p>A poem by another poetry vet, Robert Frost. A <a href="https://poemanalysis.com/poetic-form/terza-rima/" title="Terza Rima - Poem Analysis">terza rima</a>.</p>
<h3>Acquainted with the Night</h3>
<p>by Robert Frost</p>
<pre class="poem">
I have been one acquainted with the night.
I have walked out in rain — and back in rain.
I have outwalked the furthest city light.

I have looked down the saddest city lane.
I have passed by the watchman on his beat
And dropped my eyes, unwilling to explain.

I have stood still and stopped the sound of feet
When far away an interrupted cry
Came over houses from another street,

But not to call me back or say good-bye;
And further still at an unearthly height,
One luminary clock against the sky

Proclaimed the time was neither wrong nor right
I have been one acquainted with the night.
</pre>]]></description>
      <pubDate>Mon, 29 Apr 2024 11:52:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-29</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 28</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-28</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 28 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>An <a href="https://www.masterclass.com/articles/poetry-101-what-is-a-quatrain-in-poetry-quatrain-definition-with-examples" title="Envelope quatrain - masterclass.com">envelope quatrain</a>.</p>
<h3>Secret agent</h3>
<pre class="poem">
Invisible to cameras on the walls
I float through guarded rooms like butterflies
Disarming bombs by cutting colored wires
Slowly creep to keep from getting caught
</pre>

<h2>Featured poem</h2>
<p>A classic by Big Willie.</p>
<h3>Sonnet III</h3>
<p>by William Shakespeare</p>
<pre class="poem">
Look in thy glass and tell the face thou viewest
Now is the time that face should form another;
Whose fresh repair if now thou not renewest,
Thou dost beguile the world, unbless some mother.
For where is she so fair whose unear'd womb
Disdains the tillage of thy husbandry?
Or who is he so found will be the tomb,
Of his self-love to stop posterity?
Thou art thy mother's glass and she in thee
Calls back the lovely April of her prime;
So thou through windows of thine age shalt see,
Despite of wrinkles this thy golden time.
But if thou live, remember'd not to be,
Die single and thine image dies with thee.
</pre>]]></description>
      <pubDate>Sun, 28 Apr 2024 23:42:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-28</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 27</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-27</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 27 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>My first <a href="https://literaryterms.net/double-entendre/" title="Double entendre - literaryterms.net">double entendre</a>.</p>
<h3>Cold flow</h3>
<pre class="poem">
Flow so cold, that's why they wanna jack it/jacket
</pre>

<h2>Featured poem</h2>
<p>A poem for the inebriated among us. (Me included!)</p>
<h3>A Glass of Wine</h3>
<p>by Ella Wheeler Wilcox</p>
<pre class="poem">
"What's in a glass of wine?"
There, set the glass where I can look within.
No listen to me, friend, while I begin
And tell you what I see -
What I behold with my far-reaching eyes,
And what I know to be Below the laughing bubbles that arise
Within the glass of wine.
There is a little spirit, night and day,
That cries one word, for ever and alway;
That single word is "More!"
And whoso drinks a glass of wine, drinks him:
You fill the goblet full unto the brim,
And strive to silence him.

Glass after glass you drain to quench his thirst,
Each glass contains a spirit like the first;
And all their voices cry
Until they shriek and clamor, howl and rave,
And shout "More!" noisily,
Till welcome death prepares the drunkard's grave,
And stills the imps that rave.

That see I in the wine;
And tears so many that I cannot guess;
And all these drops are labelled with "Distress."
I know you cannot see.
And at the bottom are the dregs of shame:
Oh! it is plain to me.
And there are woes too terrible to name:
Now drink your glass of wine.
</pre>]]></description>
      <pubDate>Sat, 27 Apr 2024 22:31:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-27</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 26</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-26</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 26 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/monostitch" title="Monostitch - Poem Analysis">monostitch</a>.</p>
<h3>From scratch</h3>
<pre class="poem">
Like a contagious rash, I started from scratch
</pre>

<h2>Featured poem</h2>
<p>By Susan Jarvis Bryant, from her poetry collection, <em>Elephants Unleashed</em>.</p>
<h3>Zoom Etiquette</h3>
<p>by Susan Jarvis Bryant</p>
<pre class="poem">
When attending a conference at home in your room
On the boon of that technical app they call Zoom,
To emerge in your undies and pitch from your bed
Is a frightful faux pas that is simply ill-bred.
Never greet at a meeting in anything less
Than a brushed and flossed smile and sartorial finesse
Do not slouch on the couch, it's unseemly and rude
And don't ever appear drinking beer in the nude.
Please relinquish all fancies to fidget or fart;
Remain pert and alert and as sharp as a dart.
Any brash cyber crassness is at your expense
If you make others wince with an online offense.
You will slay the Zoom forum with polish and class
When you're minding your manners and covering your arse!
</pre>]]></description>
      <pubDate>Fri, 26 Apr 2024 05:54:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-26</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 25</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-25</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 25 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="http://www.poetrybase.info/forms/002/264.shtml" title="Sicilian Quatrain - Poetry Gnosis">Sicilian quatrain</a>, written in <a href="https://poemanalysis.com/poetic-meter/iambic-pentameter/" title="Iambic Pentameter - Poem Analysis">iambic pentameter</a>.</p>
<h3>Lighter</h3>
<pre class="poem">
Before the smoke can rise, the flame precedes;
Before the flame ignites, the finger flicks;
Before the finger flicks, the fluid feeds
The spark wheel that'll kindle fires quick.
</pre>

<h2>Featured poem</h2>
<p>One of <a href="https://www.youtube.com/watch?v=rHhaX3TSeu8" title="Motives and Thoughts by Lauryn Hill - YouTube">my favorite poems</a> from <a href="https://en.wikipedia.org/wiki/Lauryn_Hill" title="Lauryn Hill - Wikipedia">Lauryn Hill</a>, recited during <a href="https://en.wikipedia.org/wiki/Def_Poetry_Jam" title="Def Poetry Jam - Wikipedia">Def Poetry Jam</a>. It's written in iambic pentameter, each line being acephalous (i.e. missing the first weaker syllable), and each two lines forming rhyming couplets.</p>
<h3>Motives and thoughts</h3>
<p>by Lauryn Hill</p>
<pre class="poem">
Rotating bodies, confusion of sound
Negative imagery, holding us down
Social delusion, clearly constructed
Human condition, morals corrupted
Trapped in reaction, lawlessness, war
Dissatisfaction from bowels to core
Devil's technology, strategy for
Human mythologies, urban folklore
Sick of psychology, counterfeit cure
Wicked theology, robbing the poor
Scheme demonology mislead the pure
Strictly strategically studying war
Light shown in darkness, image exposed
Few can see through the new emperor's clothes
Lustful this hustle turn humans to hoes
When the blind lead the blind, just more trouble and woes
It's the mind that they chose
Its designed to stay closed
Standard of jokers, court jester logic
Sick looking cosmics, from schoolyards to college
Primitive man with civilized knowledge
System collapse and he still won't acknowledge
God is the saviour, studies behavior
Trying to fix the mix mind that he gave ya
Stiff-necked scholars on prescription meds
Wishing their problems were all in their heads
Moral dilemma, pride is the root
Misguided from youth, heart divided from truth
Egyptians and Grecians, spiritually dead
Imperially led, by the gods in their heads
Motives and thoughts
Industrial wealth
Global economy, in it for self
Heart full of madness, covered with kind
Pleasure designed to take over your mind
Furnished in godliness, painted in good
This tainted priesthood got real saints misunderstood
While classes in government, set up the veil
And cultivate minds for more mythical tales
Typical Hollywood follies good girl
While vice and corruption take over the world
Motives and thoughts
Check your motives and thoughts
Blind with the wickedness, deep in your heart
Modern day wickedness is all you've been taught
Lied to your neighbors, so you get ahead
Modern day trickery is all you've been fed
Motives and thoughts
Check your motives and thoughts
</pre>]]></description>
      <pubDate>Thu, 25 Apr 2024 00:31:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-25</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 24</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-24</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 24 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/definition/riddle/" title="Riddle - Poem Analysis">riddle</a>.</p>
<h3>Riddle</h3>
<pre class="poem">
I wear a shining, scorching crown
That causes me to sweat
And if I sweat just long enough
I shrink down to my death
</pre>

<p class="answer">Answer: Candle</p>
<h2>Featured poem</h2>
<p>A <a href="http://www.shadowpoetry.com/resources/wip/ballad.html" title="Ballad - Shadow Poetry">ballad</a> by Emily Dickinson.</p>
<h3>Beclouded</h3>
<p>by Emily Dickinson</p>
<pre class="poem">
The sky is low, the clouds are mean,
A travelling flake of snow
Across a barn or through a rut
Debates if it will go.

A narrow wind complains all day
How some one treated him;
Nature, like us, is sometimes caught
Without her diadem.
</pre>]]></description>
      <pubDate>Wed, 24 Apr 2024 00:28:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-24</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 23</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-23</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 23 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="http://www.shadowpoetry.com/resources/wip/diamante.html" title="Diamante - Shadow Poetry">diamante</a>.</p>
<h3>Hero/villain</h3>
<pre class="poem">
              hero
      selfless, noble
  saving, giving, preserving
   good, order, chaos, evil
killing, stealing, destroying
      selfish, cunning
             villain
</pre>

<h2>Featured poem</h2>
<p>A <a href="http://www.shadowpoetry.com/resources/wip/rondeau.html" title="Rondeau - Shadow Poetry">rondeau</a> by Susan Jarvis Bryant.</p>
<h3>Silence</h3>
<p>by Susan Jarvis Bryant</p>
<pre class="poem">
My silence listens to the crows
Of bloviators' blow-by-blows —
They rise in flares of air so hot
They boil and stir the bubbling pot
Of heaving sobs and howling woes.

My silence slips on tippy toes
Between the sly, melodious throes
Of crooked lines to learn what's what...
My silence listens.

My silence hears the fears of those
Bombarded by bombastic shows,
Ensnared and seared by plots that knot
The stomach with rhapsodic rot.
I have a nose for phony prose...
My silence listens.
</pre>]]></description>
      <pubDate>Tue, 23 Apr 2024 08:25:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-23</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 22</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-22</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 22 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A Monday morning <a href="https://poemanalysis.com/literary-device/couplet" title="Couplet - Poem Analysis">couplet</a> of <a href="https://poemanalysis.com/literary-device/fourteener" title="Fourteener - Poem Analysis">fourteeners</a>.</p>
<h3>Monday delivery</h3>
<pre class="poem">
If Monday were a package shipped by Amazon for free
I'll keep it wrapped and ship it back — and pay if charged a fee
</pre>

<h2>Featured poem</h2>
<p>Three cerebral <a href="http://www.shadowpoetry.com/resources/wip/triolet.html" title="Triolet - Shadow Poetry">triolets</a>.</p>
<h3>Mind Games</h3>
<p>by Susan Jarvis Bryant</p>
<pre class="poem">
<b>Propaganda</b>
    It wants your mind. It wants you blind.
    It warps and washes wayward brains.
    It gains control of humankind.
    It wants you blind. It wants your mind
    To cave, to close, no cogs to grind
    Till not one stain of you remains.
    It wants your mind. It wants you blind.
    It warps and washes wayward brains.

<b>Plot</b>
    They want you led. They want you dead.
    They're carnage cloaked in care's disguise.
    They want you cowed — afraid — unfed.
    They want you led. They want you dead.
    They wield the reaper's scythe of red.
    They suck the soul from guileless eyes.
    They want you led. They want you dead.
    They're carnage cload in care's disguise.

<b>Play</b>
    Delight n dreams and set them free
    Like butterflies and birds in flight.
    Rejoice in treasured reverie!
    Delight in dreams and set them free.
    All hope is fair and feathery;
    It rises like a wind-kissed kite.
    Delight in dreams and set them free
    Like butterflies and birds in flight.
</pre>]]></description>
      <pubDate>Mon, 22 Apr 2024 08:25:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-22</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 21</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-21</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 21 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/cinquain/" title="Cinquain - Poetic Analysis">cinquain</a>.</p>
<h3>Wind whispers</h3>
<pre class="poem">
The breeze —
A voice of peace —
Speaks, cut off by a truck —
The truck shouts and screams then leaves —
Whisper
</pre>

<h2>Featured poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/villanelle/" title="Villanelle - Poetic Analysis">villanelle</a> by Dusty Grein.</p>
<h3>Hold My Hand in Yours</h3>
<p>by Dusty Grein</p>
<pre class="poem">
Hold my hand in yours; we'll make it through.
If life becomes too hard to comprehend,
for no one understands me like you do.

Along life's lonely road, I'll walk with you.
When times are hard, please know you have a friend.
Hold my hand in yours; we'll make it through.

I'm here for you. You give me your strength too;
my courage is no longer just pretend,
for no one understands me like you do.

My friend, I'll cheer you up when you are blue,
A smile, my heart to yours will always send.
Hold my hand in yours; we'll make it through.

If I am down, you make me feel brand new
You know the way, my broken heart to mend,
for no one understands me like you do.

Through oft times life presents a horrid view,
Together we can face the bitter end.
Hold my hand in yours; we'll make it through,
for no one understands me like you do.
</pre>]]></description>
      <pubDate>Sun, 21 Apr 2024 10:49:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-21</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 20</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-20</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 20 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A riddle.</p>
<h3>Riddle</h3>
<pre class="poem">
In chemistry, you may confuse
This object for a flask —
It's made of glass and has a bowl
Attached for smoking gas
</pre>

<p class="answer">Answer: <a href="https://weedmaps.com/learn/dictionary/bong" title="What is a bong? - Weedmaps">Bong</a></p>
<h2>Featured poem</h2>
<p>A blank-verse <a href="https://classicalpoets.org/2024/01/05/kintsugi-a-poem-by-susan-jarvis-bryant/" title="Kintsugi - Classical Poets">poem</a> about a 19th century cooking pot repaired with the kintsugi technique.</p>
<h3>Kintsugi</h3>
<p>by Susan Jarvis Bryant</p>
<pre class="poem">
There is an ancient practice in Japan —
Chipped and broken vessels, dear to hearts,
Are mended with a striking golden blend.

These cracked ceramics, kissed with artistry,
Have former glory honorably restored.
Each gleaming seam adds meaning to their worth.

This emphasis of imperfection shows
The wonder of destruction and rebirth —
The value of life’s scuffs and scrapes and scars.

I know bold souls of grit and wisdom gained
Through pain. They’ve soared to reach the giddy peaks
Of triumph in a rush of cloudless blue…

Then fallen from the crest of sky-high waves.
Life’s heady heights give way to stony ground
Littered with a slew of bones and dreams.

Old souls with tales of miracles to tell
Shimmer with the luster of the East.
Here in the West worn gifts are tossed aside.

They’re shoved in cobwebbed corners, locked away
In musty rooms where memories gather dust,
And ghosts float in the sheen of unseen pearls.
</pre>]]></description>
      <pubDate>Sat, 20 Apr 2024 10:46:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-20</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 19</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-19</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 19 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A couplet for the <a href="https://en.wikipedia.org/wiki/420_(cannabis_culture)" title="420 (Cannibus culture) - Wikipedia">season</a>.</p>
<h3>Wake and bake</h3>
<pre class="poem">
Don't put it in the oven —
Alarm, don't make a sound —
Just roll it in an ashtray
And pass the blunt around
</pre>

<h2>Featured poem</h2>
<p>A <a href="https://poetscollective.org/poetryforms/kyrielle" title="Kyrielle - Poets Collective">kyrielle</a> by <a href="https://classicalpoets.org/2023/08/04/the-blame-game-and-other-poetry-by-susan-jarvis-bryant/" title="The Blame Game - Classical Poets">Susan Jarvis Bryant</a>.</p>
<h3>The Blame Game</h3>
<p>by Susan Jarvis Bryant  </p>
<pre class="poem">
They rile. They gall. They know it all.
These irksome jerks in folly’s thrall
Are perilously cretinous.
  It’s always Them. It’s never Us.

They grouse and groan. They mope and moan.
With spines of sponge and souls of stone
These gutless gripers cuss and fuss.
  It’s always Them. It’s never Us.

They’re dull of head. Their wits have fled.
Their loony lips are spewing dread—
The chunder of a blunderbuss.
  It’s always Them. It’s never Us.

These cliquey freaks who scheme and sneak
And squeak and shriek in doublespeak
Will claim our blame is scurrilous—
  It’s never Them. It’s always Us.
</pre>]]></description>
      <pubDate>Fri, 19 Apr 2024 10:52:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-19</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 18</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-18</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 18 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/haiku" title="Haiku - Poem Analysis">haiku</a>.</p>
<h3>Nature's goodness</h3>
<pre class="poem">
Plastic cup of juice —
Orange sweetness to the brim —
Made of baby carrots
</pre>

<h2>Featured poem</h2>
<p>A <a href="https://classicalpoets.org/2024/03/17/coffee-limericks-by-roy-e-peterson/" title="Coffee Limericks - Classical Poets">limerick</a>.</p>
<h3>Coffee Limericks</h3>
<p>by LTC Roy E. Peterson</p>
<pre class="poem">
I love to have coffee each morning,
Including the act of the pouring:
  I smell the aroma,
  Come out of my coma,
And wonder why you still are snoring.

I start with a coffee each day —
A creamy and sugared latte.
  I open my eyes,
  And to my surprise
I made it into the café.

I’m proud of my coffee selection;
I brew it until it’s perfection.
  I make it real strong.
  Now don’t take this wrong:
I drink it for your own protection.
</pre>]]></description>
      <pubDate>Thu, 18 Apr 2024 22:56:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-18</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 17</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-17</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 17 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/monostitch" title="Monostitch - Poem Analysis">monostitch</a>.</p>
<h3>Buffalo wings</h3>
<pre class="poem">
Ordered all those wings and you still ain't fly
</pre>

<h2>Featured poem</h2>
<p>Yet another poem by <a href="https://briefpoems.wordpress.com/" title="Brief Poems - Damian Balassone">Damian Balassone</a>.</p>
<h3>Advice from Jonah</h3>
<p>by Damian Balassone</p>
<pre class="poem">
If God is calling and you bail,
you might end up inside a whale.
</pre>]]></description>
      <pubDate>Wed, 17 Apr 2024 11:00:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-17</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 16</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-16</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 16 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/monostitch" title="Monostitch - Poem Analysis">monostitch</a>. <a href="https://www.merriam-webster.com/dictionary/braggadocio" title="Braggadocio - Merriam-Webster Dictionary">Braggadocio</a>.</p>
<h3>Rapping</h3>
<pre class="poem">
Wrapping burritos on the railroad is the only way you could rap on a track
</pre>

<h2>Featured poem</h2>
<p>Another poem by <a href="https://briefpoems.wordpress.com/" title="Brief Poems - Damian Balassone">Damian Balassone</a>.</p>
<h3>Garden of Eden</h3>
<p>by Damian Balassone</p>
<pre class="poem">
A multitude of monsters will be on the loose
if man and woman work out how to reproduce.
</pre>]]></description>
      <pubDate>Tue, 16 Apr 2024 08:56:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-16</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 15</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-15</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 15 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>. Halfway through.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/tercet" title="Tercet - Poem Analysis">tercet</a>.</p>
<h3>Soccer game</h3>
<pre class="poem">
They scored us so much I started hearing music
It was playing the whole time — 
But I was just deaf to it
</pre>

<h2>Featured poem</h2>
<p>A poem I found on a <a href="https://briefpoems.wordpress.com/" title="Brief Poems - Damian Balassone">website</a> that the official <a href="https://www.napowrimo.net" title="NaPoWriMo official website">NaPoWriMo</a> recommended.</p>
<h3>The Fall of Nebuchadnezzar</h3>
<p>by Damian Balassone</p>
<pre class="poem">
He once was king of Babylon...but now
he's drenched in dew and frolics like a cow.
</pre>]]></description>
      <pubDate>Mon, 15 Apr 2024 17:56:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-15</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 14</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-14</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 14 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poetscollective.org/everysonnet/?s=terza+rima" title="Terza Rima Sonnet - Poet's Collective">terza rima sonnet</a>.</p>
<h3>Pals with Egypt</h3>
<pre class="poem">
Israelites with evil ways — 
Though living in the Promised Land
We're still living in the Egypt days.

Pharoah did not promise land
But lashes if you slacked at work
Then God showed him his mighty hand.

Through wildernesses, lessons learnt;
A gift of real estate from God
Retired us from all our work.

But then we lusted after gods
And turned ourselves back into slaves
But this time it's a choice, though odd.

Israelites with evil ways — 
Still living in the Egypt days.
</pre>

<h2>Featured poem</h2>
<p>In this limerick, Ed Salem of Boynton Beach was addressing the rising sea levels associated with climate change.</p>
<h3>Untitled</h3>
<p>by Ed Salem</p>
<pre class="poem">
There once was a senior Floridian
who lived by the sea in oblivion
when climate change hit
his life changed a bit
and he had to become an amphibian
</pre>]]></description>
      <pubDate>Sun, 14 Apr 2024 23:39:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-14</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 13</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-13</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 13 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poetscollective.org/everysonnet/limerick-sonnet/" title="Limerick Sonnet - Poet's Collective">limerick sonnet</a>.</p>
<h3>At TSA</h3>
<pre class="poem">
They told me to put in the bin
My hoodie, my watch, and my pen
I got in the machine
The light didn't stay green
So they told me to go in again

They said that my belt was the cause
So I took my entire wear off
They said, "It'll be fast"
They expected a pass
But the machine still discovered a flaw

They claim that this problem is new
They asked if I ate any food
I said, "I eat veggies in general
Because of the minerals"
They said, "Must be the iron in you"
</pre>

<h2>Featured poem</h2>
<p>One of my <a href="https://www.tweetspeakpoetry.com/2017/04/10/irreverent-limerick-poetry-prompt/" title="Irreverent Limerick Poetry Prompt - Tweetspeak Poetry">favorite limericks</a> that got me into writing them.</p>
<h3>Untitled</h3>
<p>by Monica Sharman</p>
<pre class="poem">
Relentless, insatiable deadlines!
This manuscript’s still full of red lines.
First I’ll sweat through the edits
and check all the credits
then chill with my favorite red wine.
</pre>]]></description>
      <pubDate>Sat, 13 Apr 2024 10:51:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-13</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 12</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-12</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 12 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A couplet poem.</p>

<h3>Tired at the lobby</h3>
<pre class="poem">
I try to keep myself awake
My eyeliids want to rest
The background music's playing low —
A soft whisper at best
</pre>

<h2>Featured poem</h2>
<p>A classic.</p>
<h3>Song</h3>
<p>by Christina Rossetti</p>
<pre class="poem">
When I am dead, my dearest,
Sing no sad songs for me;
Plant thou no roses at my head,
Nor shady cypress tree:
Be the green grass above me
With showers and dewdrops wet;
And if thou wilt, remember,
And if thou wilt, forget.

I shall not see the shadows,
I shall not feel the rain;
I shall not hear the nightingale
Sing on, as if in pain:
And dreaming through the twilight
That doth not rise nor set,
Haply I may remember,
And haply may forget.
</pre>]]></description>
      <pubDate>Fri, 12 Apr 2024 10:59:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-12</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 11</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-11</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 11 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A <a href="https://poemanalysis.com/poetic-form/shakespearean-sonnet/" title="Shakespearean sonnet - Poetic Analysis">Shakespearean sonnet</a> I wrote after hearing about <a href="https://www.npr.org/2024/04/10/1243825571/rapper-j-cole-apologizes-for-kendrick-lamar-dis-track" title="J. Cole Apologizes for Kendrick Lamar Diss Track - NPR">J. Cole apologizing to Kendrick Lamar for a diss track</a> recently.</p>
<h3>From J. Fold with Love</h3>
<pre class="poem">
I never meant to diss you in my track;
The gassing up from friends made me explode.
It took some days to realize it was wack;
You know we're more than brothers on the low.

Your albums aren't bad, I take it back;
I played my hand and now I got to fold.
At first I felt like Gambit on attack;
But now I feel as powerless as Toad.

The hatchet's buied more than six feet deep;
You're the G.O.A.T. we all should truly fear.
To show you that I'm saying what I mean,
Listen to this brilliant idea:

Just so we even up the score,
Please use my diss track beat to diss me more.
</pre>

<h2>Featured poem</h2>
<p>A poem by <a href="https://poets.org/poem/how-do-i-love-thee-sonnet-43" title="How Do I Love Thee (Sonnet 43) - Poets.org">Elizabeth Barrett Browning’s Sonnet 43</a> called <em>Sonnet 43</em> was written for her husband Robert.</p>
<h3>How Do I Love Thee? (Sonnet 43)</h3>
<p>by Elizabeth Barrett Browning</p>
<pre class="poem">
How do I love thee? Let me count the ways.
I love thee to the depth and breadth and height
My soul can reach, when feeling out of sight
For the ends of Being and ideal Grace.
I love thee to the level of everyday’s
Most quiet need, by sun and candle-light.
I love thee freely, as men strive for Right;
I love thee purely, as they turn from Praise.
I love thee with the passion put to use
In my old griefs, and with my childhood’s faith.
I love thee with a love I seemed to lose
With my lost saints—I love thee with the breath,
Smiles, tears, of all my life!—and if God choose,
I shall but love thee better after death.
</pre>

<h2>Further reading</h2>
<ul>
<li><a href="https://classicalpoets.org/2018/03/03/essay-thirty-one-sonnets/" title="Thirty-one Sonnets: Renaissance to New Millennial - Classical Poets">Thirty-one Sonnets: Renaissance to New Millennial</a></li>
</ul>]]></description>
      <pubDate>Thu, 11 Apr 2024 10:56:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-11</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 10</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-10</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 10 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A couplet.</p>
<h3>Time travels</h3>
<pre class="poem">
Time moves so fast, it needs a speeding ticket
Longing for the past, need to get to the beginning
</pre>

<h2>Featured poem</h2>
<p>A shape poem I found on <a href="http://shadowpoetry.com/resources/wip/shape.html" title="Shape poem - Shadow Poetry">Shadow Poetry</a>.</p>
<h3>Birth of a Triangle</h3>
<pre class="poem">
mama and papa and baby make three,
  reaching sides of a three-sided tree.
    oedipal winds rustle from leaves;
      triangular shapes converting
         dissimilarity into peeves.
           straight lines connect
             the corners turned;
                mirrored sight
                  un-burned;
                    buried
                      am
                        i
</pre>]]></description>
      <pubDate>Wed, 10 Apr 2024 21:56:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-10</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 9</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-9</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 9 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>Quickly concocted couplets.</p>
<h3>At a snail's pace</h3>
<pre class="poem">
At a snail's pace, I gently move along
Leaving trails of slime with every step
Looking for a place, where I can belong
The shell I carry with me hurts my neck
</pre>

<h2>Featured poem</h2>
<p>A classic by <em>Ella Wheeler Wilcox</em>.</p>
<h3>Don't Drink</h3>
<p>by Ella Wheeler Wilcox</p>
<pre class="poem">
Don't drink, boys, don't!
There is nothing of happiness, pleasure, or cheer,
In brandy, in whiskey, in rum, ale, or beer.
If they cheer you when drunk, you are certain to pay
In headaches and crossness the following day.
Don't drink, boys, don't!

Boys, let it alone!
Turn your back on your deadliest enemy — Drink !
An assassin disguised; nor for one moment think,
As some rashly say, that true women admire
The man who can boast that he's playing with fire.
Boys, let it alone!

No, boys, don't drink!
If the habit's begun, stop now! stop to-day!
Ere the spirit of thirst leads you on and away
Into vice, shame, and drunkenness. This is the goal,
Where the spirit of thrirst leads the slave of the bowl.
No, boys, don't drink!

Boys, touch not, nor taste!
Don't think you can stop at the social "First Glass."
Too many have boasted that power, alas!
And found they were slaves to this seeming good friend,
And have grown into drunkards and knaves, in the end.
Boys, touch not, nor taste!

Don't drink, boys, Don't!
If loafers and idlers scoff, never heed:
True men and true women will wish you "God-speed."
There is nothing of purity, pleasure, or cheer
To be gotten from whiskey, wine, brandy, or beer.
Don't drink, boys, Don't!
</pre>]]></description>
      <pubDate>Tue, 09 Apr 2024 12:46:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-9</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 8</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-8</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 8 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A monostich.</p>
<h3>Phone bars</h3>
<pre class="poem">
Always dropping bars like I'm losing cell signal
</pre>

<h2>Featured poem</h2>
<p>A poem from <em>The Society of Classical Poets</em>.</p>
<h3>Apes or Angels</h3>
<p>by Ron L. Hodges</p>
<pre class="poem">
Humans, some say, aren't much more than an ape —
A reasoning beast, quintessence of dust.
Others believe we're of angelic shape.

Hungry for morsels, we scrabble and scrape,
Leaving the tree to indulge termite lust.
Humans, some say, aren't much more than an ape.

Yet not all dwell in this feral landscape —
Their minds are free to transcend when hearts must.
Others believe we're of angelic shape.

We squat under shadows, covet and rape,
Then flaunt our filth like a Renaissance bust.
Humans, some say, aren't much more than an ape.

Still, there are many whose spirits escape
The region where bodies settle for crust.
Others believe we're of angelic shape.

Though such a question makes all skeptics jape,
How could our good rise from matter unjust?
Humans, some say, aren't much more than an ape,
I must believe we're of angelic shape.
</pre>]]></description>
      <pubDate>Mon, 08 Apr 2024 21:00:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-8</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 7</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-7</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 7 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>From a writing prompt.</p>
<h3>Bird in a cage</h3>
<pre class="poem">
The bars of steel surrounding me
Are keeping me from flight
No space to spread my wings apart
And soar into the sky

I have to find an exit out
I have to find the key
And if I don't I'll break the bars
From picking with my beak
</pre>

<h2>Featured poem</h2>
<p>By the queen, <em>Emily Dickinson</em>.</p>
<h3>The Mountain</h3>
<p>by Emily Dickinson</p>
<pre class="poem">
The mountain sat upon the plain
In his eternal chair,
His observation omnifold,
His inquest everywhere.

The seasons prayed around his knees,
Like children round a sire:
Grandfather of the days is he,
Of dawn the ancestor.
</pre>]]></description>
      <pubDate>Sun, 07 Apr 2024 18:23:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-7</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 6</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-6</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 6 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>An attempt at braggadocio.</p>
<h3>No chance</h3>
<pre class="poem">
I petal to the metal, I'm the first — you can't contest
Even if you flip a coin, you'll never get ahead
</pre>

<h2>Featured poem</h2>
<p>A classic poem by <em>Big Willie</em>.</p>
<h3>Sonnet 18</h3>
<p>by William Shakespeare</p>
<pre class="poem">
Shall I compare thee to a summer's day?
Thou art more lovely and more temperate:
Rough winds do shake the darling buds of May,
And summer's lease hath all too short a date:
Sometimes hot the eye of heaven shines,
And often is his gold complexion dimm'd;
And every fair from fair sometime declines,
By chance or nature's chaning course untrimm'd;
But thy eternal summer shall not fade
Nor lose possession of that fair thou owest;
Nor shall Death brag though wander'st in his shade,
When in eternal lines to time thou growest:
So long as men can breathe or eyes can see,
So long lives this and this gives life to thee.
</pre>]]></description>
      <pubDate>Sat, 06 Apr 2024 09:39:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-6</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 5</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-5</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 5 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>Made my own riddle poem.</p>
<h3>Riddle</h3>
<pre class="poem">
You always look around for me
Though I'm invisible
Once found, you then connect to me
Until you're miserable
</pre>

<p class="answer">Answer: Wi-Fi</p>
<h2>Featured poem</h2>
<p>Another poem by the G.O.A.T.</p>
<h3>This World is not Conclusion</h3>
<p><em>by Emily Dickinson</em></p>
<pre class="poem">
This World is not Conclusion.
A Species stands beyond –
Invisible, as Music –
But positive, as Sound –
It beckons, and it baffles –
Philosophy – don’t know –
And through a Riddle, at the last –
Sagacity, must go –
To guess it, puzzles scholars –
To gain it, Men have borne
Contempt of Generations
And Crucifixion, shown –
Faith slips – and laughs, and rallies –
Blushes, if any see –
Plucks at a twig of Evidence –
And asks a Vane, the way –
Much Gesture, from the Pulpit –
Strong Hallelujahs roll –
Narcotics cannot still the Tooth
That nibbles at the soul –
</pre>]]></description>
      <pubDate>Fri, 05 Apr 2024 04:43:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-5</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 4</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-4</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 4 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A poem I wrote recently. Probably should have dropped it on April fool's.</p>
<h3>Perfect lover</h3>
<pre class="poem">
I took my girl to lunch today
And left my wallet home
I kept a car note on her desk
Since she'd rather be a loan

She said she wanted space to breathe
I took her to the moon
She said "It isn't working out"
I said the gym will open soon
</pre>

<h2>Featured poem</h2>
<p>A riddle poem from <em>J.R.R. Tokien's</em> <em>The Hobbit</em>.</p>
<h3>Riddle</h3>
<p>by J.R.R. Tolkien</p>
<pre class="poem">
Alive without breath,
As cold as death;
Never thirsty, ever drinking,
All in scales but never clinking.
</pre>

<p class="answer">Answer: Fish</p>]]></description>
      <pubDate>Thu, 04 Apr 2024 04:57:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-4</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 3</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-3</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 3 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>Penned this a couple days ago on a cold afternoon.</p>
<h3>Winter</h3>
<pre class="poem">
If you see me in a cotton coat
As thick as Santa's beard
With gloves on but still shivering
You know winter is here

Bought firewood to keep us warm
The cold is unforgiving
Got kerosine to start a flame
But the lighter liquid's finished!
</pre>

<h2>Featured poem</h2>
<p>Found <a href="https://www.poetrykit.org/CITN/citn%20184.htm" title="Ronnie Goodyer - Poetry Kit">this poem</a> in a poetry anthrology I own called <em>Perfect Binding</em> edited by <em>Alison and Malcolm Chisolm</em>.</p>
<h3>Let's Not Go Out On This Winter Day</h3>
<p>by Ronnie Goodyer</p>
<pre class="poem">
Let's not go out on this winter day,
the wind is shouting at the walls,
the fire won't take that long to catch,
the softness of the sofa calls.

Let's not go out on this winter day,
let's both hold still and think of ways
to travel worlds inside our heads,
refuse the places winter stays.

Let's walk through books, let's walk through poems,
visit Fern Hill and Dover Beach;
to Yeats' Lake Isle of Innisfree,
Frost's America, Homer's Greece.

Let's drink too much and let's laugh too loud,
let's find what sheer indulgence brings;
let's clink our glasses while we can
and catch each other's hiccupping!

Then let our music resound from rooms,
as we struggle to sing as one;
Landslide, Forever young,
Ruby Tuesday, Here Comes the Sun.

Let's not go out on this winter day
but well before the flames expire,
let's sink into each other's arms,
make love before our winter fire.
</pre>]]></description>
      <pubDate>Wed, 03 Apr 2024 04:57:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-3</guid>
    </item>
    <item>
      <title>How I read my webpages with Google Speech</title>
      <link>https://www.mmhq.me/posts/how-i-read-my-webpages-with-google-speech</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Acts-12-22/">
    <p>And the people gave a shout, saying, It is the voice of a god, and not of a man.</p>
    <cite>Acts 12:22, The Bible</cite>
</blockquote>

<p>I've recently been looking for a way to get the computer to read my text. I always like to hear my text read aloud, so that I could make changes if the flow isn't right.</p>
<p>I figured, "Why do it myself when I could get the computer to do it?". In this blog post, I would like to discuss how I made Google speech to work.</p>
<h2>The search for human audio</h2>
<p>My first hunch was to search for a speech engine that could just read my text. I didn't want to have to use the browser (like I've done plenty times before); I wanted to do everything entirely from the terminal.</p>
<p>I stumbled upon my heart's desires when I saw a <a href="https://askubuntu.com/questions/501910/how-to-text-to-speech-output-using-command-line" title="How to text-to-speech output using command-line? - Ask Ubuntu">post on Ask Ubuntu</a>. I tried <a href="https://manpages.ubuntu.com/manpages/trusty/man1/say.1.html" title="say - man pages"><code>say</code></a>, <a href="https://manpages.ubuntu.com/manpages/trusty/man1/festival.1.html" title="festival - man pages"><code>festival</code></a>, <a href="https://manpages.ubuntu.com/manpages/trusty/man1/spd-say.1.html" title="spd-say - man pages"><code>spd-say</code></a> and <a href="https://manpages.ubuntu.com/manpages/trusty/man1/espeak.1.html" title="espeak - man pages"><code>espeak</code></a> as text-to-speech engines. They all worked, but they all sucked; they all sounded like robots for the text they read aloud.</p>
<p>It was truly unbearable. So I scrolled. I scrolled lower and lower on the page, looking at answer after answer.</p>
<p>Until I stumbled upon what I wanted to see:</p>
<div class="codehilite"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>google_speech
google_speech<span class="w"> </span><span class="s2">"Test the hello world"</span>
</code></pre></div>

<p>A command to install the Python library for Google Speech and say the words "Test the hello world". I heard the voice of a <em>digital angel</em>. She sounded a lot more natural than any of the previous versions I've had.</p>
<p>I rushed back to my terminal from my browser to try it out. Unfornately, I had to set up a virtual environment first. (That's most annoying part of Python 🙄. I understand its use; I don't understand why it is mandated.)</p>
<p>Once I took care of the virtual environment issue, it worked! And there was no need to sign up or use API keys or anything. A double win.</p>
<p>Hear it for yourself:</p>
<div class="codehilite"><pre><span></span><code>google_speech<span class="w"> </span><span class="s2">"Hello world"</span>
</code></pre></div>

<p><audio controls=""><source src="/static/data/audio/hello-world.mp3" type="audio/mp3"><a href="/static/data/audio/hello-world.mp3">Download audio</a></audio></p>
<div class="codehilite"><pre><span></span><code>google_speech<span class="w"> </span><span class="s2">"The quick brown fox jumps over the lazy dog"</span>
</code></pre></div>

<p><audio controls=""><source src="/static/data/audio/the-quick-brown-fox.mp3" type="audio/mp3"><a href="/static/data/audio/the-quick-brown-fox.mp3">Download audio</a></audio></p>
<h2>Audible freedom</h2>
<p>With this addition, I became super-powerful. I felt like Thanos with all 5 rings and finding a sixth hidden ring just to top it off. I knew from this point on, it would be easy to use my terminal to read my text.</p>
<p>To read text from my website, I run:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>https://mmhq.me/posts/how-i-read-my-webpages-with-google-speech<span class="w"> </span><span class="p">|</span><span class="w"> </span>xmllint<span class="w"> </span>--html<span class="w"> </span>--xpath<span class="w"> </span><span class="s1">'//p/text()'</span><span class="w"> </span><span class="m">2</span>&gt;<span class="w"> </span>/dev/null<span class="w"> </span>-<span class="w"> </span><span class="p">|</span><span class="w"> </span>google_speech<span class="w"> </span>-
</code></pre></div>

<p>Simple. Let's break it down.</p>
<p>I use <code>curl</code> to open the webpage I would like to read:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>https://mmhq.me/posts/how-i-read-my-webpages-with-google-speech
</code></pre></div>

<p>I use <code>xmllint</code> to filter the HTML page downloaded by <code>curl</code>. I use XPath (the <code>//p/text()</code> part) to tell <code>xmllint</code> to print the texts of all paragraphs on the webpage:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xmllint<span class="w"> </span>--html<span class="w"> </span>--xpath<span class="w"> </span><span class="s1">'//p/text()'</span><span class="w"> </span><span class="m">2</span>&gt;<span class="w"> </span>/dev/null<span class="w"> </span>-
</code></pre></div>

<p>Then last, but not least, I tell Google Speech to read the text aloud:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>google_speech<span class="w"> </span>-
</code></pre></div>

<p>I could also save the text to an MP3 file if I desire:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>google_speech<span class="w"> </span>-o<span class="w"> </span>output.mp3<span class="w"> </span>-
</code></pre></div>

<p>The final command is all these commands piped (with <code>|</code>) to save me the extra <kbd>Enter</kbd> key strokes.</p>
<h2>Bottom line</h2>
<p><strong>Terminal is king.</strong> Also, shout out to Google for making the text-to-speech service free for all. Never thought I'd be thanking them again, maybe there still is hope in this universe.</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://blog.unrealspeech.com/google-translate-tts-api-simplified-usage-guide/" title="Google Translate TTS API Guide">Google Translate TTS API Guide</a></li>
<li>
<a href="https://pypi.org/project/google-speech" title="Google Speech TTS Python package">Google Speech TTS API Python package</a> on PyPI</li>
</ul>]]></description>
      <pubDate>Wed, 03 Apr 2024 01:21:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/how-i-read-my-webpages-with-google-speech</guid>
    </item>
    <item>
      <title>Coincidental progressive enhancement</title>
      <link>https://www.mmhq.me/posts/coincidental-progressive-enhancement</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="quote" cite="https://www.brainyquote.com/quotes/mitch_hedberg_401954">
    <p>An escalator can never break: it can only become stairs.</p>
    <p>You should never see an <em>Escalator Temporarily Out Of Order</em> sign,
    just <em>Escalator Temporarily Stairs</em>.</p>
    <p>Sorry for the convenience.</p>
    <cite>Mitch Hedberg</cite>

</blockquote>

<details>
    <summary>Poem: <em>Enhancing progressively</em></summary>
<pre class="poem">
Progressive enhancement is not a new style;
A tried and true method that's been here a while.
You'll see that your site would be easy to build;
The site users happy, your mission fulfilled.
</pre>
</details>

<p>Sometimes, I make decisions because I am well aware of what I am doing; sometimes, my decisions are completely arbitrary. (Or are they? 🤔)</p>
<p>In this blog post, I would like to discuss progressive enhancement and how I've accidentally chosen to implement it.</p>
<h2>What is progressive enhancement?</h2>
<p>Progressive enhancement, according to <a href="https://www.wikiwand.com/en/Progressive_enhancement" title="Progressive enhancement - Wikiwand">Wikiwand</a>, is a strategy in web design that puts emphasis on web content first, allowing everyone to access the basic content and functionality of a web page, while users with additional browser features or faster Internet access receive the enhanced version instead.</p>
<p>Basically, it means you build websites from the ground up, starting from your content, then the HTML code, the CSS code, and the JS code, as illustrated:</p>
<p><picture><img alt="The progressive enhancement stack" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/progressive-enhancement.svg" srcset="/static/data/images/360w/progressive-enhancement.svg 360w, /static/data/images/640w/progressive-enhancement.svg 640w, /static/data/images/1080w/progressive-enhancement.svg 1080w, /static/data/images/1280w/progressive-enhancement.svg 1280w" title="Progressive enhancement pyramid"></picture></p>
<p>It is important to remember that all websites work by default if proper (even if not perfect) HTML is used alone; CSS and JavaScript tend to break website behavior the most. In other words, <strong>all websites are responsive by default; your CSS and JavaScript code break things</strong>.</p>
<p>Progressive enhancement reduces the chances of you breaking your own site by starting you off from the bottom and working your way up.</p>
<p>In progressive enhancement, you think of the <a href="https://indieweb.org/design#UX_Before_Infrastructure" title="Indie Web - Design - UX before infrastructure">user first</a>. You ask questions like:</p>
<ul>
<li>What if images don’t load?</li>
<li>What if stylesheets don't load?</li>
<li>What if web fonts don’t render?</li>
<li>What if JavaScript fails?</li>
<li>What if a 3rd party resource blocks rendering?</li>
</ul>
<p>Some articles have even described progressive enhancement as <a href="https://www.stillbreathing.co.uk/2016/10/13/technical-credit" title="Technical credit - Still Breathing Blog">technical credit</a> (the opposite of <a href="https://en.wikipedia.org/wiki/Technical_debt" title="Technical debt - Wikipedia"><em>technical debt</em></a>).</p>
<blockquote cite="https://www.stillbreathing.co.uk/2016/10/13/technical-credit">
    <p>Technical Credit is the investment in the engineering, designing and constructing of software or systems over and above the minimum necessary effort, in anticipation of emergent properties paying dividends at a later date.</p>
</blockquote>

<h2>I've been doing it this whole time</h2>
<p>Ever since I have had a rekindled interest in the web in 2020, I have been coding all my websites from scratch using this strategy. Of course, I never knew that it was called <em>progressive enhancement</em>, and it wasn't really a strategy for me. <strong>I just did it that way because I wanted to cut out all the bloat.</strong> At the time, I was watching a lot of <a href="https://www.youtube.com/@LukeSmithxyz" title="Luke Smith's Youtube channel">Luke Smite videos</a> on YouTube and he's all about <em>software minimalism</em> and doing things yourself. I'll probably speak more about this in a future blog post.</p>
<p>I realized that I had been practicing the strategy when I read the introduction of the <a href="https://www.wikiwand.com/en/Progressive_enhancement" title="Progressive enhancement - Wikiwand">Wikiwand article</a>:</p>
<blockquote cite="https://www.wikiwand.com/en/Progressive_enhancement#Introduction">
    <p>[In progressive enhancement,] the web content is created with a markup document, geared towards the lowest common denominator of browser software functionality.</p>
    <p>If content should be revealed interactively through JavaScript, such as a collapsible navigation menu,
    this would be by default and only first hidden by JavaScript itself.</p>
    <p>The developer adds all desired functionality to the presentation and behavior of the page,
    using modern CSS, Scalable Vector Graphics (SVG), or JavaScript.</p>
</blockquote>

<p>To me, progressive enhancement is about:</p>
<ul>
<li>Making sure your website works without CSS and JavaScript because the love of them is the <em>root of all evil</em> on the web. (Yes, the equivalent of the <em>love of money</em> in the Bible.)</li>
<li>Making sure your website is <a href="https://indieweb.org/design#UX_Before_Infrastructure" title="Indie Web - Design - UX before infrastructure">accessible to all users</a>, including users with impairments of any sort.</li>
<li>Making updates to your website little by little. You don't have to get it all right the first time.</li>
<li>Following web standards.</li>
</ul>
<h2>The tension</h2>
<p>Progressive enhancement is not always easy; it involves resolving the dilemma between <em>design</em> and <em>compatibility</em>. You have to make the best choice for the users of your site so that everybody has the same experience.</p>
<p>There is also the tension of <em>bare metal</em> and <em>abstraction</em>; should I use a framework or not? Is <em>Wordpress</em> cool? What about <em>Wix</em>?</p>
<p>My advice is to stay away from those technologies.</p>
<p>From my experience, frameworks and CMS's generate a lot of bloat. They would <em>always</em> generate more code then <em>handcrafted</em> sites. This is the best courtesy you could pay to your <a href="https://indieweb.org/design#UX_Before_Infrastructure" title="Indie Web - Design - UX before infrastructure">users</a>.</p>
<p>There are also bad <em>fits</em> for creating frontends for the web. The dev tools in browsers these days are powerful enough to do any type of troubleshooting you need and come with a lot of benefits right out the box. I should probably do a blog post about this as well. (I'll add it to the never-ending pile of <em>blog post todos</em>.)</p>
<p>That being said, if you've tried it, and it's too hard, I'll say what I always say: use whatever you can use. The web is all about meeting us at our various levels so we can grow. Just be aware of the HTML, CSS and JavaScript generated by these <em>tools</em> (of bloat). These languages directly influence the speed of your page and the viewership of site audience, since all code written is downloaded to the browser before it can be run. The more the code to parse by the browser, the longer the parsing takes.</p>
<h2>Core principles of progressive enhancement</h2>
<p>They include:</p>
<ul>
<li>Basic content should be accessible to all web browsers.</li>
<li>Basic functionality should be accessible to all web browsers.</li>
<li>Sparse, semantic markup contains all content.</li>
<li>Enhanced layout is provided by externally linked CSS.</li>
<li>Enhanced behavior is provided by externally linked JavaScript.</li>
<li>End-user web browser preferences are respected.</li>
</ul>
<p>The <a href="https://www.stillbreathing.co.uk/2016/10/13/technical-credit" title="Technical credit - Still Breathing Blog">Still Breathing blog post</a> I read summarizes the principles as:</p>
<ol>
<li>Identify the core functionality.</li>
<li>Implement it using the simplest technology possible.</li>
<li>Enhance!</li>
</ol>
<p>This also breaks down to:</p>
<ul>
<li>Use standard HTML elements; let buttons be buttons and links be links.</li>
<li>Don’t rely on JavaScript (or even CSS) to deliver the core content and functionality of the page.</li>
<li>Make the raw HTML usable even if everything else fails; which means you may well need to develop server-side handling of form submission.</li>
<li>Check for support of features before attempting to use them.</li>
</ul>
<p>You should think of these points as more of a philosophy than a checklist.</p>
<h2>Benefits of progressive enhancement</h2>
<ul>
<li>
<strong>Accessibility, compatibility, and outreach</strong>: Everyone benefits; a win-win for all.</li>
<li>
<strong>Speed and efficiency</strong>: <a href="https://www.wikiwand.com/en/Tag_soup" title="Tag soup - Wikiwand">Less bloat</a> generated when writing code by hand and therefore faster loading in browsers since there is less to download.</li>
<li>
<strong>User control</strong>: The user has more control of how the page is rendered; he can turn off JavaScript in his browser or easily modify or choose a stylesheet if all code is put in its proper place.</li>
<li>
<strong>Search engine optimization (SEO)</strong>: It is really easy to optimize your code for search engines, like by using <a href="https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data" title="Intro to Structured Data - Google Search Central">structured data</a>. Great for businesses that need exposure.</li>
<li>
<strong>Resilience against failure</strong>: HTML without CSS and JavaScript is very resilient against errors; you could make mistakes in your markup and everything would <em>still be</em> rendered just fine. If the site works without CSS and JavaScript, there is a higher chance that it would work when both are present.</li>
</ul>
<h2>Bottom line</h2>
<p><strong>Remember, <a href="https://indieweb.org/design#UX_Before_Infrastructure" title="Indie Web - Design - UX before infrastructure">UX before infrastructure</a></strong>. When you enhance your websites progressively, you leave room for your user to benefit in the worse conditions and for the websites themselves to gradually grow into the <em>responsible adults</em> you've been training them to be (as proud <em>webpage parents</em>).</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://www.viget.com/articles/progressive-enhancement-benefits" title="Progressive enhancement benefits - Viget">Progressive enhancement benefits</a></li>
<li><a href="https://charandev.com/react-fragments" title="The Problem with &lt;div&gt; soup in React">The Problem with <code>&lt;div&gt;</code> soup in React</a></li>
</ul>]]></description>
      <pubDate>Tue, 02 Apr 2024 16:47:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/coincidental-progressive-enhancement</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 2</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-2</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 2 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>A sonnet I wrote for my girl when she traveled to Italy. I finished it up today.</p>
<h3>Roam in Italy</h3>
<pre class="poem">
A trip to the cathedral in Milan
Later to lake Como for a swim
Visit Venice just for parmesan
Cameras out to capture sites on film

Stop to eat when Mama Tummy grumbles
Grab a pizza, food used to appease her
Drinking wine from wooden covered tunnels
Second time in Europe since Ibiza

Train ride to Almalfi for some cooking
Gondola ride to see the home girl Florence
Climb a thousand stairs? A major footing
Rush back to the airport before boarding

A country warm enough to call my home
Guess when you go to Italy, you go to roam/Rome
</pre>

<h2>Featured poem</h2>
<p>I stumbled upon <a href="https://www.lightenup-online.co.uk/index.php/2023/issue-63-september-2023/julia-griffin-fair-dos" title="Fair Do's - Lighten Up Online">this light verse</a> while I was traversing the web.</p>
<h3>Fair Do's</h3>
<p>by Julia Griffin</p>
<pre class="poem">
Sabrina and her sister Vanity
Form two models for humanity.
Sitting by her glassy wave,
Cool Sabrina likes to save;
Hot upon the newest trend,
Vanity cries: “Spend, spend, spend!”
While Sabrina’s amber’s dropping,
Vanity imagines shopping,
Eyeing, through the silver foam,
Quite a classy golden comb.
When you need a faithful friend,
Pick Sabrina: in the end
That wise virgin is the one;
Meanwhile, Van’s a bit more fun.
</pre>]]></description>
      <pubDate>Tue, 02 Apr 2024 13:41:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-2</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 day 1</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-day-1</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<p>Day 1 of <a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">NaPoWriMo</a>.</p>
<h2>My poem</h2>
<p>First poem for the challenge. Written in short meter.</p>
<h3>Daemon possessed</h3>
<pre class="poem">
Daemon on my system
Someone call an exorcist
And bring a couple scriptures too
Preferably from Genesis

We'll trip him in his tracks
Since he's always on the run
Then cast the daemon out
Before the processing is done!
</pre>

<h2>Featured poem</h2>
<p>A personal favorite of mine. A ballad.</p>
<h3>I dwell in Possibility</h3>
<p>by Emily Dickinson</p>
<pre class="poem">
I dwell in Possibility —
A fairer House than Prose —
More numerous of Windows —
Superior — for Doors —

Of Chambers as the Cedars —
Impregnable of eye —
And for an everlasting Roof
The Gambrels of the Sky —

Of Visitors — the fairest —
For Occupation — This —
The spreading wide my narrow Hands
To gather Paradise —
</pre>]]></description>
      <pubDate>Mon, 01 Apr 2024 14:13:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-day-1</guid>
    </item>
    <item>
      <title>NaPoWriMo 2024 is (almost) here</title>
      <link>https://www.mmhq.me/posts/napowrimo-2024-is-almost-here</link>
      <description><![CDATA[<p><picture><img alt="Pen on top of an open book" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/poetry-writing.webp" srcset="/static/data/images/360w/poetry-writing.webp 360w, /static/data/images/640w/poetry-writing.webp 640w, /static/data/images/1080w/poetry-writing.webp 1080w, /static/data/images/1280w/poetry-writing.webp 1280w" title="Poetry writing"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Psalm-49-4/">
    <p>I will incline mine ear to a parable: I will open my dark saying upon the harp.</p>
    <cite>Psalm 49:4, The Bible</cite>
</blockquote>

<p>It's that time of the year again. April is <a href="http://napowrimo.net" title="NaPoWriMo Home Page"><em>National Poetry Writing Month</em></a> (or <em>NaPoWriMo</em>) in America. The simple goal of the challenge is to write 30 poems in 30 days, kinda like a 30-day exercise challenge.</p>
<p>In this blog post, I would like to discuss my history with poetry and how I intend to partake in NaPoWriMo.</p>
<h2>Isn't poetry dead?</h2>
<p><strong>No! Poetry might be buried, but it's definitely not dead.</strong> Ironic, I know. But it's true.</p>
<p>Poetry is really everywhere. <strong>Most songs we listen to, from hip-hop to country to pop, <em>still</em> adhere to the rules of poetry</strong>. They use rhyme, rhythm, metaphor, and many other poetic devices. This pretty much makes it poetry.</p>
<p>Sadly, in academia, a lot of the poems have been stripped of those devices leaving them lifeless, like a bowl of veggies with no dressing. They believe that poetry can exist without any of the poetic <em>spices</em> the audiences have grown to love. I strongly disagree with this take.</p>
<p>This is why I don't like a lot of modern poetry. I do believe there is a balance that can be struck. I see this balance all the time when I listen to <em>battle rap</em> poetry on YouTube for instance; they tell stories and make points all without leaving the tasty goods out.</p>
<p>If you are like me, fortunately there is hope. <a href="https://classicalpoets.org/" title="Society of Classical Poets">Classical poetry</a> still exist in many circles. You can help keep the art alive by writing your own poems too. It really doesn't take a lot of effort, just more of getting used to.</p>
<p>Let's <em>resurrect</em> poetry together!</p>
<h2 id="poetry-and-i-go-way-back">Poetry and I go way back...</h2>
<p>The first poem I heard that got me real interested in poetry was <strong>a poem by <em>Thad Langenberg</em> called <em>A Birthday Gift</em></strong>. I was uncertain what was so captivating about it. Here's the poem:</p>
<h3>A Birthday Gift</h3>
<pre class="poem">
She lived a life of solitude.
She lived a life in vain.
She lived a life in which there was
A strong, ongoing pain.

She had no friends on which to lean
And cry her problems to.
She had no friends to give her love
And hope and kindness, too.

She thought about it day and night;
She lay upon her bed.
Her mind made up, she grabbed a gun
And put it to her head.

Just then a ring came from the phone.
She pulled the gun away.
Her mom was on the other end
And wanted just to say.

"Happy Birthday, my dear girl.
Today is just for you.
I care for you with all my heart,
I hope you know that's true."

These words ran through her mind so much.
The gun was down for good.
She changed her mind about her life
And then she changed her mood.

She thought about this special day
And what her mom had said.
The gift her mm gave her that day
Was the gift of life, again.
</pre>

<p>A real charmer, huh? I read this poem when I was about 10 years old. I wouldn't be reintroduced to poetry until 2021, when I was reading the Bible. It was interesting to me that over a third of the Bible was written in poetry. Reading the Psalms got me interested again. What can I say, David has a way with words!</p>
<p>From that point, I started doing a lot of research on poetry. I read poems from various poets, some of which have become my favorites like Emily Dickinson, Ella Wheeler Wilcox, William Shakespeare and Alison Chisolm. I also discovered poetry had been <em>done dirty</em> the same way the gospel had. <strong>People have redefined what poetry is, leaving it to have no meaning, just like they did the gospel.</strong></p>
<p>Now, I don't say any of this to gatekeep; I'm not the one to say what is poetry and what is not. But to say that a poem with rhyme sounds the same as a poem without would be disingenous at best and delusional at worst. I'm <em>not</em> saying rhyme is necessary because it's not. What I <em>am</em> saying is that <strong><em>all</em> formal poetry in English uses rhyme except blank verse and free verse 😐.</strong> I think that decision by English poets was intentional.</p>
<p>So, to reiterate, poetry is not dead, and it won't stop breathing till the world ends.</p>
<h2>It's time to celebrate</h2>
<p>This April, I intend to celebrate poetry by joining the challenge; I will be writing a poem everyday. Here are some arbitrary rules to govern my goal:</p>
<ul>
<li>The poems don't have to be formal.</li>
<li>The poems can be of any length.</li>
<li>It's a one-time challenge (i.e. I don't have to commit to doing the challenge yearly).</li>
</ul>
<p>I guess you could say these are more of exceptions than rules lol. </p>
<p>I would also be posting some of my favorite poems from other poets along with mine.</p>
<h2>Bottom line</h2>
<p>Poetry should be celebrated; it is responsible for innovation in language. English wouldn't be where it is today without it (from Shakespeare to Dickinson to Eminem).</p>
<p>In summary, <strong>poetry is dead, long live poetry 👑!</strong></p>
<h2>Further reading</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/National_Poetry_Writing_Month" title="NaPoWriMo - Wikipedia">National Poetry Writing Month on Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/National_Poetry_Month" title="National Poetry Month - Wikipedia">National Poetry Month on Wikipedia</a></li>
<li>
<a href="https://www.gutenberg.org/files/12242/12242-h/12242-h.htm" title="Emily Dickinson Poems"><em>Poems: Three Series, Complete</em></a> by <em>Emily Dickinson</em>
</li>
<li><a href="https://www.napowrimo.net/faq/" title="FAQs - NaPoWriMo">FAQs on NaPoWriMo</a></li>
</ul>]]></description>
      <pubDate>Sun, 31 Mar 2024 04:01:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/napowrimo-2024-is-almost-here</guid>
    </item>
    <item>
      <title>HSL over RGB (and hex)</title>
      <link>https://www.mmhq.me/posts/hsl-over-rgb-and-hex</link>
      <description><![CDATA[<p><picture><img alt="Color pencils of different lengths on a table" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/color-pencils.webp" srcset="/static/data/images/360w/color-pencils.webp 360w, /static/data/images/640w/color-pencils.webp 640w, /static/data/images/1080w/color-pencils.webp 1080w, /static/data/images/1280w/color-pencils.webp 1280w" title="Color pencils"></picture></p>
<blockquote cite="https://www.goodreads.com/quotes/273346-the-best-colour-in-the-whole-world-is-the-one">
    <p>The best color in the whole world is one that looks good on you.</p>
    <cite>Coco Chanel</cite>
</blockquote>

<p>Which is better, HSL, RGB or hex? In this blog post, I will be exploring each of the common color representations in CSS.</p>
<h2 id="representing-the-colors-of-the-rainbow">Representing the colors of the rainbow</h2>
<p>There are various ways to represent color in CSS:</p>
<ul>
<li>
<strong>RGB</strong>: <em>RGB</em> stands for <em>red</em>, <em>green</em>, and <em>blue</em>. These three colors can be used to make up ever other color.</li>
<li>
<strong>Hex</strong>: <em>Hex</em> stands for <em>hexidecimal</em>, the format the color values are stored in. To get the hex value of any color, you must convert each value in the RGB to the hexidecimal format.</li>
<li>
<strong>HSL</strong>: <em>HSL</em> stands for <em>hue</em>, <em>saturation</em> and <em>lightness</em>. More on this later.</li>
</ul>
<p>These are just a few, but these are the only ones I care about.</p>
<h2 id="the-problem-with-rgb-and-hex">The problem with RGB and hex</h2>
<p>I've always used hex values when writing colors in code. Out of all the color representations, it's the shortest:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">rgb</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nb">rgb</span><span class="p">(</span><span class="mi">250</span><span class="w"> </span><span class="mi">142</span><span class="w"> </span><span class="mi">50</span><span class="p">);</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">hsl</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">28</span><span class="w"> </span><span class="mi">95</span><span class="kt">%</span><span class="w"> </span><span class="mi">59</span><span class="kt">%</span><span class="p">);</span>
<span class="p">}</span>

<span class="p">.</span><span class="nc">hex</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">color</span><span class="p">:</span><span class="w"> </span><span class="mh">#fa8e32</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div>

<p>Technically, it was created to be the shortest; hex values are RGB values in the hexidecimal format. The hexidecimal format is usually shorter to write than its binary or octal counterparts, so I could see why it is used for representing color:</p>
<table>
<thead>
<tr>
<th>The number 245</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Value in binary</td>
<td>11110101 (8 digits)</td>
</tr>
<tr>
<td>Value in octal</td>
<td>365 (3 digits)</td>
</tr>
<tr>
<td>Value in hex</td>
<td>F5 (2 digits)</td>
</tr>
</tbody>
</table>
<p>But are hex values the best representation simply because they are shorter?</p>
<p>Take for instance, what color do you imagine when you see <code>#ff8cab</code><span class="dot" style="color: #ff8cab"></span> or <code>#d0bdf0</code><span class="dot" style="color: #d0bdf0"></span>? Of course they are the <em>shorter</em> hex values but what can we as humans make of those values?</p>
<p>Or, using RGB, what colors does <code>rgb(194 33 205)</code><span class="dot" style="color: rgb(194 33 205)"></span> or <code>rgb(93 161 247)</code><span class="dot" style="color: rgb(93 161 247)"></span> bring to mind? Would you know that <code>#eaed20</code><span class="dot" style="color: #eaed20"></span> and <code>rgb(234 237 32)</code><span class="dot" style="color: rgb(234 237 32)"></span> are the same color?</p>
<p>As you can see, <strong>hex and RGB aren't <em>human-readable</em>; they require a <em>machine</em> to visualize</strong>. Is there a way to write colors in a way that can be visualized but us mere humans?</p>
<h2 id="hsl-to-the-rescue">HSL to the rescue!</h2>
<p>HSL solves our readability problem. How? I saw the solution in a <a href="https://stackoverflow.com/questions/26059228/css-hsl-or-rgba-colors" title="CSS - HSL or RGBA Colors - Stack Overflow">Stack Overflow answer</a> where they illustrated a color wheel:</p>
<p><picture><img alt="Color wheel" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/color-wheel.webp" srcset="/static/data/images/360w/color-wheel.webp 360w, /static/data/images/640w/color-wheel.webp 640w, /static/data/images/1080w/color-wheel.webp 1080w, /static/data/images/1280w/color-wheel.webp 1280w" title="Color wheel"></picture></p>
<p><strong>NOTE: As corrected in the original Stack Overflow answer, the angle for blue here should be 240°, not 270°.</strong></p>
<p>HSL stands for <em>Hue</em>, <em>Saturation</em> and <em>Lightness</em>.</p>
<p><strong>Hue</strong>  is a pure color without tint or shade like red, green, blue etc. Its value is represented in degrees, from 0 to 360.</p>
<p><strong>Saturation</strong> is how much hue is visible. Its value is represented as a percentage; 0% saturation displays dull gray, 100% saturation displays the hue.</p>
<p><strong>Lightness</strong> is how much whiteness is visible. Its value is represented as a percentage (like saturation); 0% lightness displays pure black, 100% lightness displays pure white.</p>
<p><picture><img alt="Saturation and lightness" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/saturation-lightness.webp" srcset="/static/data/images/360w/saturation-lightness.webp 360w, /static/data/images/640w/saturation-lightness.webp 640w, /static/data/images/1080w/saturation-lightness.webp 1080w, /static/data/images/1280w/saturation-lightness.webp 1280w" title="Saturation and lightness"></picture></p>
<p>Using this knowledge, its a lot easier to visualize colors from looking at its HSL value. Take for instance, the color <code>#e9520c</code><span class="dot" style="color: #e9520c"></span>:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Value<span class="dot" style="color: #e9520c"></span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Hex</strong></td>
<td><code>#e9520c</code></td>
</tr>
<tr>
<td><strong>RGB</strong></td>
<td><code>rgb(233 82 12)</code></td>
</tr>
<tr>
<td><strong>HSL</strong></td>
<td><code>hsl(19 90% 50%)</code></td>
</tr>
</tbody>
</table>
<p>If we wanted to mix a bit of white into the color (<code>#f7996e</code><span class="dot" style="color: #f7996e"></span>), the new value would become completely different:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Old value<span class="dot" style="color: #e9520c"></span>
</th>
<th>New value<span class="dot" style="color: #f7996e"></span>
</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Hex</strong></td>
<td><code>#e9520c</code></td>
<td><code>#f7996e</code></td>
</tr>
<tr>
<td><strong>RGB</strong></td>
<td><code>rgb(233 82 12)</code></td>
<td><code>rgb(247 153 110)</code></td>
</tr>
<tr>
<td><strong>HSL</strong></td>
<td><code>hsl(19 90% 48%)</code></td>
<td><code>hsl(19 90% 70%)</code></td>
</tr>
</tbody>
</table>
<p>The only exception is the HSL value, which changed merely from <code>hsl(19 90% 48%)</code><span class="dot" style="color: hsl(19 90% 48%)"></span> to <code>hsl(19 90% 70%)</code><span class="dot" style="color: hsl(19 90% 70%)"></span>. As a human (at least from the last time I checked), I can easily tell that the new color is the same, just slightly darker; this analysis is impossible with the equivalent hex and RGB values.</p>
<p>I could also analyze the color as a whole: <code>19</code> represents 19°, which evaluates to <em>orange</em> from looking at the color wheel; <code>90%</code> means that the color is closer to the hue than it is to dull gray; <code>48%</code> means that the color is closer to black than it is white.</p>
<p>Reading colors this way makes me feel like a color guru!</p>
<h2 id="bonus-feature-relative-values-in-css">Bonus feature: relative values in CSS</h2>
<p>CSS allows for the use of relative values to determine HSL values:</p>
<div class="codehilite"><pre><span></span><code><span class="nt">hsl</span><span class="o">(</span><span class="nt">from</span><span class="w"> </span><span class="nt">green</span><span class="w"> </span><span class="nt">h</span><span class="w"> </span><span class="nt">s</span><span class="w"> </span><span class="nt">l</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">5</span><span class="o">)</span>
<span class="nt">hsl</span><span class="o">(</span><span class="nt">from</span><span class="w"> </span><span class="p">#</span><span class="nn">0000FF</span><span class="w"> </span><span class="nt">h</span><span class="w"> </span><span class="nt">s</span><span class="w"> </span><span class="nt">calc</span><span class="o">(</span><span class="nt">l</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nt">20</span><span class="o">))</span>
<span class="nt">hsl</span><span class="o">(</span><span class="nt">from</span><span class="w"> </span><span class="nt">rgb</span><span class="o">(</span><span class="nt">200</span><span class="w"> </span><span class="nt">0</span><span class="w"> </span><span class="nt">0</span><span class="o">)</span><span class="w"> </span><span class="nt">calc</span><span class="o">(</span><span class="nt">h</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nt">30</span><span class="o">)</span><span class="w"> </span><span class="nt">s</span><span class="w"> </span><span class="nt">calc</span><span class="o">(</span><span class="nt">l</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nt">30</span><span class="o">))</span>
</code></pre></div>

<p>What this means is that you can get the <code>h</code>, <code>s</code> and <code>l</code> from any color and manipulate it. For instance, for the first example:</p>
<div class="codehilite"><pre><span></span><code><span class="nt">hsl</span><span class="o">(</span><span class="nt">from</span><span class="w"> </span><span class="nt">green</span><span class="w"> </span><span class="nt">h</span><span class="w"> </span><span class="nt">s</span><span class="w"> </span><span class="nt">l</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">5</span><span class="o">)</span>
</code></pre></div>

<p>Green would have the HSL value of <code>hsl(120, 100%, 25%)</code><span class="dot" style="color: hsl(120, 100%, 25%)"></span>. This means that <code>h</code> would evaluate to <code>120</code>, <code>s</code> to <code>100</code> and <code>l</code> to <code>25</code>. Those values can be manipulated with CSS functions like <code>calc()</code> to tweak values. For instance, if I wanted the green color to have 20% less saturation, I could do this:</p>
<div class="codehilite"><pre><span></span><code><span class="nt">hsl</span><span class="o">(</span><span class="nt">from</span><span class="w"> </span><span class="nt">green</span><span class="w"> </span><span class="nt">h</span><span class="w"> </span><span class="nt">calc</span><span class="o">(</span><span class="nt">s</span><span class="w"> </span><span class="nt">-</span><span class="w"> </span><span class="nt">20</span><span class="o">)</span><span class="w"> </span><span class="nt">l</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nt">0</span><span class="p">.</span><span class="nc">5</span><span class="o">)</span>
</code></pre></div>

<p>Pretty intuitive!</p>
<h2 id="the-css-color-wheel">The CSS color wheel</h2>
<p>Creating a color wheel is easy in CSS with our knowledge of HSL:</p>
<div class="css-color-wheel"></div>

<p>The CSS code?</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">css-color-wheel</span><span class="w"> </span><span class="p">{</span>
<span class="w">    </span><span class="k">width</span><span class="p">:</span><span class="w"> </span><span class="mi">250</span><span class="kt">px</span><span class="p">;</span>
<span class="w">    </span><span class="k">aspect-ratio</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<span class="w">    </span><span class="k">margin</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="kc">auto</span><span class="p">;</span>
<span class="w">    </span><span class="k">clip-path</span><span class="p">:</span><span class="w"> </span><span class="nb">circle</span><span class="p">(</span><span class="n">closest</span><span class="nv">-side</span><span class="p">);</span>
<span class="w">    </span><span class="k">background</span><span class="p">:</span><span class="w"> </span><span class="nf">conic-gradient</span><span class="p">(</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">360</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">315</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">270</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">225</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">180</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">135</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">90</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">45</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">),</span>
<span class="w">      </span><span class="nb">hsl</span><span class="p">(</span><span class="mi">0</span><span class="w"> </span><span class="mi">100</span><span class="kt">%</span><span class="w"> </span><span class="mi">50</span><span class="kt">%</span><span class="p">)</span>
<span class="w">    </span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div>

<p>Simple! In summary, <a href="https://codepen.io/brundolf/full/gRaREv" title="CSS is awesome - Code Pen">CSS is awesome</a>!</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>Ditch RGB and hex in CSS; use HSL</strong>. You make your code so much more readable and the values become more familiar with continuous use.</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://99designs.com/blog/tips/the-7-step-guide-to-understanding-color-theory" title="Color theory - 99 designs">Color theory on 99 designs</a></li>
<li><a href="https://blog.hubspot.com/marketing/color-theory-design" title="Color theory - Hubspot">Color theory on Hubspot</a></li>
</ul>]]></description>
      <pubDate>Fri, 29 Mar 2024 01:03:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/hsl-over-rgb-and-hex</guid>
    </item>
    <item>
      <title>SQLite vs the filesystem</title>
      <link>https://www.mmhq.me/posts/sqlite-vs-filesystem</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Psalm-37-16/">
    <p><span>16</span>
    A little that a righteous man hath is better than the riches of many wicked.
    </p>
    <p><span>17</span>
    For the arms of the wicked shall be broken: but the LORD upholdeth the righteous.
    </p>
    <cite>Psalm 37:16-17, The Bible</cite>
</blockquote>

<p>I know it seems like I'm beating a dead horse at this point, but I must say, I'm loving every moment of it. Not necessarily because I like to shit on SQL (though I do), but because I am currently enjoying the benefits of avoiding the language completely.</p>
<p>Take for instance this website. I am building it from scratch without using a single line of SQL. In fact, recently I made some changes to my website and it was relatively easy to change and test afterwards compared to SQL.</p>
<p>In this blog post, <strong>I would like SQLite and the filesystem to go head-to-head</strong> to see who the real champion of the database management system (DBMS) space is. I will compare the current way I'm doing things to how I would have done them with SQLite.</p>
<p>Without further ado, let the punching begin! 🥊</p>
<h2>Referee's banter</h2>
<p><b>Referee:</b> <em>Okay boys, I want a nice clean fight, and by clean, I mean foul and rough. I want no holding back. Teeth missing, ribs cracked, lungs being coughed out, the whole nine yards, capice? Let's give the audience what they asked for tonight!</em></p>
<h2>Round 1: Database creation</h2>
<p>Using SQLite:</p>
<div class="codehilite"><pre><span></span><code><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">IF</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">EXISTS</span><span class="w"> </span><span class="n">posts</span><span class="w"> </span><span class="p">(</span>
<span class="w">    </span><span class="n">id</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="w"> </span><span class="n">AUTOINCREMENT</span><span class="p">,</span>
<span class="w">    </span><span class="n">title</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span>
<span class="w">    </span><span class="n">category</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span>
<span class="w">    </span><span class="n">content</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span>
<span class="w">    </span><span class="n">banner</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span>
<span class="w">    </span><span class="n">link</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span>
<span class="w">    </span><span class="n">preamble</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span>
<span class="w">    </span><span class="k">public</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="k">TRUE</span><span class="p">,</span>
<span class="w">    </span><span class="n">hidden</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="k">FALSE</span><span class="p">,</span>
<span class="w">    </span><span class="n">date_published</span><span class="w"> </span><span class="k">TIMESTAMP</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="k">CURRENT_TIMESTAMP</span>
<span class="p">)</span>
</code></pre></div>

<p>Using the filesystem (i.e. GNU core utils):</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>mkdir<span class="w"> </span>-p<span class="w"> </span>data/posts
</code></pre></div>

<p>Some observations:</p>
<ul>
<li>SQLite requires you to know information about your data types up front. The filesystem does not have this limitation since it does not use many types. Data integrity could be compromised but the possibility is low since I fill this out manually in my Markdown file.</li>
</ul>
<p><b>Commentator:</b> What a blow by filesystem! SQLite did not see that swift right cross coming, but he's still on his feet!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Round 2: Database population</h2>
<p>Using SQLite:</p>
<div class="codehilite"><pre><span></span><code><span class="c1">-- After writing the blog post in 'sql-sucks.md'</span>

<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">posts</span><span class="w"> </span><span class="p">(</span>
<span class="w">    </span><span class="n">title</span><span class="p">,</span>
<span class="w">    </span><span class="n">category</span><span class="p">,</span>
<span class="w">    </span><span class="n">content</span><span class="p">,</span>
<span class="w">    </span><span class="n">banner</span><span class="p">,</span>
<span class="w">    </span><span class="n">link</span><span class="p">,</span>
<span class="w">    </span><span class="n">preamble</span>
<span class="p">)</span><span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span>
<span class="w">    </span><span class="s1">'SQL sucks!'</span><span class="p">,</span>
<span class="w">    </span><span class="s1">'General'</span><span class="p">,</span>
<span class="w">    </span><span class="s1">'It really does!'</span><span class="p">,</span>
<span class="w">    </span><span class="s1">'images/sql-burning-in-fire.webp'</span><span class="p">,</span>
<span class="w">    </span><span class="s1">'/posts/sql-sucks'</span><span class="p">,</span>
<span class="w">    </span><span class="s1">'This is an introduction'</span>
<span class="p">)</span>
</code></pre></div>

<p>Using the filesystem:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span><span class="c1"># After writing the blog post in 'sql-sucks.md'</span>
$<span class="w"> </span>cp<span class="w"> </span>sql-sucks.md<span class="w"> </span>data/posts
</code></pre></div>

<p>This works because all the metadata that I would usually keep in the SQL database is at the top of the file already. This concept is so widely used in real life applications. The concept I'm referring to is the <em>head-body</em> concept, though that is not the <em>official</em> name.</p>
<p>The concept of that <em>head</em> and <em>body</em> parallels <em>heaven</em> and <em>earth</em> (as I mentioned in my <a href="/posts/the-audacity-of-yin-yang" title="The audacity of yin-yang - MMHQ"><em>yin-yang</em></a> post), though I don't want to focus on that now. What I <em>do</em> want to focus on is how data in files are usually stored with some <em>header information</em> (i.e. head) before the content (i.e. body). We see this in music files (MP3, AAC, WMV), video files (MP4, MPEG, AVI), documents (XML, HTML, SVG) and so many other places.</p>
<p>Therefore, I just copy the same formula here; all Markdown files contain all their metadata. This makes it easy to <em>query</em> in the future, as we will see later.</p>
<p><b>Commentator:</b> Straight punch to the gut by filesystem! SQLite is coughing out blood now!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Round 3: Database query</h2>
<p>Using SQLite:</p>
<div class="codehilite"><pre><span></span><code><span class="k">SELECT</span><span class="w"> </span><span class="n">id</span><span class="p">,</span>
<span class="w">    </span><span class="n">title</span><span class="p">,</span>
<span class="w">    </span><span class="n">category</span><span class="p">,</span>
<span class="w">    </span><span class="n">content</span><span class="p">,</span>
<span class="w">    </span><span class="n">banner</span><span class="p">,</span>
<span class="w">    </span><span class="n">link</span><span class="p">,</span>
<span class="w">    </span><span class="n">preamble</span><span class="p">,</span>
<span class="w">    </span><span class="k">public</span><span class="p">,</span>
<span class="w">    </span><span class="n">hidden</span><span class="p">,</span>
<span class="w">    </span><span class="n">date_published</span>
<span class="w">    </span><span class="k">FROM</span><span class="w"> </span><span class="n">posts</span>
<span class="w">    </span><span class="k">LIMIT</span><span class="w"> </span><span class="mi">10</span>
</code></pre></div>

<p>Querying with the filesystem is a little different. The whole purpose of using the filesystem is customization and <em>vendor lock-in prevention</em>. That being said, I had to build my database management system API from scratch so it took a little longer than it would take for a SQL database, admittedly. However, when I was done, I came up with this:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>python
&gt;&gt;&gt;<span class="w"> </span>from<span class="w"> </span>app.database<span class="w"> </span>import<span class="w"> </span>Database
&gt;&gt;&gt;<span class="w"> </span><span class="nv">db</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>Database<span class="o">()</span>
&gt;&gt;&gt;<span class="w"> </span><span class="nv">posts</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>db.posts.previews.get<span class="o">(</span><span class="nv">limit</span><span class="o">=</span><span class="m">10</span><span class="o">)</span>
&gt;&gt;&gt;<span class="w"> </span>posts<span class="o">[</span><span class="m">0</span><span class="o">]</span>.title
<span class="s1">'SQLite vs the filesystem'</span>
</code></pre></div>

<p>A couple things to unravel here:</p>
<ul>
<li>I created a <em>node</em> system for my database where each node represents a point of data, like a tree. Under <code>db</code> is <code>posts</code> and under that is <code>previews</code>.</li>
<li>The action verbs chosen for each node are based on (or more accurately, stolen from) HTTP request methods (GET, POST, PUT, DELETE). This parallels <em>CRUD</em> (Create, Read, Update, Delete) for databases.</li>
<li>Note that <code>previews</code> are different from <code>posts</code>. <code>previews</code> are the summarized versions of the posts (for my home page), while <code>posts</code> are the full posts.</li>
<li>The data can instantly be accessed by switching to my website's root directory and starting a <code>python</code> session.</li>
<li>I can add new database API as I go (i.e. progressively).</li>
</ul>
<p><b>Commentator:</b> A swift uppercut from the filesystem throws SQLite back a couple steps! He is really in a daze!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Round 4: Data manipulation</h2>
<p>In SQLite:</p>
<div class="codehilite"><pre><span></span><code><span class="k">UPDATE</span><span class="w"> </span><span class="n">posts</span><span class="w"> </span><span class="k">SET</span><span class="w"> </span><span class="n">title</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'SQL - Stupid Query Language'</span><span class="p">,</span>
<span class="w">    </span><span class="n">description</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'A query language'</span>
<span class="w">    </span><span class="k">WHERE</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
</code></pre></div>

<p>For the filesystem, I could open any file directly and make the update. If I wanted to update multiple files, <code>sed</code> comes to my rescue: </p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sed<span class="w"> </span>-i<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/#\s+(.*)/SQL - Stupid Query Language/g"</span><span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/^(Description:)\s+(.*)/\1\sA query language/g"</span><span class="w"> </span>blog-post-in-question.md
</code></pre></div>

<p>Using <code>sed</code> is just one way. There are other programs, both terminal and graphical applications, that can search through text files. So don't let the <code>sed</code> script scare you; the point is that you can use whatever you want since each Markdown is a plain old text file.</p>
<p><b>Commentator:</b> Just when you thought SQLite was out of the match, he's fighting back! Way to go landing his first haymaker of the fight!</p>
<p><b>Round winner:</b> SQLite (since it's a bit less cryptic)</p>
<h2>Round 5: Data deletion</h2>
<p>In SQLite:</p>
<div class="codehilite"><pre><span></span><code><span class="k">DELETE</span><span class="w"> </span><span class="n">posts</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
</code></pre></div>

<p>In the filesystem:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>rm<span class="w"> </span>data/posts/sql-sucks.md
</code></pre></div>

<p><b>Commentator:</b> SQLite is still standing, but the filesystem is still swinging his fists!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Round 6: Database alteration</h2>
<p>Adding a column in SQLite:</p>
<div class="codehilite"><pre><span></span><code><span class="k">ALTER</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">posts</span><span class="w"> </span><span class="k">ADD</span><span class="w"> </span><span class="k">COLUMN</span><span class="w"> </span><span class="n">date_updated</span><span class="w"> </span><span class="k">TIMESTAMP</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="k">NULL</span><span class="p">;</span>
</code></pre></div>

<p>Sadly, all your information has to be uniform. You cannot have more fields for one post than others. This may be desired in some applications, but specifically with this website, I don't care to have that restriction.</p>
<p>For the filesystem, I just open the file in question in my favorite editor and change its metadata:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>vim<span class="w"> </span>sql-sucks.md
</code></pre></div>

<p>Each column in the SQLite database would represent a metadata field in the file. In my Markdown file, I have it like this:</p>
<div class="codehilite"><pre><span></span><code>Title: SQL sucks
Description: The many reasons SQL sucks
Published: 2024-03-15 00:12

<span class="gh"># SQL sucks</span>

It really does.
</code></pre></div>

<p>So to add the field <code>Updated</code>, I need to add it to my file:</p>
<div class="codehilite"><pre><span></span><code>Title: SQL sucks
Description: The many reasons SQL sucks
Published: 2024-03-15 00:12
Updated: 2024-03-15 16:37

<span class="gh"># SQL sucks</span>

It really does.
</code></pre></div>

<p><b>Commentator:</b> SQLite should change his name to beat, battered and bruised!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Round 7: Database dump</h2>
<p>In SQLite:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sqlite3<span class="w"> </span>data.db<span class="w"> </span>.dump<span class="w"> </span>&gt;<span class="w"> </span>dump.sql
</code></pre></div>

<p>For the filesystem, just archive your files:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>tar<span class="w"> </span>-cvzf<span class="w"> </span>mywebsite.zip<span class="w"> </span>data/
</code></pre></div>

<p>A couple takeaways:</p>
<ul>
<li>All files remain readable. For SQLite, neither a binary file nor a SQL dump file can be easily read by a human.</li>
</ul>
<p><b>Commentator:</b> This is training for the filesystem! SQLite won't even fight back anymore!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Round 8: Database restore</h2>
<p>In SQLite:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sqlite3<span class="w"> </span>data.db<span class="w"> </span>&lt;<span class="w"> </span>dump.sql
</code></pre></div>

<p>For the filesystem:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>tar<span class="w"> </span>-xvf<span class="w"> </span>mywebsite.zip
</code></pre></div>

<p><b>Commentator:</b> Uh-oh, with that last blow, SQLite is on the floor and may not be getting up anymore!</p>
<p><b>Round winner:</b> Filesystem</p>
<h2>Who's the champion?</h2>
<p><b>Commentator:</b> This was a tough battle, but very entertaining. I wish I could say both parties held their ground, but that was not what I saw today. SQLite was outsmarted, outperformed and outclassed. He lives to fight another day, but he may not want that day to ever come.</p>
<h2>Bonus: more jabs at SQL (stolen from Reddit)</h2>
<ul>
<li>SQL is old and feels like FORTRAN.</li>
<li>You have loads of dialects. SQL depends on your Server (MS SQL Server, MySQL, MariaDB, etc) what is supported.</li>
<li>It's difficult to create functions. DRY is very hard to maintain.</li>
<li>Syntax is not consistent: You may or may not put a ; or "Go".</li>
<li>You have no step-by-step debugger.</li>
<li>"Anyone" in the team can deploy triggers and procedures. There is no real "build" and "deploy" process. Git Integration is very bad. Everyone "works on the living object". (I know, you have prod, test and dev environments, but that is not comparable to developing locally and having a real continous integration platform like Jenkins etc).</li>
<li>I feel, there are no real standards. There is no scientific Community. Its ugly. Not like C++ or Python.</li>
</ul>
<h2>The bottom line</h2>
<blockquote cite="https://www.kingjamesbibleonline.org/2-Peter-2-19/">
    <p>While they promise them liberty, they themselves are the servants of corruption: for of whom a man is overcome, of the same is he brought in bondage.</p>
    <cite>2 Peter 2:19, The Bible</cite>
</blockquote>

<p>SQL is not the worst language in the world, but it is one of the most overused. The old me would not consider any other option simply due to ignorance of other methods.</p>
<p>When in doubt, <strong>use the filesystem and ditch SQL</strong>. Don't mean to fat-shame but <em>SQLite</em> needs to lose a couple <em>more</em> pounds and probably drop to someone in a lower weight class.</p>]]></description>
      <pubDate>Sat, 23 Mar 2024 21:24:00 -0700</pubDate>
      <guid>https://www.mmhq.me/posts/sqlite-vs-filesystem</guid>
    </item>
    <item>
      <title>"Filesystems corrupt data"</title>
      <link>https://www.mmhq.me/posts/filesystems-corrupt-data</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Proverbs-18-17/">
    <p>He that is first in his own cause seemeth just; but his neighbour cometh and searcheth him.</p>
    <cite>Proverbs 18:17, The Bible</cite>
</blockquote>

<p>The other day I was going through different blog posts on my RSS feed reader, minding my business, when I came across an <a href="https://dev.to/alejandro_du/why-do-we-need-databases-and-sql-1loa" title="Why do we need databases and SQL - dev.to blog post">article</a> called <em>Why do We Need Databases and SQL</em>. I have already made a <a href="/posts/the-evil-of-sql" title="The evil of SQL - MMHQ blog post">post about SQL</a> but I figured it would be nice to see if the author had any legitimate points. Let's dive in. 🏊</p>
<h2>The claim</h2>
<p><strong>Reading the article was going well at first.</strong> He talked about how using files can work for your database, but as you get more users, thousands of people could be performing the same tasks simultaneously. This could lead to race conditions, where files can be modified or deleted in unexpected ways. He then claimed:</p>
<blockquote cite="https://dev.to/alejandro_du/why-do-we-need-databases-and-sql-1loa#the-utility-of-relational-database-systems">
    <p>At this point, the simplicity of files becomes fragile.
        Imagine one user is updating a task at the exact moment another tries to delete it.
        Or maybe two users are editing the same task at the same time.</p>
    <p>With a simple file system, you're likely to end up with corrupted or lost data
        because there's no inherent mechanism to handle such conflicts.</p>
</blockquote>

<p>Hearing this claim got me thinking, <strong>"Can the problem of corrupted or lost data <em>only</em> be solved by an <em>inherent mechanism to handle such conflicts</em>? Has all hope been lost for the ubiquitous filesystem?"</strong></p>
<p>The truth is that I never really knew how the file system would handle those cases. So I googled. I had to get to the bottom of it.</p>
<p>Google confirmed that his claim was true. But is SQL our only savior? Are we doomed without our precious president of data?</p>
<h2>The investigation</h2>
<p>On further googling, I came about an important concept called <strong>file locking</strong>:</p>
<blockquote cite="https://dev.to/alejandro_du/why-do-we-need-databases-and-sql-1loa">
    <p>File locking is a mechanism that restricts access to a computer file,
        or to a region of a file, by allowing only one user or process to modify
        or delete it at a specific time and to prevent reading of the file
        while it's being modified or deleted.</p>
    <cite>File locking, Wikipedia article</cite>
</blockquote>

<p>Hmm, interesting. That definition sounds a lot like what I need. Further investigation showed that Linux had <a href="https://www.baeldung.com/linux/file-locking#locksinlinux" title="File locking in Linux section - Baeldung">support for this feature</a> through application like <strong>flock, an terminal application for file locking</strong> already installed in my computer. <code>flock</code> is used to manage file locks from shell scripts.</p>
<p>There are two types of locking: <em>advisory</em> and <em>mandatory</em>. Mandatory locking supposed to be a system-wide type of locking, but it's not advised because of its shortcomings. Advisory locking requires that all participating scripts work in coordination. This means that every script that writes to or reads from the files in question have to be called through <code>flock</code>. If they make their calls directly however, the OS will not stop the operation.</p>
<p>To demonstrate, imagine I had a script called <code>delete_record.sh</code> on a data file called <code>data_file</code>. I could call it in the terminal with file locking like this:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># First process</span>
$<span class="w"> </span>flock<span class="w"> </span>data_file<span class="w"> </span>./update_record.sh
<span class="c1"># Runs script</span>
</code></pre></div>

<p>If another process tries to call that same script, it must also use <code>flock</code>, to lock <code>data_file</code> so that it is not used until the first call is done:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># Second process</span>
$<span class="w"> </span>flock<span class="w"> </span>data_file<span class="w"> </span>./update_record.sh
<span class="c1"># Waits for previous call to delete_record.sh to finish before it executes.</span>
</code></pre></div>

<p>However, if the second process calls the script directly, there is no protection:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># Second process</span>
$<span class="w"> </span>./update_record.sh
<span class="c1"># Doesn't wait for first call to complete. Data integrity is lost.</span>
</code></pre></div>

<p>The process is so simple! Just call all your database-modifying scripts with <code>flock</code>.</p>
<h2>What does flock get us over SQL?</h2>
<ul>
<li>Smaller memory consumption, in both RAM and disk.</li>
<li>Faster queries, since you can optimize all your queries directly through updating the scripts. (You don't need to rely on SQL for that.)</li>
<li>Since flock is an old and simple program, you get years and years of debugging and bug fixes. SQL has that too, but since it's a much larger program (that keeps getting updated), it is prone to more bugs.</li>
<li>Flat text files! No binary bullshit!</li>
<li>No stress of having to figure out SQL queries. You can query your data with <code>grep</code>, or any program you want for that matter.</li>
<li>No need for a <em>SQL viewer</em> (Thank God🙄).</li>
<li>You can read your data through <code>cat</code>.</li>
<li>You can transform your data with <code>sed</code> and <code>awk</code>.</li>
<li>
<em>You</em> own your data, not some application that makes you have to keep updating it to keep using it.</li>
<li>You can create and replace scripts that manipulate your data easily, and progressively enhance your database management system (avoiding SQL bloat).</li>
<li>You save money, because you don't have to hire a SQL professional when data gets large.</li>
<li>You learn how to build databases from the ground up and you become better at building them with time.</li>
<li>Goodbye SQL dumps!</li>
</ul>
<h2>The verdict</h2>
<p>As we can see (from my calculations above), SQL is still unnecessary in such a scenario. There are old and proven ways to accomplish the many tasks that SQL performs. We as developers are the chefs; we just have to choose the recipe we're most comfortable with.</p>
<p>We must be careful of snake oil and snake-oil salesmen in software development (the <a href="https://www.kingjamesbibleonline.org/Matthew-23-4/" title="The behavior of the Pharisees">Pharisees</a>). They want everybody to put on the same burden as them, even though there are easier ways to manage data and databases.</p>
<h2>The bottom line</h2>
<p><strong>We <em>need</em> databases, we don't <em>need</em> SQL.</strong> Embrace files and filesystems!</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://www.baeldung.com/linux/file-locking" title="Introduction to file locking in Linux - Baeldung">Introduction to file locking in Linux</a></li>
</ul>]]></description>
      <pubDate>Fri, 08 Mar 2024 06:05:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/filesystems-corrupt-data</guid>
    </item>
    <item>
      <title>ABACABA with Drake</title>
      <link>https://www.mmhq.me/posts/abacaba-with-drake</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<p>Can you spot the <a href="https://en.wikipedia.org/wiki/ABACABA_pattern" title="ABACABA pattern">ABACABA pattern</a> in Drake's chorus?</p>
<p><audio controls=""><source src="/static/data/audio/rings-drake-future.mp3" type="audio/mp3"><a href="/static/data/audio/rings-drake-future.mp3">Rings by Drake and Future</a></audio></p>
<blockquote cite="https://genius.com/Drake-and-future-big-rings-lyrics">
<pre>
'Cause I got a really big team
And they need some really big rings
They need some really nice things
Better be comin' with no strings
Better be comin' with no strings
We need some really nice things
We need some really big rings
I got a really big team
</pre>
    <cite>Drake, in his song <em>Rings</em></cite>
</blockquote>

<h2>The answer</h2>
<p>Like I've mentioned in my <a href="/posts/x-marks-the-spot-my-first-chiasmus-analysis" title="X marks the spot: my first chiasmus analysis - MMHQ article">previous blog post</a>, chiastic structures are all around us. Here's the breakdown:</p>
<pre class="poem">
<b>(A)</b>  - 'Cause I got a really big team          
  <b>(B)</b>  - And they need some really big rings     
    <b>(C)</b>  - They need some really nice things       
      <b>(D)</b>  - Better be comin' with no strings        
      <b>(D')</b> - Better be comin' with no strings        
    <b>(C')</b> - We need some really nice things         
  <b>(B')</b> - We need some really big rings           
<b>(A')</b> - I got a really big team                 
</pre>

<p>What makes this even more interesting is that the chiastic structure is sometimes called the <em>ring structure</em>, which makes the structure a play on the song title <em>Rings</em>.</p>
<p>Coincidence? Not sure, but it's hard not to think of some of these rappers as lyrical geniuses. Well done, Drake 👏!</p>
<p>You can listen to the whole song <a href="https://www.youtube.com/watch?v=3TsYIQv0sX8" title="Drake &amp; Future - Big Rings - YouTube">here</a>.</p>]]></description>
      <pubDate>Thu, 07 Mar 2024 03:47:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/abacaba-with-drake</guid>
    </item>
    <item>
      <title>The Bible is descriptive, not prescriptive</title>
      <link>https://www.mmhq.me/posts/the-bible-is-descriptive-not-prescriptive</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Exodus-34-6/">
    <p><span>6</span>
        And the LORD passed by before him, and proclaimed,
        The LORD, The LORD God, merciful and gracious,
        longsuffering, and abundant in goodness and truth,</p>
    <p><span>7</span>
        Keeping mercy for thousands, forgiving iniquity and transgression and sin,
        and that will by no means clear the guilty;
        visiting the iniquity of the fathers upon the children,
        and upon the children's children, unto the third and to the fourth generation.</p>
    <cite>Exodus 34:6-7, The Bible</cite>
</blockquote>

<p><strong>The purpose of the Bible is not to tell you what to do; its purpose is to describe God's character</strong>. In this blog post, I would like to elaborate on that statement.</p>
<h2>What is God's character?</h2>
<p>God's true character is love. If we meditate on God, we will eventually start to behave like him, but in the proper way, not the way we assume.</p>
<p>This is God's desire, that we <em>progressively</em> change through the practice of meditation. It's not a must, but it is kind of inevitable if we meditate.</p>
<p>Take for instance, I practice playing the piano sometimes. I have to <em>meditate</em> on the piano to get better. What I mean is that I must stop assuming I know the song I'm learning and play the song slowly (with a <a href="http://en.wikipedia.com/wiki/Metronome" title="Metronome - Wikipedia">metronome</a>, of course). Assuming "I know the piece" is pride. If I try to play that way, I will never truly understand the song and its nuances.</p>
<p>To understand the song, I must play the piece slowly. The piece must be broken into parts, and each part repeated a number of times. After which, I, almost inevitably, get better at playing the song.</p>
<p>But this learning is not only about learning the songs I like. I also have to do exercises that seemingly have nothing to do with the song. In the field of piano, these <em>exercises</em> manifest themselves in the form of Hanon exercises, scale exercises, chord exercises etc. Once these are completed, you will gain a new mastery of the instrument.</p>
<p>God is the same way. To truly learn about him, we must <em>consume</em> him slowly; we must meditate on his word. After meditating on his word, we will learn the true meaning of love.</p>
<p>However, God's word is not always what we want to do. It could be against what our desires are (like playing boring scale exercises), but there is a lot of learning in that too.</p>
<p>After all this, is the part we enjoy. In the piano practice world, this is known as improvisation. We can play with the melody or the structure of the song all we want because we know the <em>essence</em> of the song.</p>
<p>With God, meditating on his word will give us a glimpse of the depths of love and what it truly means to love.</p>
<h2>How do we meditate on God's word?</h2>
<blockquote cite="https://www.kingjamesbibleonline.org/Psalm-1-1/">
    <p><span>1</span>
        Blessed is the man that walketh not in the counsel of the ungodly, nor standeth in the way of sinners, nor sitteth in the seat of the scornful.
    </p>
<p><span>2</span>
        But his delight is in the law of the LORD; and in his law doth he meditate day and night.</p>
    <cite>Psalms 1:1-2, The Bible</cite>
</blockquote>

<p>My theory of the most ideal way to meditate on God's word is to read God's word slowly, verse by verse, and read the verses repeatedly a couple times. After you finish reading, you do some mindfulness meditation, then go back to reading, only pausing to answer to important things like eating, showering etc.</p>
<p>I didn't read this from anywhere, I kinda derived it. I came to this conclusion from understanding the <em>faith</em> vs <em>works</em> parallel. You either walk by faith or walk by works (or <em>by sight</em>); you either depend on God to do things for you, or you do them yourself. Everytime you do things yourself, you are taking matters into your own hands.</p>
<p>Another thing is that the Bible says our righteousness is like a filthy rag. This means that we cannot please him through our good deeds, nor our praying, nor our fasting, nor our praise; we please him through having faith on him:</p>
<blockquote cite="https://www.kingjamesbibleonline.org/Hebrews-11-6/">
    <p>But without faith it is impossible to please him:
        for he that cometh to God must believe that he is,
        and that he is a rewarder of them that diligently seek him.</p>
    <cite>Hebrews 11:6, The Bible</cite>
</blockquote>

<blockquote cite="https://www.kingjamesbibleonline.org/Proverbs-3-5/">
    <p><span>5</span>
        Trust in the LORD with all thine heart; and lean not unto thine own understanding.</p>
    <p><span>6</span>
        In all thy ways acknowledge him, and he shall direct thy paths.</p>
    <cite>Proverbs 3:5-6, The Bible</cite>
</blockquote>

<p>From the scripture from Proverbs above, it shows that we are to trust in him, which is the same thing as having faith in God. We should acknowledge him too for what he's done, or like the Psalmist puts it:</p>
<blockquote cite="https://www.kingjamesbibleonline.org/Psalm-77-12/">
    <p>I will meditate also of all thy work, and talk of thy doings.</p>
    <cite>Psalms 77:12, The Bible</cite>
</blockquote>

<p>I think we can learn a lot from David; after all, he was <a href="https://www.kingjamesbibleonline.org/Acts-13-22/" title="David is a man after God's own heart - KJV Bible">a man after God's own heart</a>.</p>
<p>Now I know we may not have the time to meditate God's word, and there is no pressure. I try to read as much as I can. I miss a couple days of my daily reading, but it's okay. I'm human; we're all human. God created us this way and we should never be ashamed.</p>
<p>But we can be grateful. We can learn to appreciate all that is around us and the love he shows us even if we don't deserve it. There is a lot to learn from God's character</p>
<h2>The bottom line</h2>
<p>The Bible is not a rule book; it's a guide. Stop with the work mentality. Have faith in God and let God do the rest.</p>]]></description>
      <pubDate>Wed, 06 Mar 2024 18:44:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/the-bible-is-descriptive-not-prescriptive</guid>
    </item>
    <item>
      <title>The audacity of yin-yang</title>
      <link>https://www.mmhq.me/posts/the-audacity-of-yin-yang</link>
      <description><![CDATA[<p><picture><img alt="Yin-yang symbol" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/yin-yang.webp" srcset="/static/data/images/360w/yin-yang.webp 360w, /static/data/images/640w/yin-yang.webp 640w, /static/data/images/1080w/yin-yang.webp 1080w, /static/data/images/1280w/yin-yang.webp 1280w" title="Yin-yang symbol"></picture></p>
<blockquote id="genesis-1-1" class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-1-1/">
    <p>In the beginning God created the heavens and the earth.</p>
    <cite>Genesis 1:1, The Bible</cite>
</blockquote>

<p>Heaven and earth. Light and darkness. High and low. Good and evil. Two forces, bold enough to go head to head directly, but at the same time, find a sort of opposed union.</p>
<p>In this blog post, I would like to discuss what yin-yang is and how it can be used to qualify entities in the cosmos.</p>
<h2 id="heaven-and-earth">Heaven and earth</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-1-4/">
    <p><span>4</span>
            And God saw the light, that it was good: and God divided the light from the darkness.
    </p>
    <p><span>5</span>
        And God called the light Day, and the darkness he called Night. 
        And the evening and the morning were the first day.
    </p>
    <cite>Genesis 1:4-5, The Bible</cite>
</blockquote>

<p>The best way to analyze yin-yang is to look at heaven and earth. The properties of heaven and earth give us a lot of clues as to how entities manifest themselves in nature.</p>
<p>I would go as far as to say that <a href="/posts/the-audacity-of-yin-yang#genesis-1-1" title="Genesis 1:1">Genesis 1:1</a> is one of the most condensed scriptures in the Bible. I say that because breaking the universe down into heaven and earth is pretty much like breaking a house down into building blocks.</p>
<p>Don't believe me? Let's make a table of the differences between heaven and earth:</p>
<table>
<thead>
<tr>
<th>Heaven</th>
<th>Earth</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lightweight</td>
<td>Heavy</td>
</tr>
<tr>
<td>Easy to move through</td>
<td>Hard to move through</td>
</tr>
<tr>
<td>Exists freely</td>
<td>Exists under constraint</td>
</tr>
<tr>
<td>Tries to expose</td>
<td>Tries to hide</td>
</tr>
<tr>
<td>No distinguishable parts</td>
<td>Distinguishable parts</td>
</tr>
<tr>
<td>Mobile</td>
<td>Static</td>
</tr>
<tr>
<td>Simple and therefore abstract</td>
<td>Difficult and therefore concrete</td>
</tr>
<tr>
<td>Difficult to grasp</td>
<td>Easy to grasp</td>
</tr>
<tr>
<td>Transparent</td>
<td>Opaque</td>
</tr>
<tr>
<td>Spacious</td>
<td>Tight</td>
</tr>
<tr>
<td>Lasts forever</td>
<td>Lasts ephemerally</td>
</tr>
<tr>
<td>Essential</td>
<td>Optional</td>
</tr>
</tbody>
</table>
<p>This is by no means a comprehensive list; I just list a few of the property differences between heaven and earth. Because both entities appear in our physical world and are easily observed, they are easy to confirm by just looking at the world around us.</p>
<p>The yin-yang symbol has an important detail; the inclusion of a little black on the white side, and a little white on the black side. This distinction is subtle but must not be overlooked. It symbolizes that heaven can behave like earth sometimes, and earth like heaven.</p>
<p>This truth is what makes life the roller coaster that it is. Everything has a pattern, but can deviate from the pattern and throw you off.</p>
<p>How? Let's look at heaven, for instance. As much as it is difficult to grasp physically in your hand and seems to have no effect on the world, it can still show up as strong winds in nature, for example. We all know the dangers of a tornado! 🌪️</p>
<p>Earth is no different. As much as it has a hard exterior and can easily be grasped, under certain conditions, some solids can become liquid and sometimes directly gas. This is a clear transition of <em>earth</em> to <em>heaven</em>. A perfect example of this would be dry ice, which is a white solid in a fire extinguisher but quickly becomes gas when released into the atmosphere.</p>
<h2 id="as-is-above-so-is-below">As is above, so is below</h2>
<p>Heaven and earth are pretty much the foundations of the cosmos. Every other existing entity follows that fundamental principle, sometimes in a subtle way. Let's explore, shall we?</p>
<h3 id="light-vs-darkness">Light vs darkness</h3>
<p>Light is: </p>
<ul>
<li>
<strong>Lightweight</strong>: Not applicable in this context, since darkness is no heavier.</li>
<li>
<strong>Easy to move through</strong>: It's easier to move around in the morning than at night.</li>
<li>
<strong>Exists freely</strong>: In the presence of light, we can move freely.</li>
<li>
<strong>Tries to expose</strong>: Light tries to enter every corner of a dark room.</li>
<li>
<strong>No distinguishable parts</strong>: This is actually the opposite, an example of an exception.</li>
<li>
<strong>Mobile</strong>: Once again, you have the freedom to move in light without fear or ignorance.</li>
<li>
<strong>Simple and abstract</strong>: When under the light, the structure of things are exposed and they become easy to analyze.</li>
<li>
<strong>Difficult to grasp</strong>: Not applicable in this context, since both light and darkness cannot be grasped.</li>
<li>
<strong>Transparent</strong>: Everything can be seen under the light.</li>
<li>
<strong>Spacious</strong>: Available space can be seen under the light.</li>
<li>
<strong>Lasts forever</strong>: It's easy to survive under light.</li>
<li>
<strong>Essential</strong>: To ensure easy survival, light is needed.</li>
</ul>
<p>Darkness is: </p>
<ul>
<li>
<strong>Heavy</strong>: Not applicable in this context, since light is no lighter.</li>
<li>
<strong>Difficult to move through</strong>: It's harder to move around at night than in the morning.</li>
<li>
<strong>Exists under constraint</strong>: In the absence of light, we cannot move freely.</li>
<li>
<strong>Tries to hide</strong>: Darkness masks the reality of what's in existence.</li>
<li>
<strong>Distinguishable parts</strong>: This is actually the opposite, an example of an exception.</li>
<li>
<strong>Static</strong>: You don't want to move around because of fear and ignorance.</li>
<li>
<strong>Difficult and concrete</strong>: It's harder to understand things in the darkness, and you have to touch things to get through.</li>
<li>
<strong>Easy to grasp</strong>: Not applicable in this context, since both light and darkness cannot be grasped.</li>
<li>
<strong>Opaque</strong>: Nothing can be seen in darkness.</li>
<li>
<strong>Tight</strong>: No available space can be seen without light, so you feel trapped.</li>
<li>
<strong>Lasts ephemerally</strong>: It's harder to survive in the dark.</li>
<li>
<strong>Optional</strong>: In darkness, survival is harder and more risky.</li>
</ul>
<h3 id="high-vs-low">High vs low</h3>
<p>Let's talk of <em>high</em> vs <em>low</em> in terms of melody (high) and harmony, or accompaniment (low), on the piano.</p>
<p>Melodies are:</p>
<ul>
<li>
<strong>Lightweight</strong>: Easy on the ear, since the are played in the middle to high range on the piano.</li>
<li>
<strong>Easy to move through</strong>: Melodies are usually a sequence of single notes, so they are easy to play.</li>
<li>
<strong>Exists freely</strong>: Melodies have a proper sequence, but can be improvised without throwing the music off.</li>
<li>
<strong>Tries to expose</strong>: Melodies stand out in a song; it exposes itself and the song's essence.</li>
<li>
<strong>No distinguishable parts</strong>: Melodies are not as distinguishable as accompaniment or chord changes.</li>
<li>
<strong>Mobile</strong>: Melodies can be simple or all over the place in constant motion.</li>
<li>
<strong>Simple and abstract</strong>: Melodies are easier to understand than chords and harmony.</li>
<li>
<strong>Difficult to grasp</strong>: Melodies are less patterned than the accompaniment i.e. there is more variation in melodies.</li>
<li>
<strong>Transparent</strong>: Everything about the song is in the melody.</li>
<li>
<strong>Spacious</strong>: Melodies tend to sound like they are floating, because there is no bass.</li>
<li>
<strong>Lasts forever</strong>: The melody is remembered and preserved from generation to generation and even when porting a song to different genres of music.</li>
<li>
<strong>Essential</strong>: The melody is the identity of the song, and therefore most important.</li>
</ul>
<p>Harmonies are:</p>
<ul>
<li>
<strong>Heavy</strong>: Heavy on the ear, since the are played in the bottom range of the piano.</li>
<li>
<strong>Difficult to move through</strong>: Chords and bass notes can easily get muddied, especially with the <a href="https://en.wikipedia.org/wiki/Sustain_pedal" title="Sustain pedal - Wikipedia article">sustain pedal</a> pressed.</li>
<li>
<strong>Exists under constraint</strong>: The harmony section has to stick to the chord progression.</li>
<li>
<strong>Tries to hide</strong>: Harmony stays in the background. Also, could possibly mask the melody if too loud.</li>
<li>
<strong>Distinguishable parts</strong>: Harmony changes the mood of the melody and is therefore more distinguishable.</li>
<li>
<strong>Static</strong>: Tries not to move around a lot (though there are exceptions).</li>
<li>
<strong>Difficult and concrete</strong>: Chords can get very complex and voicing them could even be more of a problem.</li>
<li>
<strong>Easy to grasp</strong>: Harmony usually has a consistent pattern with less variations, making it easier to learn.</li>
<li>
<strong>Opaque</strong>: You may not remember a song from hearing the chord progression alone; you may need the melody.</li>
<li>
<strong>Tight</strong>: Lower tones sound like they take up more space in the sound spectrum when played.</li>
<li>
<strong>Lasts ephemerally</strong>: Chord progression and harmony is secondary to the melody and may not last in your head as long.</li>
<li>
<strong>Optional</strong>: The harmony can be left out of a song and the song will still be recognizable as long as the melody is played.</li>
</ul>
<p>Those are some rough examples. As you can see, they are not perfect, but you can see the similarities. They are not arbitrary either; the universe has a clever design to it.</p>
<p>With all that being said, how is yin-yang defined?</p>
<h2 id="yin-the-glass-half-empty">Yin: the glass half empty</h2>
<p><em>Yin</em> translates more to <em>earth</em>. According to <a href="https://en.wikipedia.org/wiki/Yin_and_yang#Loanwords" title="Yin-yang Wikipedia article">Wikipedia</a>:</p>
<blockquote class="quote" cite="https://en.wikipedia.org/wiki/Yin_and_yang#Loanwords">
    <p>yin (jɪn) Also Yin, Yn. [Chinese yīn shade, feminine; the moon.]</p>
    <p>a. In Chinese philosophy, the feminine or negative principle (characterized by dark, wetness, cold, passivity, disintegration, etc.) of the two opposing cosmic forces into which creative energy divides and whose fusion in physical matter brings the phenomenal world into being. Also attrib. or as adj., and transf. Cf. yang.</p>
    <p>b. Comb., as yin-yang, the combination or fusion of the two cosmic forces; freq. attrib., esp. as yin-yang symbol, a circle divided by an S-shaped line into a dark and a light segment, representing respectively yin and yang, each containing a 'seed' of the other.</p>
    <cite>Wikipedia</cite>
</blockquote>

<p>Yin also represents:</p>
<ul>
<li>female, passive, negative principle in nature</li>
<li>The moon</li>
<li>Shaded orientation</li>
<li>Covert; concealed; hidden</li>
<li>Female genitals</li>
<li>Of the netherworld</li>
<li>Overcast</li>
<li>Sinister; treacherous</li>
</ul>
<h2 id="yang-the-glass-half-full">Yang: the glass half full</h2>
<p><em>Yang</em> translates to <em>heaven</em>. According to <a href="https://en.wikipedia.org/wiki/Yin_and_yang#Loanwords" title="Yin-yang Wikipedia article">Wikipedia</a>:</p>
<blockquote class="quote" cite="https://en.wikipedia.org/wiki/Yin_and_yang#Loanwords">
    <p>yang (jæŋ) Also Yang. [Chinese yáng yang, sun, positive, male genitals.]</p>
    <p>a. In Chinese philosophy, the masculine or positive principle (characterized by light, warmth, dryness, activity, etc.) of the two opposing cosmic forces into which creative energy divides and whose fusion in physical matter brings the phenomenal world into being. Also attrib. or as adj. Cf. yin.</p>
    <p>b. Comb.: yang-yin = yin-yang s.v. yin b.</p>
    <cite>Wikipedia</cite>
</blockquote>

<p>Yang represents:</p>
<ul>
<li>Male/active/positive principle in nature</li>
<li>The sun</li>
<li>Male genitals</li>
<li>In relief</li>
<li>Open, overt</li>
<li>Belonging to this world (or natural, as opposed to artificial)</li>
<li>Masculine</li>
</ul>
<h2 id="its-all-the-same-ying">It's all the same ying</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Job-33-14/">
    <p>For God speaketh once, yea twice, yet man perceiveth it not.</p>
    <cite>Job 33:14, The Bible</cite>
</blockquote>

<p>If yin-yang truly embodies the foundational truth of the cosmos, then we should see the patterns repeat all throughout nature. After all, nature should know that human beings learn through repetition, and if there was a message out there for us, it should be repeated multiple times. Here are a few of my observations (excluding any explanations):</p>
<h3>Animals</h3>
<ul>
<li>Lean meat (<em>yang</em>) vs fat (<em>yin</em>)</li>
</ul>
<h3>Electronics</h3>
<ul>
<li>Modulating wave (<em>yang</em>) vs carrier wave (<em>yin</em>) in radio transmission</li>
</ul>
<h3>Computers</h3>
<ul>
<li>0s (<em>yin</em>) vs 1s (<em>yang</em>) for binary messages</li>
<li>plaintext (<em>yang</em>) vs cipher (<em>yin</em>), used in encryption</li>
<li>On vs off (<em>yin</em>) for screen pixels</li>
</ul>
<h3>Web Development</h3>
<ul>
<li>HTML (<em>yang</em>) vs CSS (<em>yin</em>), two most important languages on the web</li>
</ul>
<h3>Physics</h3>
<ul>
<li>Action (<em>yang</em>) vs reaction (<em>yin</em>), equal but opposing forces (Newton's Third Law)</li>
</ul>
<h3>Poetry</h3>
<ul>
<li>Stressed syllables (<em>yang</em>) vs unstressed syllables (<em>yin</em>), used for meter</li>
<li>A vs B (<em>yin</em> and <em>yang</em> can be interchanged here) in popular rhyme schemes (e.g. ABAB or ABBA)</li>
</ul>
<h3>Figurative language</h3>
<ul>
<li>Metaphors (aka the powerhouse of figurative language)<ul>
<li>Tenor (<em>yang</em>) vs vehicle (<em>yin</em>)</li>
</ul>
</li>
<li>Oxymorons<ul>
<li>cold sweat</li>
</ul>
</li>
<li>Hyperboles</li>
<li>Antimetabole<ul>
<li>The Sabbath vs man, in "The Sabbath was made for man, not man for the Sabbath"</li>
</ul>
</li>
<li>Holonymy vs metonymy<ul>
<li>Parent (<em>yang</em>) vs child (<em>yin</em>) relationship (i.e. is-a relationship)</li>
</ul>
</li>
<li>Hypernymy vs hyponymy</li>
</ul>
<h3>Music</h3>
<ul>
<li>Black keys (<em>yin</em>) vs white keys (<em>yang</em>) on piano</li>
<li>Legato (<em>yang</em>) vs staccato (<em>yin</em>)</li>
<li>Stressed beats (<em>yang</em>) and unstressed beats (<em>yin</em>)</li>
</ul>
<h3>Christianity</h3>
<ul>
<li>The creation of the world<ul>
<li>The heavens (<em>yang</em>) vs the earth (<em>yin</em>) (Genesis 1:1)</li>
<li>The flaming sword (<em>yang</em>) vs the Cherubims (<em>yin</em>) (Genesis 3:24)</li>
</ul>
</li>
<li>The laws<ul>
<li>Clean animals (<em>yang</em>) vs unclean animals (<em>yin</em>) (Leviticus 20:25)</li>
</ul>
</li>
<li>The gospel<ul>
<li>Faith in God for salvation (<em>yang</em>) (John 3:16) vs working for your salvation (<em>yin</em>) (Matthew 7:21-23)</li>
<li>The servant (<em>yin</em>) vs the son (<em>yang</em>) (John 3)</li>
</ul>
</li>
<li>Psalms in the Bible<ul>
<li>The righteous (<em>yang</em>) vs the wicked (<em>yin</em>) (Psalm 1)</li>
</ul>
</li>
<li>Proverbs in the Bible<ul>
<li>The righteous (<em>yang</em>) vs the wicked (<em>yin</em>)</li>
</ul>
</li>
</ul>
<h3>Other symbols</h3>
<ul>
<li>The power icon: 0 (<em>yin</em>) vs 1 (<em>yang</em>)</li>
<li>The tree (<em>yang</em>) and the snake (<em>yin</em>)</li>
</ul>
<p>Maybe someday I could discuss them all along with many more.</p>
<h2>The bottom line</h2>
<p>Understanding the symbol of yin-yang can be very helpful in analyzing the cosmos since it is the very atoms of creation. There are even deeper connections that can be made with yin-yang (like God vs man, love vs indifference, poetry vs music) and hopefully I can study and talk about more in the future.</p>
<p>Observations like this remind me to pay attention to the world around me and to look for similarities and differences to connect the universe. Understanding patterns is a skill that can translate to all fields of life, so it's definitely a skill worth acquiring.</p>]]></description>
      <pubDate>Mon, 04 Mar 2024 03:30:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/the-audacity-of-yin-yang</guid>
    </item>
    <item>
      <title>Love the stranger</title>
      <link>https://www.mmhq.me/posts/love-the-stranger</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Deuteronomy-10-19/">
    <p>Love ye therefore the stranger: for ye were strangers in the land of Egypt.</p>
    <cite>Deuteronomy 10:19, The Bible</cite>
</blockquote>

<p>I was reading the book of Deuteronomy recently and came across the scripture above. It reminded me of who God truly is and how his character can teach a lot of lessons about life. In this blog post, I would like to talk about God's love for the stranger.</p>
<h2 id="who-is-the-stranger">Who is the stranger?</h2>
<blockquote cite="https://www.kingjamesbibleonline.org/Exodus-23-9/">
    <p>Also thou shalt not oppress a stranger: for ye know the heart of a stranger, seeing ye were strangers in the land of Egypt.</p>
    <cite>Exodus 23:9, The Bible</cite>
</blockquote>

<p><strong>A stranger</strong>, according to <a href="http://wordnetweb.princeton.edu/perl/webwn?s=stranger&amp;sub=Search+WordNet&amp;o2=&amp;o0=1&amp;o8=1&amp;o1=1&amp;o7=&amp;o5=&amp;o9=&amp;o6=&amp;o3=&amp;o4=&amp;h=" title="WordNet - Definition of stranger">WordNet</a>, <strong>is anyone who does not belong in the environment in which they are found.</strong></p>
<p>We all have experienced the newcomer coming in — in school, at work, in church, sometimes even at home. They are different from us in some way. They don't understand the rules around here, the operations. They may mess things up. They may be careless or may not know the importance of things because of their naïveté. And even sometimes, they might be dangerous to you and to everyone else.</p>
<p><strong>We're all familiar with the stranger, because we've all been strangers in every aspect in our lives.</strong> We were strangers to talking, strangers to walking, strangers to travelling, strangers to classmates, strangers to co-workers, strangers in groups we choose to associate with. We were strangers to adults as children and strangers to children as adults. The irony of life.</p>
<h2 id="how-man-deals-with-the-stranger">How man deals with the stranger</h2>
<p>When you join a basketball team as a point guard, and you are paid a lot of money to perform, you are expected to rack in points non-stop. You may be given time by the coach, it may take you some time to catch your stride, but eventually you have to produce results (aka score). If seasons go by and points are not forthcoming, you would eventually be let go.</p>
<p>When you join a jazz band as the lead pianist, you have to hold those chords down. You have to make sure the harmonic section is on par. You may slip and fat-finger a couple notes here and there, but eventually you have to get up to speed. If you don't, they show you the door.</p>
<p>There is a version of this with the sick among the Israelites in the Old Testament. They were told to quarantine for some days but if the sickness persisted, they were given the boot and were told to leave the camp.</p>
<p>I think you can start to see a pattern of how man handles the stranger. There are many other scenarios that I didn't mention like:</p>
<ul>
<li>Giving the stranger more work e.g. a new employee</li>
<li>Using the stranger as a slave e.g. in the time of the Egyptians</li>
<li>Excluding them from good e.g. immigrants not having the same rights as citizens</li>
<li>Making them take the blame for everything e.g. Potiphar's wife getting Joseph locked up</li>
</ul>
<p>Bad things are not the only thing that happens to a stranger, but as you can see, you have to do good, or else! Or like they say it in some nursery school songs:</p>
<blockquote>
<p>If you do good, kingdom waiting for you; if you do bad, no more kingdom.</p>
</blockquote>
<h2 id="how-god-dealt-with-the-stranger">How God dealt with the stranger</h2>
<p>What does the Bible say about the way God dealt with the stranger?</p>
<ul>
<li>In the garden of Eden, he prepared coats of skin for Adam and Eve (the new strangers). (<a href="https://www.kingjamesbibleonline.org/Genesis-3-21/" title="Genesis 3:21 - King James Bible Online">Gen. 3:21</a>)</li>
<li>After Sarah kicked out Hagar (the stranger), God visited her. (<a href="https://www.kingjamesbibleonline.org/Genesis-21-17/" title="Genesis 21:17 - King James Bible Online">Gen. 21:17</a>)</li>
<li>In Exodus, the strangers (the Israelites) were saved from Egypt. (<a href="https://www.kingjamesbibleonline.org/Exodus-22-21/" title="Exodus 22:21 - King James Bible Online">Ex. 22:21</a>)</li>
<li>The strangers that were among them were told to follow the same law. (<a href="https://www.kingjamesbibleonline.org/Exodus-12-49/" title="Exodus 12:49 - King James Bible Online">Ex. 12:49</a>)</li>
<li>The strangers were told to observe the Sabbath. (<a href="https://www.kingjamesbibleonline.org/Deuteronomy-5-14/" title="Deuteronomy 5:14 - King James Bible Online">Deut. 5:14</a>)</li>
<li>He accepted the stranger Abraham, and even gave Abraham the land that he was a stranger in. (<a href="https://www.kingjamesbibleonline.org/Genesis-28-4/" title="Genesis 28:4 - King James Bible Online">Gen. 28:4</a>)</li>
<li>Moses was a stranger in Egypt. (<a href="https://www.kingjamesbibleonline.org/Exodus-2-22/" title="Exodus 2:22 - King James Bible Online">Ex. 2:22</a>)</li>
</ul>
<h2 id="how-jesus-dealt-with-the-stranger">How Jesus dealt with the stranger</h2>
<blockquote cite="https://www.kingjamesbibleonline.org/Matthew-5-43/">
    <p><span>43</span>
        Ye have heard that it hath been said, Thou shalt love thy neighbour, and hate thine enemy.</p>
    <p><span>44</span>
        But I say unto you, Love your enemies, bless them that curse you, do good to them that hate you,
        and pray for them which despitefully use you, and persecute you;</p>
    <cite>Matthew 5:43-44, The Bible</cite>
</blockquote>

<p>Did Jesus deal with the stranger? He sure did:</p>
<ul>
<li>Jesus told us to love our enemies aka the stranger (as in the scripture quoted above).</li>
<li>Jesus saved the Gentiles, who are considered strangers to the Jews.</li>
<li>Jesus saved other Jews that were under the curse of the law. They were strangers because they were put under the laws of the Pharisees, which they were unable to follow.</li>
<li>The parable about the Good Samaritan could be viewed as a person being saved by a stranger (as how God can seem like a stranger to us).</li>
<li>Jesus always ate with sinners. <em>Sinners</em> in this context play the role of the stranger.</li>
<li>Though Jesus wants us to continue believing in him after he saves us, and we choose to turn our backs on him i.e. choose to become <em>strangers to him</em>, he still keeps to his promise and grants us eternal life.</li>
<li>Man is a stranger to God, because our ways are opposite. (<a href="https://www.kingjamesbibleonline.org/1-Corinthians-1-25/" title="1 Corinthians 1:25 - King James Bible Online">1 Cor. 1:25</a>)</li>
</ul>
<p>In summary:</p>
<blockquote>
<p>If you believe once, kingdom; if you do evil, kingdom still waiting for you.</p>
</blockquote>
<h2 id="how-can-i-apply-this">How can I apply this?</h2>
<blockquote cite="https://www.kingjamesbibleonline.org/Isaiah-55-9/">
    <p>For as the heavens are higher than the earth, so are my ways higher than your ways, and my thoughts than your thoughts.</p>
    <cite>Isaiah 55:9, The Bible</cite>
</blockquote>

<p>There is a lot to learn from the stranger. Having this attitude can make life a lot better. Learn to understand your children (the strangers) and not just judge them. Try to understand the Republicans and the Democrats (the strangers) before you criticize what they say. Try to be a listening ear to the employee that is under you (stranger again) or an old geezer.</p>
<p>I use this principle even in my work. When I write software, I try to create interfaces that <em>capture</em> part of the problem. This is how I come up with my best solutions. For instance, if I write a program that converts spreadsheet documents to XML, I most likely would use high-level representations of <code>Spreadsheet</code> and <code>XML</code> in the code to help <em>materialize</em> the problem. Once the problem is defined, the solution can easily be put together.</p>
<p>Obviously these principles can be applied outside of software. Show love to people that don't deserve it. <a href="https://www.youtube.com/watch?v=hrhsa7oec1Y" title="Love like the sun by Dr. Orion Taraban">Love like the sun</a>. Love like God.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>This is a true exercise of <a href="https://www.kingjamesbibleonline.org/Hosea-6-6/" title="'I desired mercy, not sacrifice' scripture">mercy</a>. We all need it, so it is only fair we give to all, including the stranger. We don't have to, but it surely doesn't hurt.</p>]]></description>
      <pubDate>Sun, 03 Mar 2024 13:33:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/love-the-stranger</guid>
    </item>
    <item>
      <title>The evil of S(E)Q(UE)L</title>
      <link>https://www.mmhq.me/posts/the-evil-of-sql</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Matthew-23-4/">
    <p>For they bind heavy burdens and grievous to be borne, and lay them on men's shoulders; but they themselves will not move them with one of their fingers.</p>
    <cite>Matthew 23:4, The Bible</cite>
</blockquote>

<details>
    <summary>Poem: <em>Database Doom</em></summary>
<pre class="poem">
You know what rhymes with <em>SQL</em>?
<em>Next to hell</em> and <em>Save yourself</em>
</pre>
</details>

<p>Any techie that has worked extensively with data has probably used SQL once in his lifetime. I started using SQL early in my programming days, when I worked on a record-keeping software soon after I learned C++. It was very instrumental in that project, and pretty much in any job I've worked for in my career. <strong>As long as there was data, there was SQL</strong> (in most cases).</p>
<p>With this foundation, you could probably see how surprised I was to come to the conclusion of what SQL truly is, a gatekeeper of data. In this blog post, I'm going to explore what this means in detail.</p>
<h2 id="what-is-a-database">What is a database?</h2>
<p>First, let's start with what a database is.</p>
<p>According to <a href="http://en.wikipedia.com/wiki/Database" title="Database">Wikipedia</a>, a database is an organized collection of data. It can also mean a database management system (like SQL), though I don't believe this to be its original definition.</p>
<p>A <a href="http://en.wikipedia.com/wiki/Database#database-management-system" title="Database management systems">database management system</a> (DBMS) is the software system that enables users to define create, maintain and control access to the database.</p>
<p>As you can see, the term <em>database</em> and <em>database management system</em> can both mean 2 different things. This is where I believe the confusion comes from. We conflate what a database and a DBMS is and that could get in our way of truly understanding the role of a database, and not the software around it (the DBMS).</p>
<h2 id="the-problem-with-sql">The problem with SQL</h2>
<p><strong>The main problem with SQL is that it merges the database and DBMS</strong>. This may be desired in some situations, but not all. This creates a lack of separations of concerns; SQL tries to do everything for you, leaving little room for the developer to manipulate data easily.</p>
<p>This all-in-one solution by SQL causes some issues:</p>
<h3 id="data-is-stored-as-binary-instead-of-as-text">Data is stored as binary instead of as text</h3>
<blockquote class="quote" cite="https://shop.elsevier.com/books/the-unix-philosophy/gancarz/978-0-08-094819-5">
    <p>Programs do not create data, people do.</p>
    <cite>Mike Gancarz, The Unix Philosophy</cite>
</blockquote>

<p>SQL violates tenet 5 of the UNIX philosophy:</p>
<blockquote>
<p>Store data in flat text files.</p>
</blockquote>
<p>In my experience, <strong>storing data in flat text files makes data handling a breeze</strong>. Anybody can take a look at the data at anytime, ANYBODY! Not a SQL expert, not a programmer, but a basic computer user can make complete sense of the data that is available.</p>
<p>Imagine searching through files with common Linux tools like <a href="https://www.gnu.org/software/grep/manual/grep.html" title="grep on The GNU Project website">grep</a> and manipulating data with <a href="https://www.gnu.org/software/sed/manual/sed.html" title="sed on The GNU Project website">sed</a>. It's much easier. And better yet, you can store data in a format that is more suited for its application. For example, you could store structured data in JSON, but key values in INI files. Life becomes a lot easier when you are in full control of your data.</p>
<h3 id="bloat">Bloat</h3>
<p>SQL violates tenet 2 of the UNIX philosophy:</p>
<blockquote>
<p>Make each program do one thing well.</p>
</blockquote>
<p>SQL is more than just a query language; it provides security, data validation and so many other things. Many claim that handling this yourself could be tricky, but I don't believe that to be true. These choices should be left in the hands of the developer.</p>
<h3 id="its-hefty">It's hefty</h3>
<p>SQL violates tenet 1 of the UNIX philosophy:</p>
<blockquote>
<p>Small is beautiful.</p>
</blockquote>
<p>Having to install a server and client makes running SQL a pain. Why do I have to install 2 programs just to read <em>my</em> data? Why do I have to run a full server just to read data made for human consumption?</p>
<h3 id="it-has-different-versions">It has different versions</h3>
<p>SQLite, MySQL, PostgreSQL, MariaDB and a lot more. All of them have their nuances when it comes to the SQL language and are not really compatible with themselves.</p>
<h3 exported-sql-needs-to-be-built="exported-sql-needs-to-be-built">Exported SQL needs to be <em>built</em>
</h3>
<p>A SQL database to be used by another SQL database first needs to be exported to SQL code. Exporting a SQL database converts the data back into SQL code. Unfortunately, this could be time-consuming if you have a large database, and it is pretty annoying that you have to convert it from one form to another, just to transfer it, only to convert it back when it needs to be used by a database.</p>
<h3 id="the-syntax-can-be-hard-to-use-for-beginners">The syntax can be hard to use for beginners</h3>
<p>Beginners are not really familiar with how SQL works and it is not a trivial technology to learn.</p>
<h3 id="the-syntax-can-only-be-used-in-sql-environments">The syntax can only be used in SQL environments</h3>
<p>Only SQL programs understand SQL; humans don't read SQL naturally.</p>
<h3 id="sql-databases-need-to-be-constantly-updated">SQL databases need to be constantly updated</h3>
<p>This should be the most scary disadvantage: if data is very old, you may have difficulty putting data into a database because of <em>updated syntax</em>. By keeping data security separate from the data itself, you can update security without touching your data at all.</p>
<h2 id="a-better-alternative">A better alternative?</h2>
<blockquote class="quote" cite="http://quotes.cat-v.org/programming">
    <p>We have persistent objects, they’re called files.</p>
    <cite>Ken Thompson</cite>
</blockquote>

<p><strong>A better alternative would be to keep your data as flexible as possible.</strong> In order to do that, I suggest using different technologies that do one (main) thing well, then find a way to make them all work together.</p>
<p>For me, I have decided to use the Linux <em>filesystem</em> as my database, and <em>JSON</em> to store most of my data. However, I could use any format that is appropriate and easy to read and query like INI or CSV.</p>
<p>The beauty of using the filesystem is that everyone knows how to use it. It's as easy as creating files and folders and there are a number of terminal commands that make that relatively easy.</p>
<p>The beauty of using JSON is that you can easily make queries to your data using <a href="https://jqlang.github.io/jq/" title="jq official website">jq</a> (or any other JSON query language). Therefore you could make the same types of queries that you make in SQL, just with the added advantage of being able to manipulate or view data yourself. When you export your data, you don't need a special program to read it. Everything is ready to be used immediately.</p>
<p><a href="https://jqlang.github.io/jq/" title="jq official website">jq</a> also has the added benefit of <a href="/posts/the-power-of-piping" title="The power of piping">piping</a>, something that SQL lacks.</p>
<p>For data integrity with JSON, <a href="https://json-schema.org/" title="JSON Schema official website">JSON schema</a> can be used to ensure the data is saved properly.</p>
<p>Some other formats that can be used instead of SQL are plain text, XML, HTML, YAML, INI, TOML, and the list goes on. The importance of storing data as plain text cannot be overstated. This is exactly why Unix has had this as their philosophy for years, and why it scales so well in the software industry. <strong>Learn from the pros.</strong></p>
<h2 id="the-bottom-line">The bottom line</h2>
<p><strong>Stop using SQL if you can.</strong> Try to explore other data formats that are less bloated and completely readable.</p>
<p>Take the power in your own hands!</p>]]></description>
      <pubDate>Sun, 03 Mar 2024 09:18:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/the-evil-of-sql</guid>
    </item>
    <item>
      <title>www: Write What you knoW</title>
      <link>https://www.mmhq.me/posts/www-write-what-you-know</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote cite="https://www.kingjamesbibleonline.org/Ecclesiastes-9-4/">
    <p>For to him that is joined to all the living there is hope: for a living dog is better than a dead lion.</p>
    <cite>Ecclesiastes 9:4, The Bible</cite>
</blockquote>

<p>In this Wild Wide Web we surf through, all the distractions around us can derail us from remembering the true purpose of the web: expressing what you know and learning from the expression of others.</p>
<p>Recently I have been reading <a href="https://www.w3.org/People/Berners-Lee/Weaving/" title="Weaving the Web book"><em>Weaving the Web</em></a> by Tim Burners-Lee and I have been blown away. The stress that seems to keep recurring in the book is the concept of making things <em>universal</em>, simple and easy to use. Those traits indeed did make the web as accessible as it is today, a free playground for all who are interested.</p>
<p>And it is important that we remember that. It was made for us all, there is no need to gatekeep. The <a href="https://indieweb.org/plurality" title="Plurality - Indie Web">plurality</a> of choices on the web has made us get to where we are now. We are standing on the shoulders of giants by using technology that we didn't build but many put effort to make so that we can all contribute to this wonderful world we live in.</p>
<p>We are the color of the world; each voice paints a different shade. All our voices should not be followed, but at least be heard. And that's why I'm happy I can be heard on this side of the web, my little corner. Blogging is so empowering as it just allows you to express yourself free of too many rules.</p>
<p>And that's part of the reason I'm blogging right now. I don't have to prepare content to be perfect all the time. Sometimes, I could just put down exactly what flows from my head. Whether it's carefully thought out, or just ramblings and thoughts from my naive brain, I still have a medium of expression, and I can do it on my own terms, with my data, with a place I could call home online.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>If you can't own your own website from scratch, use a content management system (CMS). If you don't like that, then use a static site generator (SSG) to build your blog. If you can't do any of those things or you don't want to be bothered with that, then go ahead and release on social media sites (if you must! I prefer <a href="https://indieweb.org/why" title="Why - Indie Web">other ways</a>).</p>
<p>But don't stop writing, don't stop making content, or videos, or music, or whatever you do. The web would not be what it is if it didn't allow for unique voices. Keep the web weird!</p>
<details>
    <summary>Poem: <em>Test</em></summary>
<pre class="poem">
This is just a test I wrote
To see if this would work.
I've got to try this out real quick
And hurry back to work.

Still on break so I could take
My time to pen these words;
I hope this works but if it don't
I got a lot to learn.
</pre>
</details>]]></description>
      <pubDate>Tue, 27 Feb 2024 21:57:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/www-write-what-you-know</guid>
    </item>
    <item>
      <title>Why I believe the gospel</title>
      <link>https://www.mmhq.me/posts/why-i-believe-the-gospel</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/John-8-32/">
    <p>And ye shall know the truth, and the truth shall make you free.</p>
    <cite>John 8:32, The Bible</cite>
</blockquote>

<p><strong>I'm not writing this blog post to convince you to believe in Jesus Christ; I simply would like to give my own reasons for believing the gospel.</strong> I don't believe anybody can really be convinced through argument (or a blog post) anyway. It's a choice to believe: you hear the truth and you either accept it or reject it.</p>
<p>In this blog post, I'll discuss briefly why I believe the gospel and what it means to me.</p>
<h2>What I thought the gospel was</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Matthew-19-16/">
    <p>And, behold, one came and said unto him, Good Master, what good thing shall I do, that I may have eternal life?</p>
    <cite>Matthew 19:16, The Bible</cite>
</blockquote>

<p>Religion was no stranger in my home. I grew up in the church for all my youth; I can't remember a time when "not going to church" was acceptable in my family.</p>
<p>So I've heard it all.</p>
<p>"God loves you, but only if you do good."<br>
"Follow the ten commandments and you will go to heaven."<br>
"Give your tithes and offering so God will bless you."<br>
"Be a good person like God made everyone."<br>
"Go to church or you are a devil."<br>
"Don't question God; he knows everything and you know nothing so just shut up and follow."<br>
"Be a good person or you will die and go to hell!"<br>
"You must stay away from sin or you will die!"</p>
<p>These were the the thoughts circling in my head about God through the teachings of others. God will love me if I love him; it's that simple.</p>
<p>It makes complete sense; how many of us would love our spouses if they didn't love us back? Or if we had a father or mother that betrayed us, would we want to love them? Are they deserving of our love?</p>
<p>So it had to be true. Do good and good would be done to you. Love God and he would love you back. Heaven helps those who help themselves.</p>
<p>But they were all lies; I only found out the truth when I heard the true gospel, or as <a href="https://en.wikipedia.org/wiki/Paul_the_Apostle" title="Paul the Apostle on Wikipedia">Apostle Paul</a> puts it:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Romans-10-17/">
    <p>So then faith cometh by hearing, and hearing by the word of God.</p>
    <cite>Romans 10:17, The Bible</cite>
</blockquote>

<h2>What the gospel is</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Acts-16-30/">
    <p><span>30</span>
        And brought them out, and said, Sirs, what must I do to be saved?</p>
    <p><span>31</span>
        And they said, Believe on the Lord Jesus Christ, and thou shalt be saved, and thy house.</p>
    <cite>Acts 16:30-31, The Bible</cite>
</blockquote>

<p>There are two concepts repeated in every listed thought I had in the previous section: <strong>work</strong> and <strong>self</strong>. It was all about the <em>work</em> that <em>I</em> had to do. <em>I</em> had to "be a good person". <em>I</em> had to "give so I would be blessed". <em>I</em> had to "go to church to not be a devil".</p>
<p>This whole idea of <strong><em>our</em> work</strong> and <strong>self</strong> is the antithesis of the gospel: the gospel is about <strong>the work that Jesus Christ</strong> has done for <strong>us</strong>.</p>
<p>The gospel is simply this:</p>
<blockquote id="john-3-16" class="scripture" cite="https://www.kingjamesbibleonline.org/John-3-16/">
    <p>For God so loved the world, that he gave his only begotten Son,
        that whosoever believeth in him should not perish,
        but have everlasting life.</p>
    <cite>John 3:16, The Bible</cite>
</blockquote>

<p>Notice how no work is required from the world; the only person doing the work is God. This fundamental truth is what makes it so hard for people to understand; it goes against everything we are accustomed to as humans. (We work for everything we have, including love.)</p>
<p>The only thing God requires is <strong>belief</strong>. He wants us to believe in him. He wants us to believe that he sent his only begotten Son to die for our sins. He does not want us to prove it (or else, that would be us working); he just wants us to believe:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Hebrews-11-6/">
    <p>But without faith it is impossible to please him:
        for he that cometh to God must believe that he is,
        and that he is a rewarder of them that diligently seek him.</p>
    <cite>Hebrews 11:6, The Bible</cite>
</blockquote>

<p>After you believe in Jesus Christ <strong>once</strong>:</p>
<ul>
<li>You receive everlasting life forever right that instant.</li>
<li>The everlasting life is not contingent on your behavior i.e. sinning would not jeopardize your eternity.</li>
<li>Even if you doubt, you are still eligible for heaven because it's a free gift. Once a gift is received, it cannot be taken back.</li>
<li>You enter into your eternal rest immediately.</li>
</ul>
<p>Therefore, we can conclude that everlasting life does not come from:</p>
<ul>
<li>Praying</li>
<li>Fasting</li>
<li>Confessing your sins</li>
<li>Being righteous</li>
<li>Speaking in tongues</li>
<li>Giving all your money to the church</li>
<li>Giving to the poor</li>
<li>Attending church every Sunday</li>
<li>Evangelism</li>
<li>Singing praise</li>
<li>Casting out devils</li>
<li>Loving your neighbor</li>
<li>Loving God</li>
<li>Following Christ</li>
<li>Healing the sick</li>
<li>Prophecy</li>
<li>Etc.</li>
</ul>
<p>It comes from <strong>believing in the Lord Jesus Christ</strong> (remember <a href="/posts/why-i-believe-the-gospel#john-3-16" title="John 3:16">John 3:16</a>). None of what I listed is bad, but none of them offers you eternal life.</p>
<h2>The bottom line</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Galatians-3-11/">
    <p>But that no man is justified by the law in the sight of God, it is evident: for, The just shall live by faith.</p>
    <cite>Galatians 3:11, The Bible</cite>
</blockquote>

<p>Without the gospel, there would be no hope for me. I grew up in a Christian home and yet, I still sin. Everyday. In thought, word and deed. <a href="https://en.wikipedia.org/wiki/Book_of_Proverbs" title="The Book of Proverbs on Wikipedia">The Book of Proverbs</a> puts it like this:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Proverbs-24-9/">
    <p>The thought of foolishness is sin: and the scorner is an abomination to men.</p>
    <cite>Proverbs 24:9, The Bible</cite>
</blockquote>

<p>Every foolish thought I've had is a sin. So there is no escape for me. Except through Jesus.</p>
<p>So I believe the gospel, not because I'm strong, but because I'm weak. However, I know that he's my strength in my weakest moments:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/2-Corinthians-12-9/">
    <p>And he said unto me, My grace is sufficient for thee: for my strength is made perfect in weakness.
        Most gladly therefore will I rather glory in my infirmities,
        that the power of Christ may rest upon me.</p>
    <cite>2 Corinthians 12:9, The Bible</cite>
</blockquote>

<p>I have seen no greater love.</p>
<h2>Other resources</h2>
<ul>
<li>
<a href="https://www.youtube.com/watch?v=9M3-eybl1gQ" title="How to be saved (video) by Onorato Diamante">How to be saved from hell (video)</a> by Onorato Diamante</li>
<li>
<a href="https://www.youtube.com/watch?v=4T-NoUalLbI" title="How to be saved from hell (video) by Daniel Perez">How to be saved from hell (video)</a> by Daniel Perez</li>
<li><a href="https://carm.org/about-salvation/what-is-once-saved-always-saved" title="What is once saved always saved?">What is once saved always saved?</a></li>
</ul>]]></description>
      <pubDate>Tue, 06 Feb 2024 20:38:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/why-i-believe-the-gospel</guid>
    </item>
    <item>
      <title>The power of piping</title>
      <link>https://www.mmhq.me/posts/the-power-of-piping</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="quote" cite="https://en.wikipedia.org/wiki/Unix_philosophy#Mike_Gancarz:_The_UNIX_Philosophy">
    <p>Make every program a filter.</p>
    <cite>Mike Gancarz, The UNIX Philosophy</cite>
</blockquote>

<p>It's no secret that I love working with <a href="https://www.pcmag.com/how-to/what-is-gnulinux" title="What is GNU/Linux">GNU/Linux</a>. The ease that I get at my fingers is uncanny and like no other. I don't even have to touch my mouse most of the time.</p>
<p>In this blog, I would like to talk about how I use GNU tools and utilities, and how it helps me get work done efficiently and quickly.</p>
<h2>The problem</h2>
<p>I have 2 scripts:</p>
<p><strong>xx-print-emoji.sh</strong>: This script takes an emoji name and prints an emoji. For example:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xx-print-emoji.sh<span class="w"> </span>red_circle
🔴
$<span class="w"> </span>xx-print-emoji.sh<span class="w"> </span>yellow_circle
🟡
</code></pre></div>

<p><strong>xx-show-emoji-names.sh</strong>: This script prints all the emoji names in Unicode as a list (downloaded and cached) from the <a href="https://unicode.org/emoji/charts/full-emoji-list.html" title="Full Emoji list from unicode.org">Unicode website</a>. Printing the first 10 results yields:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>head
grinning<span class="w"> </span>face
grinning<span class="w"> </span>face<span class="w"> </span>with<span class="w"> </span>big<span class="w"> </span>eyes
grinning<span class="w"> </span>face<span class="w"> </span>with<span class="w"> </span>smiling<span class="w"> </span>eyes
beaming<span class="w"> </span>face<span class="w"> </span>with<span class="w"> </span>smiling<span class="w"> </span>eyes
grinning<span class="w"> </span>squinting<span class="w"> </span>face
grinning<span class="w"> </span>face<span class="w"> </span>with<span class="w"> </span>sweat
rolling<span class="w"> </span>on<span class="w"> </span>the<span class="w"> </span>floor<span class="w"> </span>laughing
face<span class="w"> </span>with<span class="w"> </span>tears<span class="w"> </span>of<span class="w"> </span>joy
slightly<span class="w"> </span>smiling<span class="w"> </span>face
</code></pre></div>

<p>I want to print the globe emoji in my blog text; how can I use GNU tools to get me what I want?</p>
<h2>The solution</h2>
<p>Let's go through the steps I took:</p>
<p><b>Step 1:</b> Search for <em>globe</em> in <code>xx-show-emoji-names.sh</code> results:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe
globe<span class="w"> </span>showing<span class="w"> </span>Europe-Africa
globe<span class="w"> </span>showing<span class="w"> </span>Americas
globe<span class="w"> </span>showing<span class="w"> </span>Asia-Australia
globe<span class="w"> </span>with<span class="w"> </span>meridians
</code></pre></div>

<p><b>Step 2:</b> Remove spaces from the results to make it suitable as an input for <code>xx-print-emoji.sh</code>:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe<span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/\s/_/g"</span>
globe_showing_Europe-Africa
globe_showing_Americas
globe_showing_Asia-Australia
globe_with_meridians
</code></pre></div>

<p><b>Step 3:</b> Convert <code>-</code> to <code>_</code> for all results, further making it suitable for <code>xx-print-emoji.sh</code>:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe<span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/\s/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/-/_/g"</span>
globe_showing_Europe_Africa
globe_showing_Americas
globe_showing_Asia_Australia
globe_with_meridians
</code></pre></div>

<p><b>Step 4:</b> Try the each result with <code>xx-print-emoji.sh</code>:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>xx-print-emoji.sh<span class="w"> </span><span class="k">$(</span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe<span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/\s/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/-/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-n<span class="w"> </span><span class="s2">"1p"</span><span class="k">)</span>
$<span class="w"> </span>xx-print-emoji.sh<span class="w"> </span><span class="k">$(</span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe<span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/\s/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/-/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-n<span class="w"> </span><span class="s2">"2p"</span><span class="k">)</span>
🌎
$<span class="w"> </span>xx-print-emoji.sh<span class="w"> </span><span class="k">$(</span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe<span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/\s/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/-/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-n<span class="w"> </span><span class="s2">"3p"</span><span class="k">)</span>
$<span class="w"> </span>xx-print-emoji.sh<span class="w"> </span><span class="k">$(</span>xx-show-emoji-names.sh<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>globe<span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/\s/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-e<span class="w"> </span><span class="s2">"s/-/_/g"</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sed<span class="w"> </span>-n<span class="w"> </span><span class="s2">"4p"</span><span class="k">)</span>
🌐
</code></pre></div>

<p>Bingo! The last emoji is the one I'm looking for!</p>
<h2>The bottom line</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Proverbs-13-11/">
    <p>Wealth gotten by vanity shall be diminished: but he that gathereth by labour shall increase.</p>
    <cite>Proverbs 13:11, The Bible</cite>
</blockquote>

<p>A couple takeaways:</p>
<ul>
<li>Notice how I used <code>|</code> to pipe two commands together. This feature is one of GNU's most powerful features! Every command's output can be treated as the input of another command. Every appended command can then filter the results of the previous command. This <a href="https://www.geeksforgeeks.org/pipes-and-filters-in-linux-unix/" title="Pipes and Filters">pipe-and-filter framework</a> is what makes using Linux a breeze.</li>
<li>I only used grep and sed in this blog, but there are many others like sort, unique, more, less etc. All these tools have different purposes but can be piped in the same way.</li>
<li>I could create my own script or program that uses piping in the exact same way. This modularity makes it easy to extend functionality in the future, even for unpredicted scenarios.</li>
<li>I don't have to learn a new program, or worse, learn a new user interface for the same old program. I could just use what's available on my computer.</li>
<li>GNU tools take very little space on my computer but offer infinite value.</li>
<li>It puts bigger applications to shame. They all use far more memory and some run slower than GNU tools.</li>
</ul>
<h2>Further reading</h2>
<ul>
<li><a href="https://www.geeksforgeeks.org/pipes-and-filters-in-linux-unix/" title="Pipes and Filters">Pipes and filters</a></li>
</ul>]]></description>
      <pubDate>Sun, 04 Feb 2024 14:21:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/the-power-of-piping</guid>
    </item>
    <item>
      <title>Giving my text a face</title>
      <link>https://www.mmhq.me/posts/giving-my-text-a-face</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Proverbs-16-15/">
    <p>In the light of the king's countenance is life; and his favour is as a cloud of the latter rain.</p>
    <cite>Proverbs 16:15, The Bible</cite>
</blockquote>

<p>Recently, I've looking at different websites on my RSS feed. I do that from time-to-time to steal ideas from others on what to put on this website.</p>
<p>I noticed the use of emojis on some websites and I thought that would be a great addition. Adding emojis could help <a href="https://www.psychologytoday.com/us/blog/articles-heterodoxy/202207/emojis-can-help-you-communicate-quickly-and-clearly" title="Emojis can help you communicate quickly and clearly">communicate some ideas more effectively</a> and <a href="https://buffer.com/resources/7-reasons-use-emoticons-writing-social-media-according-science/#2-we-react-to-them-like-we-would-real-human-face" title="We react to emojis like we would real human face">invoke emotions</a> in the readers of this blog. I see it as "changing the countenance of my text".</p>
<p>It's also a plus that emojis mean more to humans than they do to bots 😜.</p>
<p>In this article, I would like to discuss how I added emoji support to my Linux terminal and ultimately, this website.</p>
<h2 id="its-face-time">It's face time!</h2>
<blockquote class="definition" cite="https://www.websters1913.com/words/Countenance">
    <p>countenance (n) - Appearance or expression of the face; look; aspect; mien.</p>
    <cite>Definition of countenance, Webster dictionary (1913)</cite>
</blockquote>

<p>It should be no surprise by now that <a href="/posts/my-setup#my-software-tools" title="My software tools">I use Vim as a text editor for everything</a>, from code to documents; I do most of my work from inside a terminal. Rendering color emojis in the terminal does not work right-out-the-box. (<a href="https://knowyourmeme.com/memes/btw-i-use-arch" title="BTW I use Arch">I use Arch BTW</a> 🤓.)</p>
<p>While searching for a solution online, I came across <a href="https://pypi.org/project/emoji/" title="Emoji Python package on PyPI">emoji</a>, a Python package for printing emojis, so I installed it on my computer:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>python-emoji
</code></pre></div>

<p>After the installation, I tried to print color emojis to my terminal, and lo and behold, it didn't work:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>python
&gt;&gt;&gt;<span class="w"> </span>import<span class="w"> </span>emoji
&gt;&gt;&gt;<span class="w"> </span>emoji.emojize<span class="o">(</span><span class="s2">":thumbs_up:"</span><span class="o">)</span>

&gt;&gt;&gt;
</code></pre></div>

<h2 id="emoji-meet-terminal">Emoji, meet Terminal (😀 + 👨‍💻)</h2>
<blockquote class="quote" cite="https://en.wikipedia.org/wiki/Emoji">
    <p>Originally meaning pictograph, the word emoji comes from Japanese e (絵, 'picture') + moji (文字, 'character'); the resemblance to the English words emotion and emoticon is purely coincidental.</p>
    <cite>Emoji article, Wikipedia</cite>
</blockquote>

<p>I found an <a href="https://chrpaul.de/posts/2019-07-19-enable-colour-emoji-support-on-manjaro-linux/" title="Enable colour emoji support on Manjaro Linux">article</a> that explained the two steps required to add color emoji support to my terminal.</p>
<p>First I installed the Noto Emoji Font on my computer:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>pacman<span class="w"> </span>-S<span class="w"> </span>noto-fonts-emoji
</code></pre></div>

<p>Then I set up <code>fonts.conf</code>: </p>
<div class="codehilite"><pre><span></span><code><span class="cp">&lt;?xml version="1.0"?&gt;</span>
<span class="cp">&lt;!DOCTYPE fontconfig SYSTEM "fonts.dtd"&gt;</span>
<span class="nt">&lt;fontconfig&gt;</span>
<span class="w">    </span><span class="nt">&lt;alias&gt;</span>
<span class="w">        </span><span class="nt">&lt;family&gt;</span>sans-serif<span class="nt">&lt;/family&gt;</span>
<span class="w">        </span><span class="nt">&lt;prefer&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Sans<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Color<span class="w"> </span>Emoji<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Emoji<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>DejaVu<span class="w"> </span>Sans<span class="nt">&lt;/family&gt;</span>
<span class="w">        </span><span class="nt">&lt;/prefer&gt;</span>
<span class="w">    </span><span class="nt">&lt;/alias&gt;</span>
<span class="w">    </span><span class="nt">&lt;alias&gt;</span>
<span class="w">        </span><span class="nt">&lt;family&gt;</span>serif<span class="nt">&lt;/family&gt;</span>
<span class="w">        </span><span class="nt">&lt;prefer&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Serif<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Color<span class="w"> </span>Emoji<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Emoji<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>DejaVu<span class="w"> </span>Serif<span class="nt">&lt;/family&gt;</span>
<span class="w">        </span><span class="nt">&lt;/prefer&gt;</span>
<span class="w">    </span><span class="nt">&lt;/alias&gt;</span>
<span class="w">    </span><span class="nt">&lt;alias&gt;</span>
<span class="w">        </span><span class="nt">&lt;family&gt;</span>monospace<span class="nt">&lt;/family&gt;</span>
<span class="w">        </span><span class="nt">&lt;prefer&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Mono<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Color<span class="w"> </span>Emoji<span class="nt">&lt;/family&gt;</span>
<span class="w">            </span><span class="nt">&lt;family&gt;</span>Noto<span class="w"> </span>Emoji<span class="nt">&lt;/family&gt;</span>
<span class="w">        </span><span class="nt">&lt;/prefer&gt;</span>
<span class="w">    </span><span class="nt">&lt;/alias&gt;</span>
<span class="nt">&lt;/fontconfig&gt;</span>
</code></pre></div>

<p>After saving the file to <code>~/.config/fontconfig/</code> and re-opening my terminal, I ran:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>python
&gt;&gt;&gt;<span class="w"> </span>import<span class="w"> </span>emoji
&gt;&gt;&gt;<span class="w"> </span>emoji.emojize<span class="o">(</span><span class="s2">":thumbs_up:"</span><span class="o">)</span>
<span class="s1">'👍'</span>
&gt;&gt;&gt;
</code></pre></div>

<p>Voila!</p>
<h2>The bottom line</h2>
<p>Even though Arch Linux does not support displaying color emojis in the terminal right-out-the-box, adding the functionality to your computer is pretty straightforward. I created a script for myself that can print an emoji:</p>
<div class="codehilite"><pre><span></span><code><span class="ch">#!/bin/sh</span>

usage<span class="o">()</span><span class="w"> </span><span class="o">{</span>
<span class="w">    </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Usage: `basename </span><span class="nv">$0</span><span class="s2">` EMOJI"</span>
<span class="w">    </span><span class="nb">echo</span>
<span class="w">    </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Prints an emoji in the terminal"</span>
<span class="w">    </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"Example: `basename </span><span class="nv">$0</span><span class="s2">` thumbs_up"</span>
<span class="o">}</span>

<span class="nv">EMOJI</span><span class="o">=</span><span class="nv">$1</span>

<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="nv">$#</span><span class="w"> </span>-eq<span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w">    </span>usage
<span class="w">    </span><span class="nb">exit</span><span class="w"> </span><span class="m">1</span>
<span class="k">fi</span>

python<span class="w"> </span>-c<span class="w"> </span><span class="s2">"import emoji; e = emoji.emojize(':</span><span class="nv">$EMOJI</span><span class="s2">:'); print(e) if emoji.is_emoji(e) else print(end='')"</span>
</code></pre></div>

<p>With this script, I could easily print the "thumbs-up" emoji onto my Markdown file by executing <code>r! xx-print-emoji.sh thumbs_up</code> in Vim.</p>
<p>Expect to see a random emojis in posts to come!</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Emoji" title="Emoji article">Emoji article on Wikipedia</a></li>
<li>
<a href="https://chrpaul.de/posts/2019-07-19-enable-colour-emoji-support-on-manjaro-linux/" title="Enable colour emoji support on Manjaro Linux">Enable color emoji support on Manjaro Linux</a> (Works for Arch Linux too!)</li>
</ul>]]></description>
      <pubDate>Wed, 31 Jan 2024 15:00:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/giving-my-text-a-face</guid>
    </item>
    <item>
      <title>My setup</title>
      <link>https://www.mmhq.me/posts/my-setup</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Ecclesiastes-5-3/">
    <p>For a dream cometh through the multitude of business; and a fool's voice is known by multitude of words.</p>
    <cite>Ecclesiastes 5:3, The Bible</cite>
</blockquote>

<p><strong>Complexity has always been a sworn enemy of mine.</strong> I have abandoned whole codebases and projects because of complexity. I try my best to keep it out of my life because it brings about unnecessary stress.</p>
<p>That being said, <strong>I have a setup that gives me control and scale without sacrificing simplicity</strong>. In this blog post, I would like to discuss the computer setup that works for me and why it does.</p>
<h2 id="the-unix-philosophy">The UNIX philosophy</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Ecclesiastes-5-7/">
    <p>For in the multitude of dreams and many words there are also divers vanities: but fear thou God.</p>
    <cite>Ecclesiastes 5:7, The Bible</cite>
</blockquote>

<p>I use the <a href="https://en.wikipedia.org/wiki/Unix_philosophy#Mike_Gancarz:_The_UNIX_Philosophy" title="The UNIX Philosophy article">UNIX philosophy</a> to help guide my decisions:</p>
<ol>
<li>Small is beautiful.</li>
<li>Make each program do one thing well.</li>
<li>Build a prototype as soon as possible.</li>
<li>Choose portability over efficiency.</li>
<li>Store data in flat text files.</li>
<li>Use software leverage to your advantage.</li>
<li>Use shell scripts to increase leverage and portability.</li>
<li>Avoid captive user interfaces.</li>
<li>Make every program a filter.</li>
</ol>
<h2 id="my-software-setup">My software stack</h2>
<p>Let's talk about my software stack from the ground up:</p>
<h3 id="operating-system">Operating system</h3>
<p>I use <a href="https://archlinux.org/" title="Arch Linux official website">Arch Linux</a> (<a href="https://knowyourmeme.com/memes/btw-i-use-arch" title="BTW I use Arch meme">BTW</a>). I find it to be the easiest Linux distribution I've used so far, though I would only recommend it to people who understand Linux very well, or are willing to learn.</p>
<p>Linux tries to follow all the Unix philosophy rules, as Linux is a free version of Unix.</p>
<h3 id="reverse-proxy-server">Reverse proxy server</h3>
<p>My reverse proxy server of choice is <a href="https://nginx.org/en/" title="Nginx official website">Nginx</a>.</p>
<h3 id="web-server">Web server</h3>
<p>My web server of choice is <a href="https://uwsgi-docs.readthedocs.io/en/latest/" title="uWSGI docs official website">uWSGI</a>. I previously used <a href="https://gunicorn.org/" title="Green Unicorn official website">gunicorn</a>, but it seemed to take too much RAM, so I swapped it out.</p>
<h3 id="database">Database</h3>
<p>For my database, I use the Linux filesystem. No <a href="https://en.wikipedia.org/wiki/SQL" title="SQL article">SQL</a>, no <a href="https://en.wikipedia.org/wiki/NoSQL" title="NoSQL article">NoSQL</a>, just the filesystem. I prefer to store my posts as <a href="https://www.markdownguide.org/" title="Markdown Guide">Markdown</a> (<code>.md</code>) files. I find this easier to manage.</p>
<p>I never actually thought that this style could scale until I tried it for myself. So far, I'm loving the freedom it brings; I could go to any saved file and read it directly. No passwords, no checking if the database is up and running, no trying to optimize SQL queries, nada!</p>
<p>This method affords me the luxury of using any file format I want, depending on what I require at the time. For any structured data, I plan to use the <a href="https://www.json.org/json-en.html" title="JSON official website">JSON</a> file format, <a href="https://json-schema.org/" title="JSON Schema official website">JSON Schema</a>, and <a href="https://jqlang.github.io/jq/" title="jq official website">jq</a> as a query language.</p>
<h3 id="web-framework">Web framework</h3>
<p>My web framework of choice is <a href="https://flask.palletsprojects.com/en/3.0.x/" title="Flask framework official website">Flask</a>. I love it because it's a microframework and it just stays out of the way after it hands its requests to me.</p>
<h3 id="server-side-scripting">Server-side scripting</h3>
<p>Let the snake take its rightful place! <a href="https://www.python.org/" title="Python programming language official website">Python</a> is my language of choice due to its simplicity and online support. I also like that it's a language that you could do whatever you like with as it's not closed source in any way.</p>
<p>Python gets a bad rap for its speed, but it has not proven to be a problem since I have started using it. I did get a long lag on loading my pages before, but that was because of a poorly thought-out code.</p>
<h3 id="content-and-structure">Content and structure</h3>
<p>I create all my website structure with <a href="https://developer.mozilla.org/en-US/docs/Web/HTML" title="HTML on MDN">HTML</a> using Jinja2 as my template engine of choice.</p>
<h3 id="layout-and-styling">Layout and styling</h3>
<p>I create my layouts and styling with <a href="https://developer.mozilla.org/en-US/docs/Web/CSS" title="CSS on MDN">CSS</a>. I don't use any libraries or frameworks.</p>
<h3 id="client-side-scripting">Client-side scripting</h3>
<p>I create my client-side scripts with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" title="JavaScript on MDN">JavaScript</a>. I don't use any frameworks, but I do use libraries when necessary (like of rendering code snippets).</p>
<h2 id="my-software-tools">My software tools</h2>
<ul>
<li>
<b>Text editor</b>: <a href="https://www.vim.org/" title="Vim editor official website">Vim</a> (for all text editing)</li>
<li>
<b>Terminal emulator</b>: <a href="https://alacritty.org/" title="Alacritty official website">Alacritty</a>
</li>
<li>
<b>Window manager</b>: <a href="https://awesomewm.org/index.html" title="Awesome WM official website">Awesome WM</a>
</li>
<li>
<b>Bible program</b>: <a href="https://www.thegeekdiary.com/kjv-command-examples-in-linux/" title="KJV program for Linux">kjv</a>
</li>
<li>
<b>Source-control</b>: <a href="https://git-scm.com/" title="Git official website">git</a> (for posts too)</li>
<li>
<b>GNU tools and utilities</b>: <a href="https://www.gnu.org/software/grep/manual/grep.html" title="grep on The GNU Project website">grep</a>, <a href="https://www.gnu.org/software/sed/manual/sed.html" title="sed on The GNU Project website">sed</a>
</li>
<li>Custom shell scripts</li>
</ul>
<h2 id="my-hardware-stack">My hardware stack</h2>
<ul>
<li>
<b>Laptop</b>: Dell XPS 13 9310 (purchased July 2022)</li>
<li>
<b>Chromebook</b>: Acer Chromebook 11 N7 11.6" 16GB (purchased March 2022)</li>
</ul>
<p><em>NOTE: For both my laptop and my Chromebook, I run Arch Linux.</em></p>
<ul>
<li>
<b>Monitors</b>:<ul>
<li>HP monitor</li>
<li>Dell Ultra HD 4K Monitor P2415Q 24-Inch Screen LED-Lit Monitor (purchased August 2020)</li>
</ul>
</li>
<li>
<b>Bluetooth keyboard</b>: Anne Pro 2 (purchased May 2020)</li>
<li>
<b>Mouse</b>: <a href="https://www.logitech.com/en-us/mx/master-series.html" title="Logitech MX Master 3">Logitech MX Master 3</a> (purchased March 2021)</li>
</ul>
<h2 id="on-my-desk">On my desk</h2>
<ul>
<li>Gravity cube timer</li>
<li>
<b>Headset</b>: Audio-technica ATH-M50x</li>
<li>
<b>Microphone</b>: Razer Seiren Mini USB Condenser Microphone (purchased Apr 2022)</li>
<li>
<b>Toy</b>: Funko Pop! Marvel Bobblehead Captain Marvel</li>
<li>
<b>Bluetooth headphones</b>: Bose Comfort Quiet 35 III</li>
<li>
<b>Speakers</b>: Bose Companion 2 Series III Multimedia Speaker System (purchased August 2020)</li>
<li>
<b>Hard drive</b>: Samsung Portable SSD T7 1 TB</li>
<li>
<b>MIDI controllers</b>:<ul>
<li>Akai Professional LPD8 (purchased January 2021)</li>
<li>Launchpad Mini MK3 (purchased March 2021)</li>
</ul>
</li>
<li>
<b>MIDI pianos</b>:<ul>
<li>Yamaha Piaggero NP-11 (purchased December 2020)</li>
<li>Yamaha Reface CP (purchased Oct 2020)</li>
</ul>
</li>
</ul>
<h2 id="why-do-i-have-this-setup">Why do I have this setup?</h2>
<ul>
<li>It's simple!</li>
<li>Using Arch Linux on both computers makes it easier to set up the same software on both computers.</li>
<li>Using Arch Linux on both computers allows them to use the same scripts.</li>
<li>Because the Chromebook only has 16 GB of hard disk space, the tools I use must not be too large or I would run out of space quickly. This motivates me to keep my files as flat as possible and to use the <a href="https://www.gnu.org/" title="The GNU project official website">GNU</a> tools already present on the computer (or are very small in size once installed).</li>
<li>With the Chromebook, I get to see how people with lower resources experience my site.</li>
<li>It's easy to setup again if anything happens to my computers.</li>
<li>Creating custom shell scripts to do specific tasks is quick and easy.</li>
<li>
<a href="https://archlinux.org/pacman/" title="pacman on Arch Linux website">pacman</a> (not to be confused with <a href="https://en.wikipedia.org/wiki/Pac-Man" title="Pac-Man article">Pac-Man</a>) is the best package manager I have used. It's simple and straight to the point and it is Arch Linux's default package manager. I also use <a href="https://github.com/Jguer/yay?tab=readme-ov-file#yay" title="yay on GitHub">yay</a> (not to be confused with the song "<a href="https://www.youtube.com/watch?v=lPe09eE6Xio" title="Ye - Burna Boy">Ye</a>" by Burna boy or the artist "<a href="https://en.wikipedia.org/wiki/Kanye_West" title="Ye aka Kanye West">Ye</a>", though they are all pronounced the same way) to get a plethora of other packages not available on the standard Arch repositories.</li>
</ul>
<h2 id="the-bottom-line">The bottom line</h2>
<p>Don't let anyone tell you what you can or cannot use.</p>
<p><a href="https://en.wikipedia.org/wiki/KISS_principle" title="The KISS principle">Keep it simple</a>. Choose <a href="https://indieweb.org/plurality" title="IndieWeb on Plurality">whatever works for you</a>.</p>]]></description>
      <pubDate>Wed, 31 Jan 2024 12:00:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/my-setup</guid>
    </item>
    <item>
      <title>Cache rules everything around me (C.R.E.A.M.)</title>
      <link>https://www.mmhq.me/posts/cache-rules-everything-around-me</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<p>For the past couple days, I've been battling with some refresh issues in my browser. In this blog post, I'd like to talk about these issues, and how I resolved them.</p>
<h2 id="the-problem">The problem</h2>
<p>I was making updates to this website. I was trying to apply some of the principles I learned from <a href="https://heydonworks.com" title="Heydon Pickering's website">Heydon Pickering</a> and <a href="https://andy-bell.co.uk" title="Andy Bell's website">Andy Bell</a>'s book <a href="https://every-layout.dev/" title="Every Layout">Every Layout</a> and <a href="https://utopia.fyi/" title="Utopia - Fluid Responsive Design">Utopia</a> to my <a href="https://developer.mozilla.org/en-US/docs/Web/CSS" title="CSS">CSS stylesheets</a>. I had to make some updates to my <a href="https://developer.mozilla.org/en-US/docs/Web/HTML" title="HTML">HTML</a> code, so I did that first.</p>
<p>Next, I updated my stylesheets. I refreshed my browser page on my laptop. The changes didn't show immediately, so I did a <a href="https://www.wikihow.com/Force-Refresh-in-Your-Internet-Browser" title="Force refresh in your internet browser">force-refresh</a>, then I see my stylesheet updates.</p>
<p>I refreshed the page on my phone; no updates.</p>
<h2 id="the-culprit">The culprit</h2>
<blockquote class="definition" cite="http://wordnetweb.princeton.edu/perl/webwn?s=cache&amp;sub=Search+WordNet&amp;o2=&amp;o0=1&amp;o8=1&amp;o1=1&amp;o7=&amp;o5=&amp;o9=&amp;o6=&amp;o3=&amp;o4=&amp;h=">
    <p>cache (n) - a hidden storage space (for money or provisions or weapons)</p>
    <cite>The definition of cache, WordNet 3.0 (2006)</cite>
</blockquote>

<p>Immediately I thought to myself, "This must be a cache issue". A cache, in the "web browser sense", is a temporary store for files that are expected to change infrequently. The web browser uses this to hasten the time it takes for webpages to load by only downloading files when necessary.</p>
<p>This wouldn't be the first time I have battled with the cache. I usually would clear my phone's browser history, but I told myself, no, not today.</p>
<p>No more would I bow to this Pharoah; I had to figure out the proper way to fix it.</p>
<h2 id="digital-dialogue">Digital dialogue</h2>
<p>This is how I remember the events taking place:</p>
<p><i>I open <code>https://mmhq.me</code> on my phone's web browser.</i></p>
<p><b>Browser</b>: Hello <em>Server</em>, can you get me the page called <code>https://mmhq.me</code>?<br>
<b>Server</b>: Sure <em>Browser</em>! Here you go!</p>
<p><i>Server sends a webpage as a response.</i></p>
<p><b>Browser</b>: Thanks! I'll store the stylesheet in my cache so I don't have to ask you again.<br>
<b>Server</b>: I don't know what currency you are using, but sure, if you want to I guess.<br>
<b>Browser</b>: No, it's not money. It's more like a hidden storage space where humans usually keep for money or provisions or deadly weapons, but I choose to use mine to keep the stylesheets and images. That way, I don't have to download them again when I ask you for the same page again.<br>
<b>Server</b>: Okie-dokie, that's fine with me.</p>
<p><i>I make changes to my website, then refresh the page on my phone's web browser.</i></p>
<p><b>Browser</b>: Hey Server. Any updates for me?<br>
<b>Server</b>: Good question. Let me check with <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control" title="Cache Control"><em>Cache Control</em></a>... Yes, there are updates for you.<br>
<b>Browser</b>: Cache control? I thought you didn't know what a cache was?<br>
<b>Server</b>: I didn't, until Admin informed me about them yesterday. They pretty much give me instructions on how all caching is down around here.<br>
<b>Browser</b>: Oh okay. Could you hit me with the update?<br>
<b>Server</b>: I would, but  <em>Cache Control</em> says that what you have is still fresh, so I'm not going to send you anything until they declare it stale.<br>
<b>Browser</b>: Errm, okay. I guess the update is no update.</p>
<p><i>I learn about Cache Control online, and learn that none has been set for my website, so I must have been using the default. I set my <code>Cache-control</code> to <code>public, no-store</code> and refresh the page on my phone.</i></p>
<p><b>Browser</b>: Knock, knock! Guess who?<br>
<b>Server</b>: Browser, you again. What a surprise!<br>
<b>Browser</b>: I know right, it's been a whole 2 minutes and 45 seconds since I heard from you last.<br>
<b>Server</b>: Lucky for you, I do have updates now fresh from <em>Cache Control</em>, but don't store any of it in your cache. Always ask me for the latest and greatest.<br>
<b>Browser</b>: Why not? Are you telling me what to do with my money?<br>
<b>Server</b>: Not at all. These are just orders from <em>Cache Control</em>. I don't make orders, I just enforce them.</p>
<p><i>After seeing my changes work now, I update <code>Cache-control</code> to <code>public, max-age=806400</code> and refresh the page.</i></p>
<p><b>Browser</b>: Guess who's back, back again...<br>
<b>Server</b>: Browser, wasn't expecting you. I have updates for you, and these updates are going to last at least 86400 seconds.<br>
<b>Browser</b>: 86400 seconds? How many decades is that?<br>
<b>Server</b>: A day. I'll have updates by then.<br>
<b>Browser</b>: Oh! Alright, <a href="https://www.urbandictionary.com/define.php?term=bet" title="Definition of bet in the Urban dictionary">bet</a>.</p>
<p><i>I refresh the page.</i></p>
<p><b>Browser</b>: Hi!<br>
<b>Server</b>: Browser, to what do I owe the pleasure?<br>
<b>Browser</b>: Just need another update.<br>
<b>Server</b>: Sure, I would love to give it to you.<br>
<b>Browser</b>: Great, hand it over.<br>
<b>Server</b>: You didn't let me finish. I would love to give it to you, but Cache Control says no.<br>
<b>Browser</b>: What? Why?<br>
<b>Server</b>: Because they said to come back after a day has fully elapsed.<br>
<b>Browser</b>: But I need updates now.<br>
<b>Server</b>: Those are my orders. They also said that if you don't want to adhere, you could "Cache them outside".<br>
<b>Browser</b>: Look, there is no need for all that. I don't want any problems.<br>
<b>Server</b>: Cool, return in a day. Enjoy your stale content while you can.<br>
<b>Browser</b>: Fine, I'm gone.</p>
<p><i>I update my server to support cache-busting through a <a href="https://flask.palletsprojects.com/en/3.0.x" title="Flask web framework">Flask</a> plugin and refresh the page a couple times.</i></p>
<p><b>Browser</b>: Hello, server! I know I've pinged you a billion times, but I need the new updates. The user won't stop refreshing the page.<br>
<b>Server</b>: Just in time, Browser! The web admin just implemented <a href="https://www.keycdn.com/support/what-is-cache-busting#what-is-cache-busting" title="What is cache-busting">cache-busting</a>!<br>
<b>Browser</b>: Cache-busting? Are you accusing me? Sounds like you got the wrong cache. My cache is not involved in any criminal acts, we don't do money laundering.<br>
<b>Server</b>: No accusation here. It just means that from this request and beyond, you would be able to eat your cake and have it too.<br>
<b>Browser</b>: I can? <a href="https://www.youtube.com/watch?v=2RcAzPMhdB0" title="How Sway">How sway</a>?<br>
<b>Server</b>: Because I can just send you an updated version of the file, with a different name. In other words, you could "cache me if you can"; that means you could cache the file, if it is presented to you as a new URL.<br>
<b>Browser</b>: So you are saying that you can send the same file <code>https://mmhq.me/static/css/style.css</code> as <code>https://mmhq.me/static/css/style.css?v=1</code>, that way I could <a href="https://www.keycdn.com/support/what-is-cache-busting#3-query-strings" title="Cache-busting with query strings">store both of them</a>? That's genius!<br>
<b>Server</b>: I know, Cache Control came up with the whole idea.<br>
<b>Browser</b>: Hmmm, I guess they're not so bad after all.</p>
<p><i>I update my server to remove cache-busting through a Flask plugin and create my own solution; I refresh the page.</i></p>
<p><b>Browser</b>: Hello, server! You've sent me blank images for the past 20 refreshes now. Why aren't you sending your images anymore?<br>
<b>Server</b>: Not sure....wait, this just in. Cache Control says the Flask cache-buster plugin was a bust. The web admin decided to uninstall it and create his own solution. Everything is up and running now.<br>
<b>Browser</b>: I knew cache-busting sounded sketchy. I guess it doesn't hurt to <em>drink from your own cistern or to draw water from your own well</em>, but what do I know? I'm just a browser!</p>
<p><i>Browser and Server got a beer together after. The end.</i></p>
<h2>The bottom line</h2>
<blockquote class="verse" cite="https://genius.com/Wu-tang-clan-cream-lyrics">
<pre>
Cash rules everything around me
C.R.E.A.M., get the money
Dollar dollar bill, y'all
</pre>
<cite>Method Man, on the song C.R.E.A.M.</cite>
</blockquote>

<p>The cache is an indispensable tool hidden in every browser. Are you making the most of it, or making it do the most?</p>
<h2>Further reading</h2>
<ul>
<li><a href="https://medium.com/pixelpoint/best-practices-for-cache-control-settings-for-your-website-ff262b38c5a2" title="Cache control settings">Best Practices for Cache Control</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control" title="Cache Control">Cache Control on MDN</a></li>
<li><a href="https://www.keycdn.com/support/what-is-cache-busting#what-is-cache-busting" title="What is cache-busting">Cache-busting</a></li>
<li><a href="https://www.keycdn.com/support/what-is-cache-busting#3-query-strings" title="Cache-busting with query strings">Cache-busting with query strings</a></li>
<li>
<a href="https://web.dev/" title="Web dev">web.dev</a>, where I learn about the web</li>
</ul>]]></description>
      <pubDate>Thu, 25 Jan 2024 00:40:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/cache-rules-everything-around-me</guid>
    </item>
    <item>
      <title>"X" marks the spot: my first chiasmus analysis</title>
      <link>https://www.mmhq.me/posts/x-marks-the-spot-my-first-chiasmus-analysis</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Job-33-14/">
    <p>For God speaketh once, yea twice, yet man perceiveth it not.</p>
    <cite>Job 33:14, The Bible</cite>
</blockquote>

<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Psalm-62-11/">
    <p>For God hath spoken once; twice have I heard this; that power belongeth unto God.</p>
    <cite>Psalms 62:11, The Bible</cite>
</blockquote>

<p>I have been reading a lot about literary structures used in the Bible. One structure that recurs often is the <a href="https://www.litcharts.com/literary-devices-and-terms/chiasmus" title="Chiasmus definition">chiasmus</a>. In this blog post, we'll be analyzing the first chiasmus I discovered myself while studying the Bible.</p>
<h2 id="what-is-a-chiasmus">What is a chiasmus?</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Mark-10-31/">
    <p>But many that are first shall be last; and the last first.</p>
    <cite>Mark 10:31, The Bible</cite>
</blockquote>

<p>A chiasmus is an inversion of the relationship between the elements of phrases, or in simpler terms, inverted parallelism. <a href="https://www.litcharts.com/literary-devices-and-terms/parallelism" title="Parallelism definition">Parallelism</a> is the repetition of grammatical elements in writing and speaking. Examples of parallelism in grammar would be the following:</p>
<ul>
<li><em>no pain, no gain</em></li>
<li><em>in for a penny, in for a pound</em></li>
<li>where <em>there is smoke</em>, <em>there is fire</em>
</li>
<li>it <em>takes one</em> to <em>know one</em>
</li>
</ul>
<p>As you can see from the examples listed, each phrase has repeated grammatical elements, even though the content of the elements themselves are unique. Here the parallelism is obvious; the words that appear in the same position are paralleled:</p>
<ul>
<li>
<em>pain</em> and <em>gain</em>
</li>
<li>
<em>penny</em> and <em>pound</em>
</li>
<li>
<em>smoke</em> and <em>fire</em>
</li>
<li>
<em>takes</em> and <em>knows</em>
</li>
</ul>
<p>All other words are the same. A chiasmus flips this concept:</p>
<ul>
<li>Never let a fool kiss you or a kiss fool you. (Note <em>fool</em>/<em>kiss</em> and <em>kiss</em>/<em>fool</em>.)</li>
<li>The sabbath was made for man, not man for the sabbath. (Note <em>sabbath</em>/<em>man</em> and <em>man</em>/<em>sabbath</em>.)</li>
</ul>
<p>This is the basic idea of a chiasmus, <em>the first becomes the last, and the last the first</em>. Words are still paralleled, but there is an inversion.</p>
<p>Because of how the words are "crossed", the letter "X" is usually associated with the concept. (The prefix "chi-" in Greek represents "X".)</p>
<h2 id="my-analysis-of-deuteronomy-18">My analysis of Deuteronomy 18</h2>
<p>Just as sentences can have parallelism and chiasmi, so can entire scriptures:</p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Deuteronomy-18-9/">
    <p><span>9</span>
        When thou art come into the land which the LORD thy God giveth thee, thou shalt not learn to do after the abominations of those nations.</p>
    <p><span>10</span>
        There shall not be found among you any one that maketh his son or his daughter to pass through the fire, or that useth divination, or an observer of times, or an enchanter, or a witch,</p>
    <p><span>11</span>
        Or a charmer, or a consulter with familiar spirits, or a wizard, or a necromancer.</p>
    <p><span>12</span>
        For all that do these things are an abomination unto the LORD: and because of these abominations the LORD thy God doth drive them out from before thee.</p>
    <p><span>13</span>
        Thou shalt be perfect with the LORD thy God.</p>
    <p><span>14</span>
        For these nations, which thou shalt possess, hearkened unto observers of times, and unto diviners: but as for thee, the LORD thy God hath not suffered thee so to do.</p>
    <cite>Deuteronomy 18:9-14, The Bible</cite>
</blockquote>

<p>In the scripture quoted above, God instructs his people to not commit abomination in the land he's about to give to them, or else he would drive them out like he did to the nations before them. It's not really what God says here I'm interested in, but how he says it. He used a chiastic structure, as we discussed in the previous section. How you ask? Let's break it down:</p>
<p>In summary, we can say that the passage is saying:</p>
<pre>
<b>(A)</b>  - Don't do as other nations (v. 9)
    <b>(B)</b>  - What you should not do (v. 10-11)
        <b>(C)</b>  - I drove the nations out because of the abominations (v. 12)
    <b>(B')</b> - What you should do (v. 13)
<b>(A')</b> - What other nations did (v. 14)
</pre>

<p>The structure can be summarized as <strong>A - B - C - B' - A'</strong>. The point of what God is trying to say, sort of like the climax in a movie, is at the center. A/A' and B/B' surround the point and support it.</p>
<h2 id="why-does-any-of-this-matter">Why does any of this matter?</h2>
<ul>
<li>Form is important, even God uses it. Chiastic structures are used repeatedly in the Bible, and God uses it as a teaching tool for his people.</li>
<li>God repeats himself a lot (mainly because <em>man</em> doesn't pay attention).</li>
<li>Chiastic structures can be used to echo important ideas, and present the point of what you are saying very strongly in the center, like a bold large header on a document to the normal sized text of its body font.</li>
<li>Chiastic structures are still used in art today, like movies, poetry and even music!</li>
</ul>
<h2 id="the-bottom-line">The bottom line</h2>
<p>Learning literary structures would only help you to appreciate design and have a deeper understanding of the Bible. Equipping yourself with this knowledge can distinguish you from shallow readers.</p>]]></description>
      <pubDate>Sun, 31 Dec 2023 14:59:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/x-marks-the-spot-my-first-chiasmus-analysis</guid>
    </item>
    <item>
      <title>The Bible is lit!</title>
      <link>https://www.mmhq.me/posts/the-bible-is-lit</link>
      <description><![CDATA[<p><picture><img alt="The Bible open" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/the-bible-open.webp" srcset="/static/data/images/360w/the-bible-open.webp 360w, /static/data/images/640w/the-bible-open.webp 640w, /static/data/images/1080w/the-bible-open.webp 1080w, /static/data/images/1280w/the-bible-open.webp 1280w" title="The Bible open"></picture></p>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Genesis-1-4/">
    <p>And God saw the light, that it was good: and God divided the light from the darkness.</p>
    <cite>Genesis 1:4, The Bible</cite>
</blockquote>

<p>Yes, the Good Book. We all think of it as the moral code of God, the standards to follow to live a righteous life. But what if I told you it's so much more? In this blog post, we would be taking a look at what makes the Bible <em>lit</em>.</p>
<h2 id="the-bible-is-lit-like-light">The Bible is lit, like light</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Psalm-119-105/">
    <p>Thy word is a lamp unto my feet, and a light unto my path.</p>
    <cite>Psalm 119:105, The Bible</cite>
</blockquote>

<p>The Bible provides direction for us to use in our everyday lives to inch towards true freedom. The stories narrated in the Bible have helped to be a light in this dark life we live in. It tells us what is right and what is wrong, but does so without judging the reader directly. It exposes the stories of others and allows you to learn from those stories.</p>
<h2 id="the-bible-is-literature">The Bible is lit(-erature)</h2>
<blockquote class="scripture" cite="https://www.kingjamesbibleonline.org/Psalm-119-103/">
    <p>How sweet are thy words unto my taste! yea, sweeter than honey to my mouth!</p>
    <cite>Psalm 119:103, The Bible</cite>
</blockquote>

<p>Yes, the Bible is literature. It wasn't until I read books like <em>A Complete Handbook of Literary Forms in the Bible</em> by Leland Ryken that I came to this conclusion. The Bible is full of literary devices; this shows how important their roles are in communication, particularly communication of truth. We often take literature for granted and falsely equate it to fiction, but literature is deeper than that. Language in the Bible (like every other thing in the cosmos) is expressed through both function and form.</p>
<p>Recently, I also discovered that the Bible <a href="http://www.bible.literarystructure.info/bible/bible_e.html" title="Literary structures in the Bible">uses literary devices like chiasmi and concentric structures much more extensively than I once imagined</a>. Literary structure may not be at the foundation of the Bible, but it definitely adds the icing on the cake that makes an otherwise bland cake sweet.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>If you are looking for a beautifully written piece of literature that is intriguing, enlightening, and mind-opening all at the same time, look no further than the Bible. You'll be surprised at what you'll find.</p>]]></description>
      <pubDate>Sun, 31 Dec 2023 00:01:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/the-bible-is-lit</guid>
    </item>
    <item>
      <title>A lesson from Jack and Jill</title>
      <link>https://www.mmhq.me/posts/a-lesson-from-jack-and-jill</link>
      <description><![CDATA[<p><picture><img alt="Mountains" sizes="(max-width: 480px) 360px, (max-width: 800px) 640px, (max-width: 1600px) 1080px, 1280px" src="/static/data/images/640w/mountains.webp" srcset="/static/data/images/360w/mountains.webp 360w, /static/data/images/640w/mountains.webp 640w, /static/data/images/1080w/mountains.webp 1080w, /static/data/images/1280w/mountains.webp 1280w" title="Mountains"></picture></p>
<p>Ancient poetry never ceases to amaze me. There are a lot of hidden gems in dense poetry that are easy to overlook when reading it, even in nursery rhymes. In this blog post, we will take a look at the classic poem <em>Jack and Jill</em> and see what makes it such an interesting poem.</p>
<h2 id="the-poem">The poem</h2>
<blockquote cite="https://www.poetryfoundation.org/poems/46974/jack-and-jill-56d2271cb3535">
<pre>
Jack and Jill went up the hill
To fetch a pail of water;
Jack fell down and broke his crown,
and Jill came tumbling after.

Up Jack got, and home did trot,
As fast as he could caper,
To old Dame Dob, who patched his nob
With vinegar and brown paper.
</pre>
<cite>Mother Goose, Poetry Foundation</cite>
</blockquote>

<p>The story of Jack and Jill is pretty straightforward: they both went up a hill to get some water and got hurt in the process. The second stanza is not recited often, but is very important to the overall form of the poem.</p>
<p>First, let's take a look at the rhyme scheme. This form of poetry can easily pass as a ballad because it has two stanzas that follow the rhyme pattern <strong>xaxa</strong>:</p>
<pre class="poem">
Jack and Jill went up the hill          <b>(x)</b>
To fetch a pail of water;               <b>(a)</b>
Jack fell down and broke his crown,     <b>(x)</b>
and Jill came tumbling after.           <b>(a)</b>

Up Jack got, and home did trot,         <b>(x)</b>
As fast as he could caper,              <b>(a)</b>
To old Dame Dob, who patched his nob    <b>(x)</b>
With vinegar and brown paper.           <b>(a)</b>
</pre>

<p>As illustrated above, the rhymes alternate: <em>hill/crown</em> don't rhyme but <em>water/after</em> do. <em>trot/nob</em> don't rhyme, but <em>caper/paper</em> do.</p>
<p>The rhyme established between <em>water/after</em> is called consonance, because the stressed vowels don't rhyme at all (the first syllable of each), but the unstressed syllables do (the second syllable of each word).</p>
<p>Why does this matter? Because the weak rhyme connection shows that a problem was encountered in the poem. Perfect rhyme, on the other hand, is used to depict that everything is going well in the story. The weaker the rhyme, the more <em>dissonance</em> or <em>tension</em> in the poem. Tension shows that something went ary.</p>
<p>The second verse, where <em>caper</em> and <em>paper</em> are used to achieve perfect rhyme, shows that the health of Jack has returned to normal, or at least there is something <em>positive</em> happening compared to the previous stanza. This is equivalent to how songs can go from a bright mood, to a temporary dark mood (like the bridge of a song), back to the mood that was established in the beginning.</p>
<h2 id="the-bottom-line">The bottom line</h2>
<p>I hope you could see the importance of form in poetry from this blog post. Form was appreciated much more back then, and was used by most poets from William Shakespeare to Emily Dickinson. Form enhances the communication in the poem and also helps to invoke emotion.</p>]]></description>
      <pubDate>Sat, 30 Dec 2023 20:00:00 -0800</pubDate>
      <guid>https://www.mmhq.me/posts/a-lesson-from-jack-and-jill</guid>
    </item>
  </channel>
</rss>
