<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en" xml:base="http://localhost:8080/">
  <title>My Web Development Blog</title>
  <subtitle>Tell the word what you are writing about in your blog. It will show up on feed readers.</subtitle>
  <link href="http://localhost:8080/feed.xml" rel="self" />
  <link href="http://localhost:8080/" />
  <updated>2026-03-17T16:23:20Z</updated>
  <id>http://localhost:8080/</id>
  <author>
    <name>Zach Gates</name>
  </author>
	<entry>
      <title>Working with boot.dev to create great cloud content</title>
      <link href="http://localhost:8080/blog/working-with-bootdev-to-create-great-cloud-content/" />
      <updated>2025-10-31T00:00:00Z</updated>
      <id>http://localhost:8080/blog/working-with-bootdev-to-create-great-cloud-content/</id>
      <content type="html">
				&lt;p&gt;I’m thrilled to announce a major collaboration between Bevel Work and the incredible team at boot.dev!&lt;/p&gt;
&lt;p&gt;We’re joining forces to develop brand-new Cloud Platform content designed to help you master the skills needed for today’s dynamic cloud environments.&lt;/p&gt;
&lt;p&gt;I have to say, boot.dev is a genuine wealth of knowledge and hosts one of the warmest, most supportive learning communities I’ve ever seen. Their commitment to making complex topics accessible and engaging is unparalleled, and we are so excited to contribute to their mission.&lt;/p&gt;
&lt;p&gt;Ready to level up your cloud skills? Get a head start and secure your spot (or snag a discount on boot.dev’s other amazing courses!) with this special &lt;a href=&quot;https://www.boot.dev?promo=BEVELWORK&quot; rel=&quot;noopener&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Stay tuned for more updates on this project!&lt;/p&gt;

 			</content>
    </entry><entry>
      <title>Quick Utils: quick-nats-are-bad</title>
      <link href="http://localhost:8080/blog/quick-utils-quick-nats-are-bad/" />
      <updated>2025-10-08T00:00:00Z</updated>
      <id>http://localhost:8080/blog/quick-utils-quick-nats-are-bad/</id>
      <content type="html">
				&lt;p&gt;Sometimes a combination of humor and details can change things. In my case convincing a team to take on the management of their NAT infrastructure is a difficult to do. So I wrote a quick tool to help and to give quick numbers if dealing with that nagging “should we replace these NAT Gateways?” question.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/bevelwork/quick_nats_are_bad/blob/main/media/qnab_report.gif?raw=true&quot; alt=&quot;quick-nats-are-bad&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/p&gt;
&lt;p&gt;It scans your US regions, lists NAT Gateways, pulls pricing, reads CloudWatch data processing, and estimates monthly spend. The output highlights where your money goes—hourly NAT charges plus per‑GB data processing—and flags cross‑AZ routing that quietly adds $0.01/GB in both directions.&lt;/p&gt;
&lt;p&gt;Source code is available on &lt;a href=&quot;https://github.com/bevelwork/quick_nats_are_bad&quot; rel=&quot;noopener&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To install run:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew tap bevelwork/tap
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; quick-nats-are-bad

quick-nats-are-bad &lt;span class=&quot;token comment&quot;&gt;# Run it&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For other quick utils, check out &lt;a href=&quot;https://bevel.work/quick-tools&quot; rel=&quot;noopener&quot;&gt;bevel.work&lt;/a&gt;.&lt;/p&gt;

 			</content>
    </entry><entry>
      <title>You are what you eat; you believe what you do.</title>
      <link href="http://localhost:8080/blog/you-are-what-you-eat;-you-believe-what-you-do/" />
      <updated>2025-09-29T00:00:00Z</updated>
      <id>http://localhost:8080/blog/you-are-what-you-eat;-you-believe-what-you-do/</id>
      <content type="html">
				&lt;p&gt;You and everyone you know are a set of rules you make for yourself.&lt;/p&gt;
