<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python on cassiobotaro</title><link>https://cassiobotaro.dev/en/tags/python/</link><description>Recent content in Python on cassiobotaro</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sat, 25 Jul 2026 13:06:19 -0300</lastBuildDate><atom:link href="https://cassiobotaro.dev/en/tags/python/index.xml" rel="self" type="application/rss+xml"/><item><title>The recipes hidden in the itertools documentation</title><link>https://cassiobotaro.dev/en/posts/itertools-recipes/</link><pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/itertools-recipes/</guid><description>&lt;p&gt;At the end of the &lt;code&gt;itertools&lt;/code&gt; page there is a section called &lt;a href="https://docs.python.org/3/library/itertools.html#itertools-recipes" class="external-link" target="_blank" rel="noopener"&gt;Itertools Recipes&lt;/a&gt;: a collection of useful functions built by combining the module&amp;rsquo;s building blocks. Flattening a list of lists, finding the first element that passes a test, walking a sequence in windows: a lot of what you would write by hand is already solved there. The recipes do not come ready to use in &lt;code&gt;itertools&lt;/code&gt;, the idea is to copy them into your code. We have already used one of them here, &lt;code&gt;consume&lt;/code&gt;, in the article about &lt;a href="https://cassiobotaro.dev/en/posts/consuming-iterables/" &gt;consuming iterables without allocating memory&lt;/a&gt;. I picked three others that are worth knowing.&lt;/p&gt;</description></item><item><title>Invoking modules with python -m</title><link>https://cassiobotaro.dev/en/posts/python-m-module/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/python-m-module/</guid><description>&lt;p&gt;Python has the &lt;code&gt;-m&lt;/code&gt; flag, which locates a module and runs it as a script. And the standard library is full of modules that turn into command line utilities ready to use, with nothing to install.&lt;/p&gt;
&lt;p&gt;Serve the current folder over HTTP:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python -m http.server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Format (and validate) a JSON:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#39;{&amp;#34;name&amp;#34;: &amp;#34;cassio&amp;#34;, &amp;#34;language&amp;#34;: &amp;#34;python&amp;#34;}&amp;#39;&lt;/span&gt; | python -m json.tool
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;See the calendar for the year in your terminal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python -m calendar &lt;span style="color:#ae81ff"&gt;2026&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You have probably already used the flag without noticing, in commands like &lt;code&gt;python -m venv .venv&lt;/code&gt; or &lt;code&gt;python -m pip install&lt;/code&gt;. It is the same mechanism: &lt;code&gt;-m&lt;/code&gt; locates the module on the import path and executes it as the main program, with &lt;code&gt;__name__&lt;/code&gt; set to &lt;code&gt;&amp;quot;__main__&amp;quot;&lt;/code&gt; (when the target is a package, what runs is its &lt;code&gt;__main__.py&lt;/code&gt;).&lt;/p&gt;</description></item><item><title>Fully comparable objects with a single method</title><link>https://cassiobotaro.dev/en/posts/comparable-objects/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/comparable-objects/</guid><description>&lt;h2 id="the-problem"&gt;
 The problem
 &lt;a class="heading-link" href="#the-problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;For an object to respond to &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;, Python expects you to implement &lt;code&gt;__lt__&lt;/code&gt;, &lt;code&gt;__le__&lt;/code&gt;, &lt;code&gt;__gt__&lt;/code&gt;, &lt;code&gt;__ge__&lt;/code&gt;, &lt;code&gt;__eq__&lt;/code&gt; and &lt;code&gt;__ne__&lt;/code&gt;. That is six nearly identical methods, tedious to write and easy to leave inconsistent (one says &lt;code&gt;a &amp;lt; b&lt;/code&gt; and another disagrees).&lt;/p&gt;
&lt;h2 id="the-tip"&gt;
 The tip
 &lt;a class="heading-link" href="#the-tip"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Two pieces cover everything:&lt;/p&gt;</description></item><item><title>Running a .zip as a Python application</title><link>https://cassiobotaro.dev/en/posts/running-a-zip-with-python/</link><pubDate>Wed, 24 Jun 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/running-a-zip-with-python/</guid><description>&lt;h2 id="the-problem"&gt;
 The problem
 &lt;a class="heading-link" href="#the-problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You have a Python application spread across several files and you want to ship everything as a single file. What if you could package it into a &lt;code&gt;.zip&lt;/code&gt; and run it with &lt;code&gt;python app.zip&lt;/code&gt;?&lt;/p&gt;
