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
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
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
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.
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
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.
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
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
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.
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.)
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
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
for more on that), this is another significant leap forward for
SwiftUI and I’m really keen to dive in.
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.
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
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.
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, 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.
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.
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.
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.
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).
Despite being a fundamental concept in relational databases, First
Normal Form (or 1NF) is often explained confusingly or downright
incorrect. This post explains what 1NF actually means and is useful
for, and debunk a number of the misunderstandings.
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
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.
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.
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.
I happened to discourage using an ORM in our company internal Slack
and suddenly found myself needing to explain some problems common in
ORMs. I got a little bit carried away, and the explanation turned
into this blog post.
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.
The console is the built-in debugger of the browser. Many developers
use console.log() all the time to print messages and debug
problems in their code. But this tool has a lot more to offer than
you may have ever realized!
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
but you can create them in other languages too. Here’s how to do it
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
tweetfile program is called several times a day via cron on MacOS.
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
I’ve gone through a few generations - I’ll use this post to
catalogue where I started and what I’m doing now.
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.
Today, I'm writing about what types can be used for other than
checking code properties. It will involve a good chunk of dynamic
typing, and yes it's in Rust. There are some wild ideas in it, so
fasten your seatbelt and get ready for a ride!
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.
Heaps are a
fundamental data structure that implement the priority queue
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
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.
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
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
King and Maxwell Book 1 by David Baldacci. It's the first time I read
a book by this author.
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.
I’ve been having a lot of fun using Rust for writing small tools. My
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
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
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.
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
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
20th of May.
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 🙃.
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 😊.
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.
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.
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
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.
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.