&lt;p&gt;People make choices every day. What to eat, what to wear, what to do this weekend. In college, we’d guess that people would generally choose to do the thing that they thought was most &lt;strong&gt;useful&lt;/strong&gt; or have the most &lt;strong&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Utility&quot; rel=&quot;noopener&quot;&gt;utility&lt;/a&gt;&lt;/strong&gt; for themselves.&lt;/p&gt;
&lt;p&gt;And while seeming too basic an idea to be true, you can bring in a surprising amount of nuance to the system.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I chose to sleep in this morning because I value the sleep more than I value the incremental benefit of exercise.&lt;/li&gt;
&lt;li&gt;I didn’t proofread this text message because I would rather spend my time on something else.&lt;/li&gt;
&lt;li&gt;I became a developer instead of a teacher because I enjoy this particular balance of risks and rewards.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These are conscious and unconscious values we place on our interactions with the world. But what’s really interesting about human behavior is people will impose different rules on themselves, and change those rules over time. Their justifications and reasons for their choices are just as varied and at times arbitrary. My father as a child heard the phrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Blue and green should never be seen.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And so he applied that rule to his life. A rule that I’ve never heard anyone else apply to themselves. What rules do you apply to yourself? Take a moment and gauge yourself of a few different metrics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How pragmatic are you:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More Pragmatic&lt;/strong&gt;: I’m going to spend my time on the most valuable things.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Less Pragmatic&lt;/strong&gt;: I prioritize following the process even if its less efficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How idealistic are you:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More Idealistic&lt;/strong&gt;: Some things have value in and of themselves.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Less Idealistic&lt;/strong&gt;: I only pursue goals that have clea, achievable, and measurable results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Are you an individual or community?
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More Community Focused&lt;/strong&gt;: I forego my needs so &lt;strong&gt;X&lt;/strong&gt; can succeed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Less Community Focused&lt;/strong&gt;: I can only accomplish what needs to be done if I take care of myself.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;How do you handle risk?
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;More Risky&lt;/strong&gt;: I am confident in my abilities and choices despite the risks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Less Risky&lt;/strong&gt;: I use my talents to build security and safety into my life.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You have unquantifiable values for each of these, and so do the people around you. So know your &lt;strong&gt;personal values&lt;/strong&gt;, and when you take the same measuring stick and apply it to your professional life.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Manager X&lt;/strong&gt; is &lt;strong&gt;pragmatic&lt;/strong&gt; and highly &lt;strong&gt;risk averse&lt;/strong&gt;, so making concerted effort to show up on time, and explicitly show how decisions compensate for risks is going to have more value demonstrating how your choices align with company values.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Manager Y&lt;/strong&gt; is very &lt;strong&gt;culture&lt;/strong&gt; and &lt;strong&gt;community&lt;/strong&gt; oriented. So showing preferences that demonstrate personal sacrifice for the benefit of the group are going to carry weight.&lt;/p&gt;
&lt;p&gt;This is not chess though, we do not have &lt;a href=&quot;https://en.wikipedia.org/wiki/Perfect_information&quot; rel=&quot;noopener&quot;&gt;perfect information&lt;/a&gt;, but I think a huge amount of &lt;a href=&quot;https://www.merriam-webster.com/dictionary/unforced%20error&quot; rel=&quot;noopener&quot;&gt;unforced errors&lt;/a&gt; would be avoided if we thought about:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;So do you know what the &lt;strong&gt;real rules&lt;/strong&gt; are for your goals, your team, and your life?&lt;/li&gt;
&lt;li&gt;Do your actions &lt;strong&gt;reflect the rules you make&lt;/strong&gt; for yourself?&lt;/li&gt;
&lt;li&gt;Do you know what the &lt;strong&gt;people around you value&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Do the people around know what &lt;strong&gt;you value&lt;/strong&gt; and do your actions reflect that?&lt;/li&gt;
&lt;/ul&gt;

 			</content>
    </entry><entry>
      <title>Should You Learn IaC?</title>
      <link href="http://localhost:8080/blog/should-you-learn-iac/" />
      <updated>2025-09-25T00:00:00Z</updated>
      <id>http://localhost:8080/blog/should-you-learn-iac/</id>
      <content type="html">
				&lt;p&gt;So I’m trying a new format. Here’s a video walking through why I got into Infrastructure as code, and the problems in my life it helps me solve.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://youtu.be/o9isjR7bjes&quot; rel=&quot;noopener&quot;&gt;youtube link here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let me know what you think.&lt;/p&gt;

 			</content>
    </entry><entry>
      <title>Devops Interview Prep: Leetcode as Code</title>
      <link href="http://localhost:8080/blog/devops-interview-prep-leetcode-as-code/" />
      <updated>2025-09-18T00:00:00Z</updated>
      <id>http://localhost:8080/blog/devops-interview-prep-leetcode-as-code/</id>
      <content type="html">
				&lt;p&gt;In a competitive job market it’s important to be able to demonstrate the technologies you’re proficient with, and the &lt;a href=&quot;https://en.wikipedia.org/wiki/Tongue-in-cheek&quot; rel=&quot;noopener&quot;&gt;undisputed best test for this&lt;/a&gt; takes the form of a whiteboard exercise or an algorithm test to see if you’re able to implement common data structures and the sort.&lt;/p&gt;
&lt;p&gt;But, could I succeed without functions, true if/else statements, and loops?&lt;/p&gt;
&lt;p&gt;Fizzbuzz is often a first interview question for candidates and we’ll cut our teeth on it:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;
locals {
  iterations = 100 # First we specify the number of iterations
  fizzbuzz = [for i in range(local.iterations) : {
    index = i
    value = i % 15 == 0 ? &quot;FizzBuzz&quot; : 
      i % 3 == 0 ? &quot;Fizz&quot; : 
      i % 5 == 0 ? &quot;Buzz&quot; : 
      i # Otherwise, just return the index
  }]
  fizzbuzz_result = [
    for i in local.fizzbuzz : length(i.value) &amp;gt; 0 ? i.value : i.index
  ]
}
# [&quot;1&quot;, &quot;2&quot;, &quot;Fizz&quot;, &quot;4&quot;, &quot;Buzz&quot;, &quot;Fizz&quot;, &amp;lt;snip&amp;gt;..., &quot;14&quot;, &quot;FizzBuzz&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Okay, not so bad, what about sorting? Surely this will scale well. Can it sort?&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;locals {
  mixed_list = [
    1, 3, 5, 1,1,1
  ]

  bubble_sorted_list = [
    for i, val in range(length(local.mixed_list)) :
    i &amp;lt; length(local.mixed_list) - 1 ?              # Make sure we don&#39;t go out of bounds
    local.mixed_list[i] &amp;lt; local.mixed_list[i + 1] ? # Determine if we need to swap
    local.mixed_list[i] : local.mixed_list[i + 1] : # Handle the swap
    local.mixed_list[i]                             # We were on the last element, just return the value
  ]
}
# Not quite. We&#39;re not sorted, and we misplaced a 5 somewhere.
# [1,3,1,1,1] &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s update that to use a module:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;locals {
  state = [5, 4, 3, 1, 2]
}

# Five passes, each pass performs odd+even swaps
module &quot;pass_0&quot; {
  source = &quot;./mods/pass&quot;
  in     = local.state # [5,4,3,1,2]
}

