<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: munyoki_kilyungi</title>
    <description>The latest articles on Forem by munyoki_kilyungi (@munyoki_kilyungi).</description>
    <link>https://forem.com/munyoki_kilyungi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F121603%2F975224db-2a95-44c8-acc9-ba214f900f25.jpg</url>
      <title>Forem: munyoki_kilyungi</title>
      <link>https://forem.com/munyoki_kilyungi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/munyoki_kilyungi"/>
    <language>en</language>
    <item>
      <title>Exponential Back-off with Jitter: Retries</title>
      <dc:creator>munyoki_kilyungi</dc:creator>
      <pubDate>Thu, 02 Apr 2026 14:51:03 +0000</pubDate>
      <link>https://forem.com/munyoki_kilyungi/exponential-back-off-with-jitter-retries-m0h</link>
      <guid>https://forem.com/munyoki_kilyungi/exponential-back-off-with-jitter-retries-m0h</guid>
      <description>&lt;p&gt;&lt;em&gt;(Originally posted &lt;a href="https://blog.bonfacemunyoki.com/exponential-backoff-with-jitter/" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;em&gt;Add random jitter to exponentially increasing retry delays to prevent synchronized client retries from overwhelming struggling services during outages.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Transient failures happen alot in production systems.  Transient failures can come from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network instability&lt;/li&gt;
&lt;li&gt;Service overload&lt;/li&gt;
&lt;li&gt;Resource contention&lt;/li&gt;
&lt;li&gt;Dependency flakiness&lt;/li&gt;
&lt;li&gt;Timeouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When an operation fails transiently, immediate retries can be tempting.  However, this (moreso repeatedly) can amplify load at the worst possible moment, turning a temporary disruption into a cascading failure.&lt;/p&gt;

&lt;p&gt;Consider a script that queries a Virtuoso triple store.  Under heavy load, the database may start returning HTTP 504 (Gateway Timeout) errors.&lt;/p&gt;

&lt;p&gt;A naive retry loop might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sparql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queryAndConvert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;504&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;  &lt;span class="c1"&gt;# retry immediately
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the server is already struggling, immediate retries only add more pressure, making recovery harder.  Even if you add a fixed delay, all retries from all clients (or even a single client) will occur at the same intervals, possibly colliding with the server’s own cool-down periods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exponential Back-off
&lt;/h2&gt;

&lt;p&gt;Exponential back-off increases the delay between retries exponentially.  For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First retry: 2 seconds&lt;/li&gt;
&lt;li&gt;Second retry: 4 seconds&lt;/li&gt;
&lt;li&gt;Third retry: 8 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives the server a growing window of relief.  But there’s still a problem: if the delays are deterministic, a single client’s retries may consistently land on a server state that’s still recovering.  Worse, multiple clients would retry in perfect synchrony.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exponential Back-off with Jitter
&lt;/h2&gt;

&lt;p&gt;Jitter adds a small random value to each calculated delay. This:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevents retries from aligning across clients (thundering herd)&lt;/li&gt;
&lt;li&gt;Avoids deterministic collisions with server‑side recovery windows&lt;/li&gt;
&lt;li&gt;Spreads the load more evenly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a single‑client scenario, jitter still helps by avoiding the situation where you always retry at times that happen to coincide with the server’s internal cooldown cycles.&lt;/p&gt;

&lt;p&gt;Here’s a function that implements exponential back-off with jitter for a SPARQL query.  It retries only on HTTP 504 errors and uses a configurable base delay and maximum retries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;SPARQLWrapper&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SPARQLWrapper&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.error&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HTTPError&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_with_retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;sparql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SPARQLWrapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;base_delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Execute SPARQL query with retry logic and exponential back-off.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sparql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queryAndConvert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;HTTPError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;504&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Exponential back-off with jitter
&lt;/span&gt;                &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base_delay&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;    Timeout (attempt &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;), retrying in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;s...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key Elements: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exponential factor: &lt;code&gt;base_delay * (2 ** attempt)&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Attempt 0 → 2 seconds&lt;/li&gt;
&lt;li&gt;Attempt 1 → 4 seconds&lt;/li&gt;
&lt;li&gt;Attempt 2 → 8 seconds&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Jitter: &lt;code&gt;+ random.uniform(0, 1)&lt;/code&gt; - adds a random value between 0 and 1 second. This small variance is enough to break any undesired alignment.&lt;/li&gt;

&lt;li&gt;Selective retry: Only HTTP 504 triggers a retry. Other errors are raised immediately, as they likely require different handling.&lt;/li&gt;

&lt;li&gt;Retry limit: The loop stops after &lt;code&gt;max_retries&lt;/code&gt;, ensuring the operation eventually fails instead of retrying forever.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Some pointers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use jitter even for a single client - it avoids deterministic collisions with server recovery periods.&lt;/li&gt;
&lt;li&gt;Set a maximum number of retries - infinite retries can mask underlying failures.&lt;/li&gt;
&lt;li&gt;Retry only idempotent operations - repeating non‑idempotent actions (e.g., writes) may cause data corruption.&lt;/li&gt;
&lt;li&gt;Log retries - in production, log each attempt with the delay used to aid debugging.&lt;/li&gt;
&lt;li&gt;Match base delay to your service - 1-2 seconds is a common starting point, but adjust based on typical recovery times.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sre</category>
      <category>devops</category>
      <category>timeouts</category>
      <category>retries</category>
    </item>
    <item>
      <title>Suffering = Pain * Resistance (and the Role of Self-Compassion)</title>
      <dc:creator>munyoki_kilyungi</dc:creator>
      <pubDate>Tue, 06 Jan 2026 12:16:03 +0000</pubDate>
      <link>https://forem.com/munyoki_kilyungi/suffering-pain-resistance-and-the-role-of-self-compassion-3fah</link>
      <guid>https://forem.com/munyoki_kilyungi/suffering-pain-resistance-and-the-role-of-self-compassion-3fah</guid>
      <description>&lt;p&gt;&lt;em&gt;Everyone talks code, few talk stress. Here’s my take: &lt;a href="https://blog.bonfacemunyoki.com/suffering/" rel="noopener noreferrer"&gt;original article&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; &lt;em&gt;Pain is unavoidable. Resistance multiplies it. Acceptance and Self-compassion reduces the damage.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Landed for Me
&lt;/h2&gt;

&lt;p&gt;Over the New Year, I went to the &lt;em&gt;2025/2026 Beneath the Baobab Festival&lt;/em&gt;&lt;sup id="fnref1"&gt;1&lt;/sup&gt; with a close friend.  Here, I mostly solo raved, finding myself quietly (at least most of day one) reflecting on some heavier chapters of my life: dark themes around death/grief; the abrupt end of a long-term commitment last February; the persistent cloud of depression in my community; and my own on-going struggle for mental/emotional stability. &lt;/p&gt;

&lt;p&gt;One moment stood out.  A homie shared some game that stayed with me long after the music died out&lt;sup id="fnref2"&gt;2&lt;/sup&gt;&lt;sup id="fnref3"&gt;3&lt;/sup&gt;&lt;sup id="fnref4"&gt;4&lt;/sup&gt;:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Suffering=Pain×Resistance
Suffering = Pain \times Resistance
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;S&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ff&lt;/span&gt;&lt;span class="mord mathnormal"&gt;er&lt;/span&gt;&lt;span class="mord mathnormal"&gt;in&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;P&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ain&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ce&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How Pain Becomes Suffering
&lt;/h2&gt;

&lt;p&gt;In meditation circles, you often hear: &lt;em&gt;"Pain is inevitable.  Suffering is optional."&lt;/em&gt;&lt;sup id="fnref3"&gt;3&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;strong&gt;pain&lt;/strong&gt; is what we cannot control (e.g., illnesses, grief because of the death of a loved one, a break-up). It is the "rawness" of the ache of that particular experience.  &lt;em&gt;Resistance&lt;/em&gt; is what we add on top of it - it acts as a multiplier.&lt;/p&gt;

&lt;p&gt;Resistance shows up in thoughts like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"This (sh/c)ouldn't be happening."&lt;/li&gt;
&lt;li&gt;"Why now?"&lt;/li&gt;
&lt;li&gt;"How could (s/h)e do this at my lowest point?"&lt;/li&gt;
&lt;li&gt;"I need to fix this."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When my ex left during a fragile period, the pain was unavoidable.  What turned it into deep suffering was my &lt;strong&gt;resistance&lt;/strong&gt;: replaying the story, arguing with reality, insisting that things should have gone differently.&lt;/p&gt;

&lt;p&gt;Pushing against reality consumes mental/emotional energy and multiplies our pain.   We suffer more.&lt;/p&gt;

&lt;h2&gt;
  
  
  When We Turn Against Ourselves
&lt;/h2&gt;

&lt;p&gt;In times of suffering, we can sometimes notice our own resistance.  That's when self-criticism shows its ugly self.&lt;/p&gt;

&lt;p&gt;We judge ourselves harshly for struggling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I'm better than this.  I shouldn't feel this way."&lt;/li&gt;
&lt;li&gt;"I suck at being 'okay'."&lt;/li&gt;
&lt;li&gt;"I'll just compartmentalize this and deal with this pain later."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern is sometimes called "resisting resistance"&lt;sup id="fnref4"&gt;4&lt;/sup&gt;.  A clearer name is &lt;strong&gt;self-criticism&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The equation now looks like this:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Suffering=Pain×Resistance×SelfCriticism
Suffering = Pain \times Resistance \times SelfCriticism
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;S&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ff&lt;/span&gt;&lt;span class="mord mathnormal"&gt;er&lt;/span&gt;&lt;span class="mord mathnormal"&gt;in&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;P&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ain&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ce&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;S&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="mord mathnormal"&gt;r&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;c&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;We are not only in pain, we are also attacking ourselves for being human.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Helps: Acceptance and Self-Compassion
&lt;/h2&gt;

&lt;p&gt;The antidote to resistance is &lt;strong&gt;acceptance&lt;/strong&gt;&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Acceptance doesn’t mean liking the situation or resigning to it.  It simply means acknowledging reality without forcing it to be different.  Not everything is under our control&lt;sup id="fnref2"&gt;2&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;To counter self-criticism, we add &lt;em&gt;self-compassion&lt;/em&gt;.  If resistance and self-criticism are multipliers, self-compassion is the divisor&lt;sup id="fnref4"&gt;4&lt;/sup&gt;:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Suffering=(Pain×Resistance)SelfCompassion
Suffering = \frac{(Pain \times Resistance)}{SelfCompassion}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;S&lt;/span&gt;&lt;span class="mord mathnormal"&gt;u&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ff&lt;/span&gt;&lt;span class="mord mathnormal"&gt;er&lt;/span&gt;&lt;span class="mord mathnormal"&gt;in&lt;/span&gt;&lt;span class="mord mathnormal"&gt;g&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;S&lt;/span&gt;&lt;span class="mord mathnormal"&gt;e&lt;/span&gt;&lt;span class="mord mathnormal"&gt;l&lt;/span&gt;&lt;span class="mord mathnormal"&gt;f&lt;/span&gt;&lt;span class="mord mathnormal"&gt;C&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mord mathnormal"&gt;p&lt;/span&gt;&lt;span class="mord mathnormal"&gt;a&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ss&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;o&lt;/span&gt;&lt;span class="mord mathnormal"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;P&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ain&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="mord mathnormal"&gt;es&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ce&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Self-compassion is offering yourself the same kindness you would offer a close friend:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This hurts. My resistance is making it harder. I’m allowed to care for myself here."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pain remains, but suffering is reduced&lt;/p&gt;

&lt;h2&gt;
  
  
  A Simple Practice
&lt;/h2&gt;

&lt;p&gt;When life feels heavy, I'm learning how to follow these steps&lt;sup id="fnref2"&gt;2&lt;/sup&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Notice a painful emotion/thought.&lt;/li&gt;
&lt;li&gt; Observe thoughts of resistance (e.g., "Why me?") and let them pass.&lt;/li&gt;
&lt;li&gt; Re-center by accepting circumstances, even if unpleasant.&lt;/li&gt;
&lt;li&gt; Focus on physical sensations, acknowledging their temporary status.&lt;/li&gt;
&lt;li&gt; Release judgment.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Finding Peace Under the Baobabs
&lt;/h2&gt;

&lt;p&gt;Standing under the baobabs, I realized I don’t need to eliminate pain to find peace.  Meditation and mindfulness don’t remove the ache of heartbreak or depression; they remove the unnecessary suffering we pile on top.&lt;/p&gt;

&lt;p&gt;Think of pain as a heavy backpack.  Resistance is trying to run uphill while complaining about the weight.  Self-compassion is stopping, breathing, and tightening the straps.  The load is the same, but the journey becomes manageable.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;&lt;a href="https://beneaththebaobabs.com/beneath-the-baobabs-festival/" rel="noopener noreferrer"&gt;Beneath the Baobab Festival&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;Buggy, P. &lt;em&gt;Suffering = pain * resistance&lt;/em&gt;. Mindful Ambition. &lt;a href="https://mindfulambition.net/suffering-pain-resistance/" rel="noopener noreferrer"&gt;https://mindfulambition.net/suffering-pain-resistance/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Selassie, S. (2023, October 28). &lt;em&gt;Pain x resistance = suffering&lt;/em&gt;. Happier Meditation. &lt;a href="https://www.happier.com/blog/pain-x-resistance-suffering/" rel="noopener noreferrer"&gt;https://www.happier.com/blog/pain-x-resistance-suffering/&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;Saltzman, A. (2025, August 5). &lt;em&gt;The new math: Suffering = (pain x resistance) / self-compassion&lt;/em&gt;. Psychology Today. &lt;a href="https://www.psychologytoday.com/us/blog/find-your-true-flow/202508/the-new-math-suffering-pain-x-resistance-self-compassion" rel="noopener noreferrer"&gt;https://www.psychologytoday.com/us/blog/find-your-true-flow/202508/the-new-math-suffering-pain-x-resistance-self-compassion&lt;/a&gt; ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>discuss</category>
      <category>mentalhealth</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>FizzBuzz using streams in Python</title>
      <dc:creator>munyoki_kilyungi</dc:creator>
      <pubDate>Thu, 13 Feb 2020 21:41:47 +0000</pubDate>
      <link>https://forem.com/bonfacekilz/fizzbuzz-using-streams-in-python-29k4</link>
      <guid>https://forem.com/bonfacekilz/fizzbuzz-using-streams-in-python-29k4</guid>
      <description>&lt;p&gt;So this evening I was fooling around with the concept of using monoids to play around with streams. The idea here is to break a relatively abstract concept into something that a noOb can follow along, and it hit me; why not demo all this stuff using the classic Fizz-buzz algorithm.&lt;/p&gt;

&lt;p&gt;Generally, for a fizz-buzz problem, you print out "Fizz" if a number is divisible by 3; and alternatively, you print "Buzz" if it's divisible by 5. Needless to say, you print "FizzBuzz" if it's divisible by both 3 and 5. Now a simple implementation in python would be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def fizz_buzz(n):
    for i in range(1, n+1):
        if (i % 3 == 0 and i % 5 == 0):
            print("{}: FizzBuzz".format(i))
            continue
        if (i % 3 == 0):
            print("{}: Fizz".format(i))
            continue
        if (i % 5 == 0):
            print("{}: Buzz".format(i))


fizz_buzz(100)        
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Well for one, I don't like that the above function has side-effects. How can we refactor this to use streams? First of all, let's clear up what a stream is. A stream is a sequence of objects which can be accessed in sequential order. Where do monoids come in? Well a monoid allows us to combine things. A monoid has a single associative "structure"(in our case this is the "append" operation that zip provides). In this case, when we have a stream, we can combine several monoids from a stream using zip. Let's look at it in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from itertools import cycle


def fizz_buzz(n):
    """Return an iter list with fizz-buzz"""
    fizz_buzz = zip(cycle(['', '', '', '', 'Fizz']),
                    cycle(['', '', 'Buzz']),
                    [i for i in range(1, n+1)])
    return filter(lambda x: (x[0] != '' or x[1] != ''),
                  fizz_buzz)

for i in fizz_buzz(100):
    print("{}: {}{}".format(i[2], i[0], i[1]))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;From the above snippet, we first generate a stream of "Fizzes" and "Buzzes", then we combine them with &lt;code&gt;zip&lt;/code&gt; after which we filter any element from the stream that has no "Fizz" or "Buzz". Python's loose typing makes it easy for us to combine and morph things. Notice that the &lt;code&gt;fizz_buzz&lt;/code&gt; function returns a generator which has it's own merits.&lt;/p&gt;

&lt;p&gt;If you want to functional programming tips, I post interesting reads on a google groups I started a while back here &lt;a href="https://groups.google.com/forum/#!forum/nairobi-functional-programming-community"&gt;https://groups.google.com/forum/#!forum/nairobi-functional-programming-community&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>fizzbuzz</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