&lt;h2 id="the-tip"&gt;
 The tip
 &lt;a class="heading-link" href="#the-tip"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You can, and it is simpler than it looks. Python knows how to execute a &lt;code&gt;.zip&lt;/code&gt; directly, as long as there is a &lt;code&gt;__main__.py&lt;/code&gt; inside it. Let&amp;rsquo;s start from scratch.&lt;/p&gt;</description></item><item><title>Consuming iterables without allocating memory</title><link>https://cassiobotaro.dev/en/posts/consuming-iterables/</link><pubDate>Wed, 17 Jun 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/consuming-iterables/</guid><description>&lt;h2 id="the-problem"&gt;
 The problem
 &lt;a class="heading-link" href="#the-problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When you just want to &amp;ldquo;run&amp;rdquo; a &lt;code&gt;map&lt;/code&gt;/generator pipeline for its side effects (writing each item to a stream, for example), the reflex is a &lt;code&gt;for&lt;/code&gt; or a &lt;code&gt;list(...)&lt;/code&gt;. The &lt;code&gt;list&lt;/code&gt; allocates an entire list that gets thrown away right after, wasting memory for nothing. The &lt;code&gt;for&lt;/code&gt; solves the memory issue, but the loop runs in pure Python.&lt;/p&gt;
&lt;h2 id="the-tip"&gt;
 The tip
 &lt;a class="heading-link" href="#the-tip"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;collections.deque&lt;/code&gt; accepts a &lt;code&gt;maxlen&lt;/code&gt; parameter. With &lt;code&gt;maxlen=0&lt;/code&gt;, it pulls each element and discards it immediately, never growing: that is the &lt;code&gt;itertools&lt;/code&gt; &lt;a href="https://docs.python.org/3/library/itertools.html#itertools-recipes" class="external-link" target="_blank" rel="noopener"&gt;&lt;code&gt;consume&lt;/code&gt;&lt;/a&gt; recipe. Instead of materializing a list only to throw it away, you drain the pipeline in constant memory.&lt;/p&gt;</description></item><item><title>The write protocol</title><link>https://cassiobotaro.dev/en/posts/write-protocol/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/write-protocol/</guid><description>&lt;h2 id="the-problem"&gt;
 The problem
 &lt;a class="heading-link" href="#the-problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;When a function only needs to write to a stream, typing the argument as &lt;a href="https://docs.python.org/3/library/typing.html#typing-io" class="external-link" target="_blank" rel="noopener"&gt;&lt;code&gt;IO[str]&lt;/code&gt;&lt;/a&gt; is overkill, since you are demanding &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;seek&lt;/code&gt;, &lt;code&gt;close&lt;/code&gt; and the rest of the interface, even though you will never use them.&lt;/p&gt;
&lt;h2 id="the-tip"&gt;
 The tip
 &lt;a class="heading-link" href="#the-tip"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Starting with &lt;strong&gt;Python 3.14&lt;/strong&gt;, the &lt;code&gt;io&lt;/code&gt; module exposes the &lt;code&gt;Writer[T]&lt;/code&gt; and &lt;code&gt;Reader[T]&lt;/code&gt; protocols. They describe only the minimum contract (&lt;code&gt;write()&lt;/code&gt; or &lt;code&gt;read()&lt;/code&gt;), so any object that implements just that method already satisfies the type.&lt;/p&gt;</description></item><item><title>POOP: Python infected by Smalltalk</title><link>https://cassiobotaro.dev/en/posts/poop-python-infected-by-smalltalk/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/poop-python-infected-by-smalltalk/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/poop.png" alt="POOP" title="The POOP project logo"&gt;&lt;/p&gt;