# &amp;lt;snip&amp;gt; pass_1 through pass_4 &amp;lt;/snip&amp;gt;

module &quot;pass_4&quot; {
  source = &quot;./mods/pass&quot;
  in     = module.pass_3.out # [1,2,3,4,5]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The timeless product of &lt;a href=&quot;https://cs50.harvard.edu/extension/2024/fall/shorts/bubble_sort/&quot; rel=&quot;noopener&quot;&gt;cs50 students&lt;/a&gt; everywhere, but we want to set our sights higher.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;P.S. unfortunately importing ./mods/pass from within mods/pass led to a circular dependency, bringing terraform to its knees. I also considered putting &lt;code&gt;terraform apply --auto-approve&lt;/code&gt; into a while loop and letting it mutate a file input, but I think I’m getting distracted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;# Here&#39;s the module:
variable &quot;in&quot; {
  type        = list(number)
  description = &quot;Input list for a single odd+even bubble pass&quot;
}

module &quot;swap_odd&quot; {
  count  = floor(length(var.in) / 2)
  source = &quot;../swap&quot;
  in     = [var.in[count.index * 2], var.in[count.index * 2 + 1]]
}

locals {
  pass_odd = concat(
    flatten([for i in range(0, length(module.swap_odd)) : module.swap_odd[i].out]),
    length(var.in) % 2 == 1 ? [var.in[length(var.in) - 1]] : []
  )
}

module &quot;swap_even&quot; {
  count  = floor((length(local.pass_odd) - 1) / 2)
  source = &quot;../swap&quot;
  in     = [local.pass_odd[count.index * 2 + 1], local.pass_odd[count.index * 2 + 2]]
}

locals {
  pass_even = concat(
    [local.pass_odd[0]],
    flatten([for i in range(0, length(module.swap_even)) : module.swap_even[i].out]),
    length(local.pass_odd) % 2 == 0 ? [local.pass_odd[length(local.pass_odd) - 1]] : []
  )
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A bit messier, but it works. I think I could get rid of the &lt;code&gt;swap&lt;/code&gt; module but I need a new challenge. Let’s try something with a cleaner approach: &lt;strong&gt;is this a palindrome?&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;locals {
  is_palindromes = [
    &quot;&quot;, &quot;a&quot;, &quot;aa&quot;, &quot;aaa&quot;, &quot;kayak&quot;, &quot;radar&quot;, &quot;racecar&quot;, &quot;madam&quot;, &quot;dog&quot;, &quot;god&quot;,
    &quot;cat&quot;, &quot;act&quot;, &quot;rat&quot;, &quot;mat&quot;, &quot;hat&quot;, &quot;bat&quot;, &quot;tab&quot;, &quot;cab&quot;, &quot;bac&quot;, &quot;aca&quot;, &quot;cac&quot;,
    &quot;aac&quot;, &quot;cca&quot;, &quot;aaa&quot;, &quot;ccc&quot;, &quot;aaaa&quot;
  ]
  palindromes = [
    for str in local.is_palindromes :
    length(str) &amp;lt;= 1 ? true : # empty string and single characters are palindromes
    alltrue([
      for i in range(floor(length(str) / 2)) :
      substr(str, i, 1) == substr(str, length(str) - 1 - i, 1)
    ])
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The next challenge is Two Sum, which we can conquer with a map:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;locals {
  # Test data for Two Sum
  two_sum_array = [2, 7, 11, 15, 3, 6, 1, 8, 4, 9]
  two_sum_target = 23
  
  two_sum_value_map = {
    for i, val in local.two_sum_array : tostring(val) =&amp;gt; i
  }
  
  # For each number, check if (target - number) exists in the map
  two_sum_raw = [
    for i, num in local.two_sum_array :
    contains(keys(local.two_sum_value_map), tostring(local.two_sum_target - num)) &amp;amp;&amp;amp; 
    local.two_sum_value_map[tostring(local.two_sum_target - num)] != i ?
    {
      indices = [i, local.two_sum_value_map[tostring(local.two_sum_target - num)]]
      values = [num, local.two_sum_target - num]
      sum = local.two_sum_target
    } : null
  ]
  
  # Filter out null results from optimized solution
  two_sum_results = [
    for result in local.two_sum_raw: result if result != null
  ]
}
# {
#     &quot;indices&quot; = [3,7]
#     &quot;sum&quot; = 23
#     &quot;values&quot; = [15,8]
# }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ah yes &lt;a href=&quot;https://x.com/mitchellh&quot; rel=&quot;noopener&quot;&gt;Mitchell&lt;/a&gt; would be proud.&lt;/p&gt;

 			</content>
    </entry><entry>
      <title>Quick Utils: quick_pipreqs</title>
      <link href="http://localhost:8080/blog/quick-utils-quick_pipreqs/" />
      <updated>2025-09-17T00:00:00Z</updated>
      <id>http://localhost:8080/blog/quick-utils-quick_pipreqs/</id>
      <content type="html">
				&lt;p&gt;Never again will I spend 10 minutes on Monday morning handling &lt;code&gt;dependabot&lt;/code&gt;/&lt;code&gt;renovate&lt;/code&gt; merge conflicts.&lt;/p&gt;
&lt;p&gt;The best way to build momentum is to consistently release small things. Not everything needs to be a masterpiece—sometimes the most valuable tools are the ones that solve one specific problem really well.&lt;/p&gt;
&lt;p&gt;This is my next small thing: &lt;a href=&quot;https://github.com/bevelwork/quick_pipreqs&quot; rel=&quot;noopener&quot;&gt;&lt;strong&gt;quick-pipreqs&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s a simple tool that iterates through large Python monorepos and utilizes &lt;code&gt;pipreqs&lt;/code&gt; to update all &lt;code&gt;requirements.txt&lt;/code&gt; files it can find.&lt;/p&gt;
&lt;p&gt;It does them all in one go and allows for quickly parallelizing them. Really helpful if you want to clear out a lot of Renovate or Dependabot merge requests at one time. Never again will&lt;/p&gt;
&lt;p&gt;Available via:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bevelwork/quick_pipreqs&quot; rel=&quot;noopener&quot;&gt;github.com/bevelwork/quick_pipreqs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;brew tap bevelwork/homebrew-tap 
brew install quick-pipreqs&lt;/code&gt;&lt;/pre&gt;

 			</content>
    </entry><entry>
      <title>What is super. Examples of Composition, Inheritance, and Interfaces</title>
      <link href="http://localhost:8080/blog/what-is-super-examples-of-composition-inheritance-and-interfaces/" />
      <updated>2025-09-13T00:00:00Z</updated>
      <id>http://localhost:8080/blog/what-is-super-examples-of-composition-inheritance-and-interfaces/</id>
      <content type="html">
				&lt;p&gt;&lt;img src=&quot;http://localhost:8080/assets/images/blog/keybr.jpeg&quot; alt=&quot;Image of a keyboard flying through the air&quot; eleventy:widths=&quot;650,960,1400&quot;&gt;&lt;/p&gt;
&lt;p&gt;So when I was first programming, the concept of &lt;code&gt;super()&lt;/code&gt; was a hard for me to grasp. I saw things like react components where things would break if you suddenly forgot to include it in certainly places.&lt;/p&gt;
&lt;p&gt;Simply put &lt;code&gt;super&lt;/code&gt; (or &lt;code&gt;base&lt;/code&gt;, or &lt;code&gt;parent&lt;/code&gt; depending on the language) explicitly import behavior from something else. So let’s start with a language that doesn’t have this like &lt;code&gt;go&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Cat &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c Cat&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Dog &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d Dog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So we’ve got a &lt;code&gt;Dog&lt;/code&gt; and a &lt;code&gt;Cat&lt;/code&gt; here, both with names. In Go, we can relate these through interfaces - things that share common behavior.&lt;/p&gt;
&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Here&#39;s an interface that we can use to relate to everything that has a name&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Nameable &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;namePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n Nameable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Both Cat and Dog implement Nameable, so we can use them interchangeably&lt;/span&gt;
cat &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; Cat&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Whiskers&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
dog &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Fido&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;namePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Whiskers&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;namePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Fido&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now let’s see how we can use composition to create more complex structures:&lt;/p&gt;
&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Animal &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Nameable
    age &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;animalNamePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Create animals using composition - embedding the Nameable interface&lt;/span&gt;
cat &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; Animal&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Nameable&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Cat&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Whiskers&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    age&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

dog &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; Animal&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    Nameable&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Fido&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    age&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Both work with our functions&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;namePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Whiskers&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;animalNamePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Whiskers&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;namePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Fido&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;animalNamePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dog&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Fido&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So our interface says here are a bunch of things that have &lt;code&gt;this&lt;/code&gt; in common. It doesn’t require any extension of the &lt;code&gt;Cat&lt;/code&gt; or &lt;code&gt;Dog&lt;/code&gt; structs themselves and just asserts that anything passed as &lt;code&gt;Nameable&lt;/code&gt; will meet the requirements of the interface.&lt;/p&gt;
&lt;p&gt;The composition method creates a struct that explicitly includes the &lt;code&gt;Nameable&lt;/code&gt; interface. So while we have to add in the behavior ourselves, it gives us a means to glue a bunch of things together and reason about the whole.&lt;/p&gt;
&lt;p&gt;Now let’s look at &lt;code&gt;super()&lt;/code&gt;, and to do so we’ll switch to some &lt;code&gt;python&lt;/code&gt; code, and afterward’s we’ll look at what’s going on.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s our base &lt;code&gt;Animal&lt;/code&gt; class with a name and a method to get the name. Now we can create specific animals that inherit from this base class.&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Dog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Create our animals&lt;/span&gt;
cat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Cat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Whiskers&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
dog &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Fido&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_name&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Whiskers&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dog&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_name&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Fido&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So when we initialize a &lt;code&gt;Cat&lt;/code&gt; or &lt;code&gt;Dog&lt;/code&gt;, we call &lt;code&gt;super().__init__(name)&lt;/code&gt;. Super lets us reference the &lt;strong&gt;parent class’ implementation&lt;/strong&gt;, in this case the initialization and the methods and properties that were implemented for &lt;code&gt;Animal&lt;/code&gt;. This is really attractive, as if we had 100’s of animals, we wouldn’t have to implement &lt;code&gt;get_name&lt;/code&gt; for each of them. This can also be chained together. So &lt;code&gt;Animal -&amp;gt; Kingdom -&amp;gt; Phylum -&amp;gt; Class -&amp;gt; Order...&lt;/code&gt; Each class is aware of its parent in a linked-list fashion.&lt;/p&gt;
&lt;p&gt;However, here’s the issue I’ve often run into. What if we have the proverbial &lt;a href=&quot;https://en.wikipedia.org/wiki/A_Horse_with_No_Name&quot; rel=&quot;noopener&quot;&gt;horse with no name&lt;/a&gt;, that is some situation where we want to include some aspects of Animal, but not all of it. How much work would it take to extend our systems to accommodate this new behavior?&lt;/p&gt;
&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// First we update our definition of Animal as not all animals are namable&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Animal &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Nameable &amp;lt;-- This was removed&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;GetAge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Our new horse&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; HorseWithNoName &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    age &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;h HorseWithNoName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;GetAge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Our implementation of Cat and Dog do not have the change&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ... Snip ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;namePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;Nameable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; animal &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; n &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;animal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;agePrinter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; animal &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; a &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;animal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GetAge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This didn’t require much change to our code, and the functions can tie directly to the aspect that pertains to their use case. All animals can still be handled by the &lt;code&gt;animalAgePrinter&lt;/code&gt; function, while only nameable animals work with &lt;code&gt;namePrinter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now let’s see how this same scenario plays out with Python’s inheritance model:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# We can keep our Animal, but we&#39;d have to add a nil name or override get_name()&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HorseWithNoName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; age&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Problem: We still need to call super().__init__() but with what name?&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# We have to provide something, even if it&#39;s empty&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; age

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;This horse has no name&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# This works, but it&#39;s awkward&lt;/span&gt;
horse &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; HorseWithNoName&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;horse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_name&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# &quot;This horse has no name&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or we have to bisect Animal into base Animals and Nameable Animals:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Separate concerns - not all animals have names&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; age&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; age

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_age&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;NameableAnimal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; age&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;age&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; name

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;get_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Cat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;NameableAnimal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; age&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; age&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# ... snipped dog example ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HorseWithNoName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; age&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;__init__&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;age&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Now we can handle both cases cleanly&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print_animal_ages&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;animals&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Animal&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; animal &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; animals&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Age: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;animal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_age&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;print_nameables&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nameables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; List&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;NameableAnimal&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; n &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; nameables&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-interpolation&quot;&gt;&lt;span class=&quot;token string&quot;&gt;f&quot;Name: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_name&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

cat &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Cat&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Whiskers&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
dog &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Dog&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Fido&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
horse &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; HorseWithNoName&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

print_animal_ages&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dog&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; horse&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
print_nameables&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dog&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;the-trade-offs&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/what-is-super-examples-of-composition-inheritance-and-interfaces/#the-trade-offs&quot; class=&quot;heading-anchor&quot;&gt;The Trade-offs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The Go composition approach gives us flexibility at the cost of more verbosity. We have to explicitly implement the methods for each structure, but we can compose those structures together, or build interfaces that allow us to interact with aspects that are shared between them.&lt;/p&gt;
&lt;p&gt;Python’s inheritance with &lt;code&gt;super()&lt;/code&gt; provides a clean way to extend functionality, but it can become problematic when the inheritance hierarchy doesn’t perfectly match the real-world relationships between objects. The “horse with no name” scenario highlights how inheritance can force us into awkward compromises or require significant refactoring.&lt;/p&gt;
&lt;p&gt;As I’ve written more things I’ve come to write more composition-based code. For when my future self comes back to that code the idea of &lt;a href=&quot;https://en.wikipedia.org/wiki/Locality_of_reference&quot; rel=&quot;noopener&quot;&gt;locality of reference&lt;/a&gt;, e.g. keeping the related code together as much as possible, makes a huge effect on how long it takes me to get up-to-speed on a codebase.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/what-is-super-examples-of-composition-inheritance-and-interfaces/#references&quot; class=&quot;heading-anchor&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=hxGOiiR9ZKg&quot; rel=&quot;noopener&quot;&gt;Go watch this, its fantastic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

 			</content>
    </entry><entry>
      <title>Quick Utils</title>
      <link href="http://localhost:8080/blog/quick-utils/" />
      <updated>2025-09-11T00:00:00Z</updated>
      <id>http://localhost:8080/blog/quick-utils/</id>
      <content type="html">
				&lt;p&gt;Something I’ve always enjoyed is when a tool or widget is surprisingly useful. Almost always, utilities I write are useful for their intended purpose and solve the immediate problem, but then they end up in the &lt;a href=&quot;https://en.wikipedia.org/wiki/Elephants%27_graveyard&quot; rel=&quot;noopener&quot;&gt;elephant graveyard&lt;/a&gt; that is 1-starred git repositories.&lt;/p&gt;
&lt;p&gt;I think the key is to publish them, accept feedback from your peers on what actually makes it into their technical toolbag, and lean into the ones that get a bit of traction. So we’ve released one of these tools: &lt;a href=&quot;https://github.com/bevelwork/quick_ssm&quot; rel=&quot;noopener&quot;&gt;&lt;strong&gt;quick-ssm&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/bevelwork/quick_ssm/raw/main/media/basic.gif&quot; alt=&quot;quick-ssm&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/p&gt;
&lt;p&gt;It’s a simple tool that lets you quickly create a new SSM session without having to log in to AWS, look up the instance name, or confirm that the instance is on.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/bevelwork/quick_ssm/raw/main/media/port-forward.gif&quot; alt=&quot;quick-ssm&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/p&gt;
&lt;p&gt;It lets you quickly expose a port to see if a web service is really running.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/bevelwork/quick_ssm/raw/main/media/check-mode.gif&quot; alt=&quot;quick-ssm&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;&lt;/p&gt;
&lt;p&gt;It lets you see the thing you obviously forgot and need to go fix. There’s something honest about a simple tool and making it available to the world.&lt;/p&gt;

 			</content>
    </entry><entry>
      <title>Just Enough Automation</title>
      <link href="http://localhost:8080/blog/just-enough-automation/" />
      <updated>2025-09-09T00:00:00Z</updated>
      <id>http://localhost:8080/blog/just-enough-automation/</id>
      <content type="html">
				&lt;p&gt;Every developer faces the same question dozens of times: “Should I automate this task?” The answer is rarely obvious. Automate too little, and you’re drowning in repetitive work. Automate too much, and you’re building elaborate systems for problems that don’t exist.&lt;/p&gt;
&lt;p&gt;In projects I’ve worked on, I’ve inevitably had to weigh this decision, and the answer invariably is “Maybe?”. But “maybe” isn’t helpful when you need to make a choice.&lt;/p&gt;
&lt;p&gt;What should factor into this decision? Where is the threshold between valuable automation and wasted time? What intangibles are we trying to optimize for?&lt;/p&gt;
&lt;h2 id=&quot;terms&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/just-enough-automation/#terms&quot; class=&quot;heading-anchor&quot;&gt;Terms&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So let’s try to quantify this.&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value Delivered = Value of the Task
                - The Effort of Implementing the Task&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Simple enough, if I see a penny on the roof of the parking garage next door, is it worth going down the stairs, navigating the parking garage, and picking up the coin? Maybe not, but there exists a pile of coins where the hassle is definitely worth it.&lt;/p&gt;
&lt;p&gt;So for tasks that we are never going to do again, we best optimize for the effort&lt;br&gt;
to get the task done and nothing else. Let’s expand our equation to accommodate an&lt;br&gt;
ongoing effort:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value Delivered = Value of the Task * Number of Iterations for the Task
                - The Effort of Implementing the Task&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So if the task is repeatedly done, or perhaps the effort for automating the task is exceptionally low, it may be the best return on our time.&lt;/p&gt;
&lt;h2 id=&quot;the-hidden-costs&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/just-enough-automation/#the-hidden-costs&quot; class=&quot;heading-anchor&quot;&gt;The Hidden Costs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Everyone who has decided to handwash that one dish instead of putting it in the dishwasher has made this calculation in their mind. However, let’s spend a moment talking about the non-obvious consequences of automation.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Maintenance&lt;/em&gt;. Whether you’re doing the task yourself or automating, there’s going to be some upkeep:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If you’re out of the office, how do you make sure the task still gets done and&lt;br&gt;
someone knows how to do it?&lt;/li&gt;
&lt;li&gt;If you write that script (workflow, program, process), who will go and update&lt;br&gt;
it as the task changes, and make sure it’s still doing what it’s supposed to?&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value Delivered = Value of the Task * Number of Iterations for the Task
                - The Effort of Implementing the Task
                - Maintenance Costs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Documentation&lt;/em&gt;. If you’re doing a task that has any impact beyond yourself, you’re going to need to document it. This is the proverbial Sticky Note on the fridge to buy milk. There’s also a cost of occasionally running out of milk when we can’t be bothered to leave a note. Let’s add that in:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value Delivered = Value of the Task * Number of Iterations for the Task
                - The Effort of Implementing the Task
                - Maintenance Costs
                - Documentation Costs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Mistakes&lt;/em&gt;. However you perform a task, the &lt;a href=&quot;https://en.wikipedia.org/wiki/To_err_is_human&quot; rel=&quot;noopener&quot;&gt;human element&lt;/a&gt; will exert itself. That could be a typo in your script or leaving a $1,000 tip instead of a $10.00 tip. What will happen to the value proposition when you discover your mistake?&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value Delivered = Value of the Task * Number of Iterations for the Task
                - The Effort of Implementing the Task
                - Maintenance Costs
                - Documentation Costs
                - Mistake Costs&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Long Term Effects&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Life is a sum of all your choices&lt;br&gt;
– Albert Camus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Choices you make on small items have a cumulative effect on the long term. Working out today won’t make you much more than sweaty, but working out for the next decade &lt;a href=&quot;https://news.ycombinator.com/item?id=44522683&quot; rel=&quot;noopener&quot;&gt;may change your life&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The same principle applies to automation decisions. Each choice to automate or perform a task manually builds your skills and shapes your approach to future decisions. Performing the task manually might improve your understanding of the process, while automating it might develop your technical skills. The key is recognizing that these long-term effects compound over time, potentially outweighing the immediate cost-benefit calculation.&lt;/p&gt;
&lt;p&gt;Consider the developer who always automates their deployment process versus one who manually deploys each time. After a year, the first developer has built robust automation skills and reliable deployment systems, while the second has gained deep intuition about deployment nuances. Both outcomes have value, but they’re different kinds of value that affect future decisions.&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Long Term Value = Value of the Task * Number of Iterations for the Task
                - The Effort of Implementing the Task
                - Maintenance Costs
                - Documentation Costs
                - Mistake Costs
                ± Long Term Effects&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/just-enough-automation/#conclusion&quot; class=&quot;heading-anchor&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Automation is a tool, not a goal. We should never automate something for the sake of automation. Our professional lives are full of rituals:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A ritual is a repeated, structured sequence of actions or behaviors that alters the internal or external state of an individual, group, or environment, regardless of conscious understanding, emotional context, or symbolic meaning.[^1]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Essentially performing an act regardless of its effectiveness at being fit for any particular purpose (e.g. Standups filled with idle chatter, meetings that fail to state or accomplish a goal, creating dashboards that will never be used).&lt;/p&gt;
&lt;p&gt;I think automation can be a great &lt;em&gt;self-documenting&lt;/em&gt; tool, or a means to fight &lt;em&gt;human error&lt;/em&gt;, but it should be wielded with purpose.&lt;/p&gt;
&lt;h2 id=&quot;references&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/just-enough-automation/#references&quot; class=&quot;heading-anchor&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[^1] &lt;a href=&quot;https://en.wikipedia.org/wiki/Ritual&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Ritual&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

 			</content>
    </entry><entry>
      <title>The Case for Cowboy Coding</title>
      <link href="http://localhost:8080/blog/the-case-for-cowboy-coding/" />
      <updated>2025-09-03T00:00:00Z</updated>
      <id>http://localhost:8080/blog/the-case-for-cowboy-coding/</id>
      <content type="html">
				&lt;p&gt;It seems like a desirable thing to be able to look at work that you’ve done&lt;br&gt;
over the years and say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“That stood the test of time, I wouldn’t change a thing.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And so, enthusiastically, I set forth to craft my project. Infusing it with&lt;br&gt;
creativity and passion, only to have the wolrd assert itself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hey, I need this done this week.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So the one week version was what was written, and we know the heart of something&lt;br&gt;
great is there, but in an honest moment I look at that projects I’ve completed and say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m not sure I’d do that again.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or worse:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That was a waste of time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why is this? What can be done to correct this? Is something going wrong in my&lt;br&gt;
preparation, my craft, my follow-through? So with years of projects to look back&lt;br&gt;
on, I’m faced with two archetypes of myself of which I have conflicting&lt;br&gt;
feelings. &lt;strong&gt;What approach can I take to deliever value?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Samurai Developer&lt;/strong&gt;. The version of myself who prepares well, is&lt;br&gt;
considered in their approach and work. A well-executed plan is the highest prize,&lt;br&gt;
and large refactoring and abandonment the highest price.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Measure twice, cut once.”, or “A sitch in time saves nine.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Or the &lt;strong&gt;Cowboy Coder&lt;/strong&gt;, who implements quickly, with minimal thought for the&lt;br&gt;
long-term vision, and is comfortable with ambiguity. Who loves getting the job&lt;br&gt;
done, and testing the validity of requirements with a working prototype.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Perfect is the enemy of progress.”, or “A bird in the hand is worth two in&lt;br&gt;
the bush.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These two mindsets I’ve used in many projects. Let’s review a few:&lt;/p&gt;
&lt;h2 id=&quot;the-generic-feature&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#the-generic-feature&quot; class=&quot;heading-anchor&quot;&gt;The Generic Feature&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This is a feature that will be used by many other downstream efforts. It has a&lt;br&gt;
clear vision, and detailed requirements.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Samurai&lt;/strong&gt; will approach this with gravitas. I probe the requirements&lt;br&gt;
for unforeseen roadblocks, and I’m willing to push the start date until the work&lt;br&gt;
is truly ready.&lt;/p&gt;
&lt;p&gt;I consider the data model and logical abstractions that will be needed. I&lt;br&gt;
diligently implement and test &lt;strong&gt;The Generic Feature&lt;/strong&gt; and do a good job.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Cowboy&lt;/strong&gt; delivers the feature ahead of schedule. It may be a bit more&lt;br&gt;
austere, but it will be delivered.&lt;/p&gt;
&lt;p&gt;Which I choose depends on this equation I subconsciouly go through for each&lt;br&gt;
task:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value I Deliver = Benefit of the Task 
                - Implementation Cost
                - (Refactor Consequence × Risk)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the &lt;strong&gt;Benefit of the Task&lt;/strong&gt; is reason why we’re doing the task. Some things&lt;br&gt;
are really worthwhile, while others are certainly worhtless.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Implementation Cost&lt;/strong&gt; is the cost of waiting for the feature to be&lt;br&gt;
delivered. My empoloyer is paying me to do the work, and other engineers and users&lt;br&gt;
are waiting for that work to be delivered. In almost all cases, fewer days is&lt;br&gt;
better.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;Refactor Consequence&lt;/strong&gt; is the cost of refactoring the code. What would it&lt;br&gt;
cost us if we have to refactor this code? Will we lose that client? Will we delay&lt;br&gt;
a release, or am I the only person on earth that will know about this feature?&lt;br&gt;
We’ll come back to this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Risk&lt;/strong&gt;, quantifies the chance that we will need to refactor this. Some code&lt;br&gt;
will never be touched again. Some code will be rewritten ten times as it&lt;br&gt;
becomes the hot path for your application.&lt;/p&gt;
&lt;p&gt;Okay, so we’ve got some levers, and we solve for while maximizing value. Let’s&lt;br&gt;
go to another example.&lt;/p&gt;
&lt;h2 id=&quot;the-pacemaker&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#the-pacemaker&quot; class=&quot;heading-anchor&quot;&gt;The Pacemaker&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This project is make it or break it. Any failure mode has disastrous consequences&lt;br&gt;
eclipsing the value of the whole project, let alone the feature. So if we plug&lt;br&gt;
this into our equation:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value I Deliver = Benefit of the Task 
                - Implementation Cost
                - (Company Ending Event × Risk)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the case were &lt;a href=&quot;https://en.wikipedia.org/wiki/Damocles&quot; rel=&quot;noopener&quot;&gt;failure is catastrophic&lt;/a&gt;, we must do everything we can to&lt;br&gt;
reduce the risk. Predicting this let’s us know if what it would take to implement&lt;br&gt;
is actually worth it.&lt;/p&gt;
&lt;p&gt;So the methodical Samurai will win out.&lt;/p&gt;
&lt;h2 id=&quot;the-idea&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#the-idea&quot; class=&quot;heading-anchor&quot;&gt;The Idea&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Your company has definitely had an idea or two. One or two of them are why this&lt;br&gt;
whole project is happening. These &lt;em&gt;might&lt;/em&gt; be untapped treasures, or these &lt;em&gt;might&lt;/em&gt;&lt;br&gt;
be a collossal ego project for someone signing the checks. How do should you&lt;br&gt;
approach this?&lt;/p&gt;
&lt;p&gt;Value I Deliver = Benefit of the Task # Nearly zero as this is a lottery ticket.&lt;br&gt;
- Implementation Cost&lt;br&gt;
- (Refactor Consequence × Risk)&lt;/p&gt;
&lt;p&gt;In this case the only variable we really control is the cost of implementation.&lt;br&gt;
Its value is arbitrary. So do we build a featured implementation that will&lt;br&gt;
succeed for any future, or do we build a prototype to validate the idea, knowing&lt;br&gt;
full well we’ll have to refactor or throw it out.&lt;/p&gt;
&lt;p&gt;The Cowboy wins here. They get to validate the idea the soonest for the&lt;br&gt;
least amount spent. Allowing a company to test the market with lots of ideas&lt;br&gt;
and not bet the farm on a single one.&lt;/p&gt;
&lt;p&gt;Okay, so “it depends” on the situtation. I think that’s something you knew&lt;br&gt;
already coming into this article, but my challenge to you is that you should&lt;br&gt;
almost always be a cowboy.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/There_are_unknown_unknowns&quot; rel=&quot;noopener&quot;&gt;Unknown unknowns&lt;/a&gt; There are a category of roadblocks that simply cannot be&lt;br&gt;
known until the project is in motion. This significantly increases the&lt;br&gt;
likelihood that &lt;strong&gt;all&lt;/strong&gt; code will be refactored anyways. That refactoring will&lt;br&gt;
benefit from both an existing prototype and knowledge of requiredments that&lt;br&gt;
could no be known otherwise.&lt;/li&gt;
&lt;li&gt;Most of what we write does not matter. Look at code you wrote 6 months ago,&lt;br&gt;
would you write it the same way? Your code is not going to &lt;a href=&quot;https://xkcd.com/2730/&quot; rel=&quot;noopener&quot;&gt;last forever&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Refactoring will happen naturally as bottlenecks are discovered, and as&lt;br&gt;
features are expanded upon. Writing the simple version first avoids a whole&lt;br&gt;
category of &lt;a href=&quot;https://en.wikipedia.org/wiki/Premature_optimization&quot; rel=&quot;noopener&quot;&gt;premature optimization&lt;/a&gt; problems.&lt;/li&gt;
&lt;li&gt;There is a huge benefit in repetition. You solving a certainly class of&lt;br&gt;
problem repeatedly will end up in a great solution that you can readily&lt;br&gt;
produce. Take this example:&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;[A] ceramics teacher announced on opening day that he was dividing the class into two groups. All those on the left side of the studio, he said, would be graded solely on the quantity of work they produced, all those on the right solely on its quality. His procedure was simple: on the final day of class he would bring in his bathroom scales and weigh the work of the “quantity” group: fifty pound of pots rated an “A”, forty pounds a “B”, and so on. Those being graded on “quality”, however, needed to produce only one pot — albeit a perfect one — to get an “A”. Well, came grading time and a curious fact emerged: the works of highest quality were all produced by the group being graded for quantity. It seems that while the “quantity” group was busily churning out piles of work – and learning from their mistakes — the “quality” group had sat theorizing about perfection, and in the end had little more to show for their efforts than grandiose theories and a pile of dead clay. &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Does quality matter?&lt;/p&gt;
&lt;p&gt;Yes, uniquivocally. We connot hire an army of interns to build a prototypes&lt;br&gt;
and expect to succeed in the market. Our same equation applies:&lt;/p&gt;
&lt;pre class=&quot;language-plaintext&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;Value I Deliver = 0 #  Benefit of the Task
                - Implementation Cost
                - (Refactoring Consequence × 99%) # Risk&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you’re code does not meet the requirements it is not delivering on the value&lt;br&gt;
of the feature. If you’re code &lt;strong&gt;always&lt;/strong&gt; has to be refactored then any value&lt;br&gt;
you’re delivering is going to be short lived.&lt;/p&gt;
&lt;p&gt;My favorite method is two fold:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create the simplest version of the feature that can be delivered.&lt;/li&gt;
&lt;li&gt;Reflect and if necessary refactor.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this way we never comit a huge amount of resources to an unproven idea. Better&lt;br&gt;
developers will deliver great simple features and get a chance to test it against&lt;br&gt;
the market. Junior developers will get feedback on their ipmlementation and how&lt;br&gt;
to improve their approach.&lt;/p&gt;
&lt;p&gt;So in summary.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Know the tradeoffs of your approach and weigh situation against them.&lt;/li&gt;
&lt;li&gt;Place a high value on iteration time. &lt;a href=&quot;https://grugbrain.dev/&quot; rel=&quot;noopener&quot;&gt;Simple components are usually better&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Most of our code is unimportant, and the important code will likely be refactored.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://martinfowler.com/bliki/Yagni.html&quot; rel=&quot;noopener&quot;&gt;Utilize protoypes and be a cowboy&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Learn to look at your code and say, “That was probably the right thing at the&lt;br&gt;
time.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;references&quot;&gt;&lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#references&quot; class=&quot;heading-anchor&quot;&gt;References&lt;/a&gt;&lt;/h2&gt;
&lt;hr class=&quot;footnotes-sep&quot;&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://austinkleon.com/2020/12/10/quantity-leads-to-quality-the-origin-of-a-parable/&quot; rel=&quot;noopener&quot;&gt;Article&lt;/a&gt; &lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://www.amazon.com/exec/obidos/ASIN/0961454733/wwwaustinkleo-20/ref=nosim/&quot; rel=&quot;noopener&quot;&gt;Book&lt;/a&gt; &lt;a href=&quot;http://localhost:8080/blog/the-case-for-cowboy-coding/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;

 			</content>
    </entry></feed>
