Normalization is not a process

Database normalization is often explained as a step-by step process to improve a database design. This is a very unfortunate misunderstanding which causes a lot of confusion for students. Instead, the normal forms should be thought of as a checklist which can be used to analyze a database design for potential problems.

Source: Normalization is not a process.

Subclassing in Python Redux

The conflict between subclassing and composition is as old as object-oriented programming. The latest crop of languages like Go or Rust prove that you don’t need subclassing to successfully write code. But what’s a pragmatic approach to subclassing in Python, specifically?

Source: Subclassing in Python Redux, an article by Hynek Schlawack.

Upgrade Your SSH Key to Ed25519

If you’re a DevOps engineer or a web developer, there’s a good chance that you’re already familiar and using the SSH key authentication on a daily basis. Whether it’s for logging into the remote server or when pushing your commit to the remote repository. It provides us with better security than the traditional password-based authentication.

But, when is the last time you created or upgraded your SSH key? And did you use the latest recommended public-key algorithm? If it was more than five years ago and you generated your SSH key with the default options, you probably ended up using RSA algorithm with key-size less than 2048 bits long.

Source: Upgrade Your SSH Key to Ed25519, an article by Risan Bagja Pradana.

See also my SSH Public Key Authentication How To.

Perl / Unix One-liner Cage Match, Part 1

A shell (like Bash) provides built-in commands and scripting features to easily solve and automate various tasks. External commands like grep, sed, Awk, sort, find, or parallel can be combined to work with each other. Sometimes you can use Perl either as a single replacement or a complement to them for specific use cases.

Perl is the most robust portable option for text processing needs. Perl has a feature rich regular expression engine, built-in functions, an extensive ecosystem, and is quite portable. However, Perl may have slower performance compared to specialized tools and can be more verbose.

Source: Perl / Unix One-liner Cage Match, Part 1, an article by Sundeep Agarwal.

Measuring memory usage in Python: it’s tricky!

If you want your program to use less memory, you will need to measure memory usage. You’ll want to measure the current usage, and then you’ll need to ensure it’s using less memory once you make some improvements.

It turns out, however, that measuring memory usage isn’t as straightforward as you’d think. Even with a highly simplified model of how memory works, different measurements are useful in different situations.

In this article you’ll learn:

  • A simplified but informative model of how memory works.
  • Two measures of memory–resident memory and allocated memory–and how to measure them in Python.
  • The tradeoffs between the two.

Source: Measuring memory usage in Python: it’s tricky!, an article by Itamar Turner-Trauring.

What Every Programmer Should Know About SSDs

Solid-State Drives (SSDs) based on flash have largely replaced magnetic disks as the standard storage medium. From the perspective of a programmer, SSDs and disks look very similar: both are persistent, enable page-based access through file systems and system calls, and have large capacities.

However, there are also important differences, which become important if one wants to achieve optimal SSD performance. As we will see, SSDs are more complicated and their performance behavior can appear quite mysterious if one simply thinks of them as fast disks. The goal of this post is to provide an understanding of why SSDs behave the way they do, which can help creating software that is capable of exploiting them. (Note that I discuss NAND flash, not Intel Optane memory, which has different characteristics.)

Source: What Every Programmer Should Know About SSDs, an article by Viktor Leis.

What is memory safety and why does it matter?

Memory safety is a property of some programming languages that prevents programmers from introducing certain types of bugs related to how memory is used. Since memory safety bugs are often security issues, memory safe languages are more secure than languages that are not memory safe.

Memory safe languages include Rust, Go, C#, Java, Swift, Python, and JavaScript. Languages that are not memory safe include C, C++, and assembly.

Source: What is memory safety and why does it matter?

What’s new in SwiftUI for iOS 15