&lt;h2 id="a-provocation-aimed-at-object-orientation"&gt;
 A provocation aimed at object orientation
 &lt;a class="heading-link" href="#a-provocation-aimed-at-object-orientation"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;There is a quote from Alan Kay that has been following me for years:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OOP is, essentially, about message passing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first time I heard about it, I pretended to understand and went on writing &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;for&lt;/code&gt; like always. But the idea would not leave my head. The final push came from Sandi Metz&amp;rsquo;s talk &lt;a href="https://www.youtube.com/watch?v=OMPfEXIlTVE" class="external-link" target="_blank" rel="noopener"&gt;&lt;em&gt;Nothing is Something&lt;/em&gt;&lt;/a&gt;, where she shows how to replace &lt;code&gt;nil&lt;/code&gt;, conditionals and operators with objects that respond to messages, including a &lt;code&gt;Null Object&lt;/code&gt; that knows how to behave like any other. I left it with a huge urge to make a concrete provocation to Python: what if I removed everything that &lt;em&gt;looks&lt;/em&gt; procedural, even when it isn&amp;rsquo;t? I know that &lt;code&gt;print(x)&lt;/code&gt; ends up calling &lt;code&gt;__str__&lt;/code&gt; and that &lt;code&gt;len(x)&lt;/code&gt; delegates to &lt;code&gt;__len__&lt;/code&gt;; Python&amp;rsquo;s data model is remarkably coherent in that regard. But the &lt;em&gt;look&lt;/em&gt; of those calls is that of a free function, not of a message to an object. No &lt;code&gt;if&lt;/code&gt;, no &lt;code&gt;for&lt;/code&gt;, no &lt;code&gt;print(x)&lt;/code&gt;, no &lt;code&gt;len(x)&lt;/code&gt;. Everything has to &lt;em&gt;look like&lt;/em&gt; a message sent to an object.&lt;/p&gt;</description></item><item><title>My First Program</title><link>https://cassiobotaro.dev/en/posts/my-first-program/</link><pubDate>Sat, 14 Mar 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/my-first-program/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/555.png" alt="555 IC with a calculator and Pascal code" title="The NE555 IC surrounded by Pascal code — my first real program"&gt;&lt;/p&gt;
&lt;h2 id="a-story-from-an-automation-technician"&gt;
 A Story from an Automation Technician
 &lt;a class="heading-link" href="#a-story-from-an-automation-technician"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In 2010 I graduated as an Industrial Automation technician. If you are not sure what that means, think of factories, conveyor belts, robots, PLCs, sensors and a pile of acronyms most people will never need to know. It was an amazing course, mixing electronics, mechanics and, this is where the story begins, programming.&lt;/p&gt;</description></item><item><title>The Money Object</title><link>https://cassiobotaro.dev/en/posts/the-money-object/</link><pubDate>Sun, 01 Mar 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/the-money-object/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/dinheiro.png" alt="Money"&gt;&lt;/p&gt;
&lt;h2 id="the-story"&gt;
 The Story
 &lt;a class="heading-link" href="#the-story"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A while ago I took part in the hiring process of a fairly well known purple bank. I did not get in, but I got valuable feedback about the code I wrote. Putting that feedback together with things I learned afterwards, I decided to revisit the challenge and improve the implementation.&lt;/p&gt;
&lt;p&gt;One of the most significant improvements was creating a &lt;code&gt;Money&lt;/code&gt; object, based on the pattern of the same name described by Martin Fowler in &lt;em&gt;Patterns of Enterprise Application Architecture&lt;/em&gt; (PEAA).&lt;/p&gt;</description></item><item><title>Roman Numerals with Python</title><link>https://cassiobotaro.dev/en/posts/roman-numerals-with-python/</link><pubDate>Sat, 14 Feb 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/roman-numerals-with-python/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/numeros-romanos.png" alt="Roman Numerals" title="Two people in roman costumes with speech balloons saying &amp;#39;5&amp;#39; and &amp;#39;V&amp;#39;"&gt;&lt;/p&gt;
&lt;h2 id="roman-numerals"&gt;
 Roman Numerals
 &lt;a class="heading-link" href="#roman-numerals"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Imagine writing Python code like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; roman
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(roman&lt;span style="color:#f92672"&gt;.&lt;/span&gt;X) &lt;span style="color:#75715e"&gt;# 10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(roman&lt;span style="color:#f92672"&gt;.&lt;/span&gt;IV) &lt;span style="color:#75715e"&gt;# 4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(roman&lt;span style="color:#f92672"&gt;.&lt;/span&gt;XLII) &lt;span style="color:#75715e"&gt;# 42&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(roman&lt;span style="color:#f92672"&gt;.&lt;/span&gt;MCMXC) &lt;span style="color:#75715e"&gt;# 1990&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Simply elegant, isn&amp;rsquo;t it? No functions, no explicit conversions, just&amp;hellip; roman numerals being roman numerals. It is as if the language naturally understood this thousand-year-old system.&lt;/p&gt;
&lt;h2 id="internal-dsls-and-the-magic-of-__getattr__"&gt;
 Internal DSLs and the Magic of &lt;code&gt;__getattr__&lt;/code&gt;
 &lt;a class="heading-link" href="#internal-dsls-and-the-magic-of-__getattr__"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;A DSL (Domain-Specific Language) is basically a language created for a specific purpose. There are &lt;strong&gt;external&lt;/strong&gt; ones (with their own syntax) and &lt;strong&gt;internal&lt;/strong&gt; ones (which piggyback on the syntax of the language you already use). What we are going to create here is an &lt;strong&gt;internal DSL&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>When Python Meets RPG: Rolling Dice with Style</title><link>https://cassiobotaro.dev/en/posts/dice-rolling-dsl/</link><pubDate>Sun, 01 Feb 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/dice-rolling-dsl/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/rpg.png" alt="People playing RPG" title="People playing RPG"&gt;&lt;/p&gt;
&lt;h2 id="shall-we-roll-the-dice"&gt;
 Shall we roll the dice?
 &lt;a class="heading-link" href="#shall-we-roll-the-dice"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Imagine being able to write RPG dice rolls as naturally as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; D6 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; D10
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And running a roll simply with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; D10 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; D4)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;roll()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That is possible in Python through operator overloading! Let&amp;rsquo;s create a DSL (Domain Specific Language) to make dice rolling intuitive and expressive.&lt;/p&gt;
&lt;h2 id="a-bit-of-context"&gt;
 A Bit of Context
 &lt;a class="heading-link" href="#a-bit-of-context"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;In my teenage years I was an RPG game master and had a lot of fun playing Vampire: The Masquerade and Tagmar. Recently, while taking an online Smalltalk course, I came across a similar example of a dice rolling DSL. I found the idea brilliant and decided to implement it in Python! It was a lot of fun exploring how operator overloading can create such a natural and expressive interface.&lt;/p&gt;</description></item><item><title>The count and index pitfall in NamedTuple</title><link>https://cassiobotaro.dev/en/posts/namedtuple-count-index-mypy/</link><pubDate>Sat, 17 Jan 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/namedtuple-count-index-mypy/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/type-checking.png" alt="Type checking"&gt;&lt;/p&gt;
&lt;h2 id="the-problem"&gt;
 The Problem
 &lt;a class="heading-link" href="#the-problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;You are using &lt;code&gt;NamedTuple&lt;/code&gt; to create your data classes and decide to add a field called &lt;code&gt;count&lt;/code&gt; or &lt;code&gt;index&lt;/code&gt;. Everything works perfectly at runtime, but when you run mypy or another type checker, you get strange errors. What is going on?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;3
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;4
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;5
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;6
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;7
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; typing &lt;span style="color:#f92672"&gt;import&lt;/span&gt; NamedTuple
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Item&lt;/span&gt;(NamedTuple):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: str
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count: int &lt;span style="color:#75715e"&gt;# Danger!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;item &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Item(name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;apple&amp;#34;&lt;/span&gt;, count&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(item&lt;span style="color:#f92672"&gt;.&lt;/span&gt;count) &lt;span style="color:#75715e"&gt;# Works at runtime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Running mypy:&lt;/p&gt;</description></item><item><title>Tracking progress with IntFlag</title><link>https://cassiobotaro.dev/en/posts/tracking-progress-with-intflag/</link><pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate><guid>https://cassiobotaro.dev/en/posts/tracking-progress-with-intflag/</guid><description>&lt;p&gt;&lt;img src="https://cassiobotaro.dev/images/tracking.png" alt="Tracking"&gt;&lt;/p&gt;
&lt;h2 id="the-problem"&gt;
 The Problem
 &lt;a class="heading-link" href="#the-problem"&gt;
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;
 &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;
 &lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Imagine you are integrating a new product into your system. This product must have complete details and specifications before being published. But that information is added in separate steps, and not necessarily in order. How do you check that every step has been completed?&lt;/p&gt;
&lt;p&gt;A naive solution would be to use a boolean variable for each step:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ProductTrack&lt;/span&gt;(models&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Model):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; product &lt;span style="color:#f92672"&gt;=&lt;/span&gt; models&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ForeignKey(Product, on_delete&lt;span style="color:#f92672"&gt;=&lt;/span&gt;models&lt;span style="color:#f92672"&gt;.&lt;/span&gt;CASCADE)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; has_specification &lt;span style="color:#f92672"&gt;=&lt;/span&gt; models&lt;span style="color:#f92672"&gt;.&lt;/span&gt;BooleanField(default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; has_detail &lt;span style="color:#f92672"&gt;=&lt;/span&gt; models&lt;span style="color:#f92672"&gt;.&lt;/span&gt;BooleanField(default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;is_complete&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;has_specification &lt;span style="color:#f92672"&gt;and&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;has_detail
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But what if you need to add more steps? Or remove one? Every change means touching the model, running database migrations and adjusting the logic.&lt;/p&gt;</description></item></channel></rss>