Expectations were always going to be high for SwiftUI this year, but the team didn’t disappoint – they’ve shipped a massive collection of improvements and features, including a new AsyncImage view for loading remote images, swipe actions for list rows, pull to refresh, plus shorter, simpler APIs for common uses. Alongside huge improvements to Swift itself (see What's new in Swift 5.5 for more on that), this is another significant leap forward for SwiftUI and I’m really keen to dive in.

Source: What’s new in SwiftUI for iOS 15, an article by Paul Hudson.

A visit to the Rijksmuseum in Amsterdam

For Father's Day Esme had planned a visit to the Rijksmuseum in Amsterdam. So a bus, a train, a metro, and a tram later we arrived.

Adam, Alice, and Esme in the garden of the Rijksmuseum
Adam, Alice, and Esme in the garden of the Rijksmuseum.
Stained glass windows showing Lucas van Leijden and Rembrandt
Stained glass windows showing Lucas van Leijden and Rembrandt.

After some walking around we arrived at the famous Night Watch. Because the Rijksmuseum is carrying out a detailed study of Rembrandt's masterpiece it was in a huge glass box and surrounded by equipment.

Operation Night Watch
Operation Night Watch.
Alice enjoying a doll's house
Alice enjoying a doll's house.
The library of the Rijksmuseum
The library of the Rijksmuseum.
At the first level of the museum
At the first level of the museum.
Esme, Adam, and Alice with Vincent van Gogh's self-portrait
Esme, Adam, and Alice with Vincent van Gogh's self-portrait.
At the ground level of the museum
At the ground level of the museum.
Rijksmuseum tuinhuis
Rijksmuseum tuinhuis.

After the museum we took a tram to the center and walked in the direction of the train station. On our way Alice and Adam each bought a book. Alice bought Five Nights at Freddy's - The Silver Eyes and Adam bought the sequel Five Nights at Freddy's - The Twisted Ones.

Tumblelog 5.1.2

In the early evening I pushed tumblelog version 5.1.2 to GitHub. This version mqkes it easier to style the calendar pages, the month overview pages, the tags and individual tag pages. I also added a new argument; --feed-size. The integer value that must follow this option determines the number of items in each feed. This used to be 14, the same as the number of days (--days), but I changed it to 25.

Version 5.1.2 of tumblelog is available on GitHub. As always feedback is very welcome.

Harry Potter and the Prisoner of Azkaban (2004)

Harry Potter, Ron and Hermione return to Hogwarts School of Witchcraft and Wizardry for their third year of study, where they delve into the mystery surrounding an escaped prisoner who poses a dangerous threat to the young wizard.

In the evening Esme, Alice, and I watched Harry Potter and the Prisoner of Azkaban. Adam had been to a birthday party and was sound asleep. I had seen the movie before. I liked the movie and give it an 8 out of 10.

Cleaning $HOME on macOS

Apple computers include a custom operating system - macOS, which has a few annoying features. Among the annoyances a special place has to be reserved for the inability to remove or rename the folders located in $HOME. On the web countless macOS users are looking for the ways to bypass this restriction. Multiple suggestions are provided as possible solutions. You can: replace the folders with files; hide the folders from ‘Finder’ and make them inaccessible; or simply learn to live with them, as the system will recreate those folders by itself anyway.

Source: Cleaning $HOME on macOS, an article by Karolis Koncevičius.

Rust is Exciting

Rust is an exciting language. I recently bought The Rust Programming Language Book. It’s quite dense with a lot of concepts I haven’t thought about since college. Working in high-level programming languages such as Java, Python, and TypeScript have allowed me to mostly forget about the woes of low-level programming. Rust has both re-introduced me to these problems, and then immediately solved them with the advanced static analysis that its compiler provides.

Source: Rust is Exciting, an article by Jerred Shepherd.

A Hungry Scorpion

In the afternoon I noticed that Adam's Heterometrus silenus was out and about. We keep this scorpion in a plastic container on my desk. As it was actively searching for food I decided to give it a mealworm.

A hungry Heterometrus silenus with two mealworms
A hungry Heterometrus silenus with two mealworms.

It grabbed the mealworm and even the tweezers I used; it was quite hungry. When it had transferred the mealworm to its "mouth" it kept looking for food so I gave it another mealworm. This is the first time the scorpion is this active, maybe because of the high temperatures in my office (±28°C).

Comparison of Python HTTP clients

There are a huge number of HTTP clients available for Python - a quick search for “Python HTTP Clients” on Github returns over 1700 results(!) How do you make sense of all of them and find one which is right for your particular use case?

Do you have a single machine at your disposal, or a collection of them? Do you want to keep things simple or is raw performance more of a concern? A web application needing to make the odd request to a micro-service api is going to have quite different requirements to a script constantly scraping data. Additionally, there's the concern whether the library you choose will still be around 6 months down the line.

In this article we're going to cover five of the best HTTP clients currently available for Python and detail why each of them might be one for you to consider.

Source: Comparison of Python HTTP clients, an article by Ian Wootten.

Liocheles australasiae Eating

In the evening I noticed that another scorpion had become quite active; Liocheles australasiae. So I dropped a mealworm close to it. At first it was not interested but later I checked upon the small scorpion and it was enjoying its meal.

Liocheles australasiae eating a mealworm
Liocheles australasiae eating a mealworm.

Creating a Self-Hosted Git Server

This article will walk you through the process of setting up a Git server which can be pushed to, cloned from, and browsed, using a static site generator called stagit as a front-end. You can see my stagit-made site at


  • Some sort of Linux server (it could be as simple as a Raspberry Pi, or a VPS).
  • At least a basic understanding of Git and the shell.
  • A way to serve HTML files.

Source: Creating a Self-Hosted Git Server, an article by Theo Henson.

Execute Docker Containers as QEMU MicroVMs

This blog post compares the advantages and disadvantages of docker containers with VMs and describes why and how we execute docker images inside a QEMU MicroVM. The described approach makes it possible to combine the security of VMs with the existing ecosystem of docker (e.g. images and tools). Afterwards we take a look at ways how we can map features like bind mounts to solutions supported by QEMU and demonstrate this by running the NGINX docker image in QEMU.

Source: Execute Docker Containers as QEMU MicroVMs, an article by Michael Müller.

Modulinos In Bash

A modulino is a file which behaves like a library when it is imported, and like a script when executed. I first read about them in Mastering Perl, but you can create them in other languages too. Here’s how to do it in Bash.

Source: Modulinos In Bash.


In the morning I pushed md2tweets to GitHub. This program is a companion to tumblelog. It reads the Markdown input file of tumblelog and outputs tweets separated by a % character; the input format of tweetfile, a program to post to Twitter at random.

I run md2tweets each time after I run tumblelog via a Makefile. The tweetfile program is called several times a day via cron on MacOS.

Writing fast async HTTP requests in Python

I do a lot of web scraping in my spare time, and have been chasing down different formats and code snippets to make a large amount of network requests locally, with controls for rate limiting and error handling.

I’ve gone through a few generations - I’ll use this post to catalogue where I started and what I’m doing now.

Source: Writing fast async HTTP requests in Python, an article by JonLuca De Caro.

On Comments in Code

I used to think that I didn’t need comments if I wrote self-documenting code. However, I have realized that I do write comments, and that I find them really useful. To see how many comments I write, and what kind they are, I wrote a script to analyze my git commits from the last six years. In total, seven percent of my committed lines contained a comment. This blog post has details on what constitutes good and bad comments, as well as more statistics from my script.

Source: On Comments in Code, an article by Henrik Warne.

Rust meets the web - a clash of programming paradigms

Most code running on the web is event-based, garbage-collected, and dynamically typed. In stark contrast, Rust is a compiled language with static type- and memory-safety without a garbage-collector. What are the implications for a project that compiles Rust to WebAssembly? I try to answer this question with a fictive story and hands-on code examples.

Source: Rust meets the web - a clash of programming paradigms, an article by Jakob Meier.

Median Heaps in Haskell

Heaps are a fundamental data structure that implement the priority queue abstract data type. Essentially, a priority queue is one where the element at the front of line is always the one of highest priority, which is defined by the programmer for a specific implementation. A standard heap implementation provides fast access to the front element of the queue, in O(1) time, as well as insertion/deletion in O(log(n)) time.

Usually, the highest priority value is defined as either the minimum or maximum value in the data, as implemented in min and max heaps respectively. In this post, however, we will look at a more specialized heap that instead prioritizes the median value. Why would this be useful? I'm not sure of any practical applications, but assumedly it could be if it were ever performance critical to repeatedly calculate the median. Let's jump in.

Source: Median Heaps in Haskell, an article by Micah Cantor.

Practical Reed-Solomon for Programmers

This article will not turn you into an expert on Reed-Solomon. It will however allow you to understand and use any R-S codes you have to work with. In addition, you’ll learn what R-S can and can not do, and how it relates to other error correcting systems. Finally, with this understanding, the more math heavy explanations might become more accessible.

Source: Practical Reed-Solomon for Programmers, an article by Bert Hubert.

Split Second

Michelle Maxwell has just wrecked her promising career at the Secret Service. Against her instincts, she let a presidential candidate out of her sight for the briefest moment and the man whose safety was her responsibility vanished into thin air.

​Sean King knows how the younger agent feels. Eight years earlier, the hard-charging Secret Service agent allowed his attention to be diverted for a split second. And the candidate he was protecting was gunned down before his eyes. Now Michelle and Sean are about to see their destinies converge.

Drawn into a maze of lies, secrets, and deadly coincidences, the two discredited agents uncover a shocking truth: that the separate acts of violence that shattered their lives were really a long time in the making—and are a long way from over.

In the evening I started in Split Second, King and Maxwell Book 1 by David Baldacci. It's the first time I read a book by this author.

SSH quoting

A while back there was a thread on one of our company mailing lists about SSH quoting, and I posted a long answer to it. Since then a few people have asked me questions that caused me to reach for it, so I thought it might be helpful if I were to anonymize the original question and post my answer here.

Source: SSH quoting, an article by Colin Watson.

Rust from a JavaScript perspective

I’ve been having a lot of fun using Rust for writing small tools. My day to day work involves a ton of JavaScript and Rust provides a familiar feeling, so trying out Rust was an easy decision to make. But at the same time, actually doing meaningful work in Rust requires a lot of rethinking on how to structure and reason about your code. The compiler – true to its call – is merciless; yet, for some reason, it emerges quite a pleasure in tinkering your code to make it so that it – finally! – compiles.

In this post, I am documenting – albeit in a bit funny way – some thoughts in my journey so far in Rust land, coming from the viewpoint of a hardcore JavaScript enthusiast.

Source: Rust from a JavaScript perspective.

Containers are tents

I’ve read a lot of articles recently that seem to suggest containers kinda suck. And, well, sure. They don’t necessarily make code faster, or more secure, or much easier to debug. They require complex orchestration systems, and you can’t even use them to test your code on a different OS. Gone are the days of evangelist posts about how containers are the answer to all of life’s problems; now the think pieces have titles like, “Why You Don’t Need Docker,” and “I Did This One Weird Trick and Still Hit Kubernetes’s Scaling Limits.”

But this brand of container fatigue is largely a product of how we’re using them. I’ve often seen containers referred to as “lightweight VMs,” yet it’s this focus on containers as a form of virtualization that leads to a lot of the angst. Yes, there are parallels and points of overlap, but containers are most useful when we think of them as a tool for solving a related, but different, set of problems. They are, in fact, exceptionally helpful—as long as you’re not trying to use them to mimic an entire operating system.

Source: VMs are houses, containers are tents, an article by Nina Schiff.

A Tale of Three Docker Images

In the morning and in the early afternoon, just before work, I wrote a very long blog post on my experiences with creating 3 Docker images; one for the Python version of tumblelog, one for tweetfile, and one for the Perl version of tumblelog. All use Alpine Linux resulting in very small images, around 50MB each. Read all about it in A Tale of Three Docker Images.

BBC Micro:Bit V2 GO Bundle

In the afternoon the BBC Micro:Bit V2 GO Bundle I had ordered for Adam arrived. He has already been working with the older version of the Micro:Bit at school and was looking forward for it to arrive. I had ordered the little computer with SOS Solutions the 20th of May.

Adam shaking the BBC Micro:Bit V2
Adam shaking the BBC Micro:Bit V2.

The bundle consists of a BBC Micro:Bit V2, a USB cable, a battery holder and two AAA batteries all packed in a nice small brown carton box. At first the little computer didn't work at all after I had connected the battery holder. I even tried to connect it to my Mac mini via a USB cable, but no luck. Then I decided to check out the batteries and it turned out that I had placed one the wrong way 🙃.

BBC Micro:Bit V2 GO Bundle
BBC Micro:Bit V2 GO Bundle.

In the early evening Adam went to the Microsoft MakeCode for micro:bit web site and started his first project. Later he asked me if I could teach him how to program in Python 😊.

A Second Monitor

When we returned from dinner the Mini DisplayPort™ to DVI-D cable made by Cable Matters I ordered with Amazon the day before yesterday arrived.

Mini DisplayPort™ to DVI-D cable (Cable Matters)
Mini DisplayPort™ to DVI-D cable (Cable Matters).

At my sister-in-law's work they had some electronics up for recycling and I managed to get a Dell E1910 monitor for free. Originally it was connected to a Raspberry Pi for the children but they rarely used the Pi so the monitor was just gathering dust. Up until today as connecting the cable was literally plug-and-play; it worked without a flaw with no configuration needed. I could now drag a window to my right and see it on a second monitor.

I am very happy with this cable. It looks good quality and both ends come with a dust cap.

Zero downtime Postgres migration, done right

In this blog post we describe how to migrate a Postgres database to a new instance with zero downtime using Bucardo. We will describe how to avoid common pitfalls like data loss, deteriorated performance and data integrity failures. We have successfully used this process to migrate our Postgres databases from version 9.5 to 12.5 on RDS, but the process isn’t restricted to RDS only, and does not depend on anything AWS specific. This migration strategy should be possible with any self-hosted or managed Postgres.

Source: Zero downtime Postgres migration, done right, an article by Rigas Papathanasopoulos.

Tumblelog 5.0.2

In the morning while working on a slightly improved version of using inspiration from tumblelog I noticed a small bug in the latter; I had written:

my $exit_code //= 0;

Instead of

my $exit_code = shift // 0;

in sub show_usage_and_exit. I fixed this and pushed version 5.0.1 of tumblelog.

Later, when running the Dockerized Python version of tumblelog I got a warning explaining that the default Loader of yaml.load() is unsafe. In the evening I fixed this issue and pushed 5.0.2.

Encoding your HTTP for fun and profit

HTTP content encoding is an incredibly powerful tool that can save you huge amounts of bandwidth and make your web or mobile application faster, basically for free.

Unfortunately, it's poorly understood by most developers. There's a lot of power here, but few people are aware of the options or what "content encoding" really means, so it's mostly left to be handled automatically (for better or worse) by your web server.

In many cases that means no encoding at all. In some helpful cases (typically CDNs or static site PaaS hosts) a useful basic default will be provided, but those defaults are rarely the best choice for every situation.

With just a tiny sprinkle of knowledge, you can enable this and speed up your web application, your API, and all your HTTP requests & responses in no time at all.

Source: Encoding your HTTP for fun and profit, an article by Tim Perry.

All you need is 5 fonts

There weren’t as many web fonts to pick from when I started my freelance career in the early 2000s, still I was always overwhelmed by the number of fonts to choose from. With no formal education in design or typography, my choices were uninformed and limited.

It’s kinda funny to look back and realise that it was harder for me to choose fonts when there were fewer to choose from than now. I had moved away from being a freelance graphic designer in the years since then, but I still do branding, web design and graphic design work for my own projects. I acquired enough experience and learned so much about web typography in my career that I naturally came to the conclusion that many designers had reached before me—all you need is 5 fonts.

Source: All you need is 5 fonts, an article by Matej Latin.