vladh's microblog

video.clumsy.computer is live!

As you may know, I create educational programming videos under the name clumsy computer where I show how to program everyday tools such as a regular expression engine from scratch without using any libraries.

So far, the videos have been hosted on YouTube. That’s fine, and virtually every single viewer has discovered the channel there. However, I (and others) have spoken about how it’s important for programmers to make sure their work is available without depending on ethically dubious companies such as Microsoft and Google. I don’t like knowing that the only reason my educational videos can be hosted for free is that the costs are subsidised by advertising revenue.

I’m therefore happy to announce video.clumsy.computer, which is a PeerTube instance hosted by me where all the educational videos I make will also be available from now on. Not only does this mean that all of my work will be hosted under my own terms, but PeerTube also supports ActivityPub, which means that all users of either another PeerTube or Mastodon instance can interact with everything hosted on the website. Confused by all the terms? It basically means this website is compatible with other people’s self-hosted social networks and video websites.

It feels a lot more cosy for clumsy computer to have its own home, and I also look forward to uploading any non-clumsy-computer videos I create in the future.

In line with this change, I’ve also moved the primary home of all of the code from GitHub to a sourcehut repository.

The eagle-eyed among you may notice that, while this is great, I haven’t actually been making many videos lately, since the last video was published more than a year ago. Perhaps you should be looking out for more news in the near future! :)

As I always say at the end of clumsy computer videos, see you soon and have fun programming!

Visit video.clumsy.computer →

Easy nocheckin with git

Sometimes, you want to add some code to test something out, but you definitely want to make sure you don’t git commit it. Of course, you should always check the output of git diff before you make a commit (you do, right?), but if you have a lot of changes things can slip through the cracks.

A solution is to write a comment containing a string such as “nocheckin”:

function do_stuff() {
    printf("hello!!! testing!!!\n"); // nocheckin

Then, you need to set git up such that it refuses to make a commit if it detects the “nocheckin” string anywhere in your changed files. Here’s how to do it.

Save this script somewhere — I put it in ~/.bin/validate-nocheckin:

#!/bin/sh -eu

# get the staged files
s_files=$(git diff --name-only --cached)

# if a staged file contains the keyword, fail the commit
for s_file in ${s_files};do
    if grep -q -E 'nocheckin' ${s_file};then
        echo "ERROR: ${s_file} contains 'nocheckin', failing commit"
        exit 1

exit 0

Then, whenever you want this feature, simply symlink that script as the pre-commit hook by running this from the root folder of your git repository:

ln -s ~/.bin/validate-nocheckin .git/hooks/pre-commit

If you then try to commit your code, it won’t work:

vladh ki test:master $ git commit -m 'will it work?'
ERROR: main.c contains 'nocheckin', failing commit

The Desire to Appear Stressed

It is undeniable that we live in a time of considerable economic inequality. As I write this, one of the headlines on the homepage of The Guardian reads: “UK cost of living crisis: More than one in eight UK households fear they have no way of making more cuts”. This necessarily means that some are able to live a very comfortable life just as others struggle to pay the bills and put food on the table.

You might be thinking I am about to embark on a criticism of the lucky few — far from it 1. Those who are able to live comfortably, are, for the most part, simply living the life everyone should be able to live. However, imagine you happen to be a very successful software developer, or perhaps an executive, who never has to worry about the bills, and most likely never will. It is difficult not to come into contact with the poverty of others — perhaps a family member is struggling to keep their head above water, or your neighbour is worried about being able to pay the rent, or perhaps you simply read about the magnitude of poverty in your country in the news.

If you live comfortably, it’s very common to feel some kind of guilt, or at the very least to wonder if this situation is justified. You might come up with some set of reasons justifying why you deserve your success, but these are always nebulous — there is always an element of luck, a bit of support from relatives, or some other such factor. There is, however, a pretty surefire way to ensure nobody will question your merit: to appear stressed, or indeed, even better, to organise your life such that you actually are stressed. Surely this will make it clear to everyone that success has not fallen into your lap.

The more you think about it, the more you realise it is almost perverse not to do so. Would it not be almost obscene to have an incredibly relaxed lifestyle, without a worry in the world, fully enjoying the fruits of your own success, always on vacation, working remotely from the beach, while relatives and friends struggle? Would this not be almost insulting to them?

At the same time, your desire to telegraph the correct signals to others is leading to you actually having a stressful life, not only because you are constantly worried that you actually do not deserve your success and are hence committing some awful injustice, but also because the desire to appear stressed and hard-working causes you to ultimately take all of the happiness and peace of mind that your success could have brought you and put it in the bin. Is it not sad to be one of the lucky few and never enjoy the fruits of your luck, never lead a relaxed and happy life, simply because of the desire to appear deserving?

This is quite a sad state of affairs, and I believe that this kind of mentality is the source of widespread unhappiness and mental health issues among the well-paid. It leads to a kind of bizarre situation where, if you’re not financially struggling, you’re quite likely to be mentally struggling. So what’s the solution?

The very idea that one is “deserving” of their success and that they built their entire life up with their own two hands is nonsensical. This is okay. There are many obvious ways to receive a little help along the way: perhaps your parents paid for your education, or you got some financial help from a friend. It also helps to live in a society where you’re unlikely to be discriminated against based on your race, gender, sexuality or other factors. But there are many other ways in which you are likely to receive support from those around you. I’m a software developer — I never chose to like software, it’s just what I’ve loved doing since I was a kid. I’m very fortunate that my field is very highly prized by the market, i.e. it pays well. However, this can always change with the times, and if my passion had been tailoring and I had worked just as hard, I would be out of luck. 2

Those with neoliberal tendencies might argue: of course my skills are prized by the market, software development is essential to society! This is, unfortunately, only true in the world of imagination, and there is no better example than that of “essential workers” during the early days of the COVID pandemic, when we endlessly praised doctors, nurses, supermarket workers and others, while paying them peanuts. Is their contribution to society less than mine? 3

It doesn’t stop here, though. Even if you were successful despite market conditions, you are still standing on the shoulders of others. You eat food brought to you from all corners of the world, you rely on transportation networks, on healthcare staff, on sanitation workers and countless others.

You might be familiar with the phrase “it takes a village to raise a child”. Well, it takes a village to raise a CEO as well.

If you take all of this into consideration, it becomes obvious how unrealistic it is to live in a fantasy world of individualism, of being solely responsible for our own success, when in reality, there is some kind of collective effort everywhere you look, which should be celebrated.

If the conclusion is that we all rely on the people and society surrounding us, that it’s nonsensical to say that only you are responsible for your own success, how are the successful supposed to frame themselves in relation to the less fortunate?

It should be clear by now that being stressed and unhappy in the name of others is absolutely foolish and only serves to make oneself miserable while not helping others in any way. It is damaging not only on the individual level, but also on the economic and societal level, to have a class of well-paid but depressed people. Stress is not a badge of honour — if anything, peaceful happiness should be.

The quest for merit, and for “deserving” one’s success should be abandoned. Even though systemic change is necessary to address systemic inequality, we would already do a great service to mental health worldwide if the fortunate dropped the pretence of unnecessary stress and self-flagellation, and instead put their commendable concern for others to good use and rang the doorbell of a struggling neighbour with an offer to lend a hand.

  1. There is a separate obvious argument to be made about how the concentration of wealth enables poverty, but my point is that it is not intrinsically reprehensible to be able to live comfortably. ↩︎

  2. For more on this topic, I can recommend “The Tyranny of Merit” by Michael J. Sandel. ↩︎

  3. No :-) ↩︎

Adding a Temperature Sensor to my Flat

I live in London now, and on the 18th and 19th of July this year, the UK saw its highest recorded temperatures ever. The south-east of England was particularly affected. I personally struggle a lot with heat, and knowing I would find temperatures of up to 40°C unbearable, I escaped London to slightly chillier Portsmouth.

However, before I left, I thought it would be really cool to see how the temperature and humidity in the flat change during the heat wave while I’m away. Luckily enough, I realised I had a Raspberry Pi Zero and a BME280 temperature sensor, so I got to work putting them together. You can get the sensor from Adafruit — it’s easy to connect via I2C and it seems to be quite well-supported when it comes to Linux drivers. Here’s what it all looks like.

A Raspberry Pi connected to a temperature
My Raspberry Pi Zero connected to the BME280

The next stop was to write some code to get the data off of the sensor. I put together something super quick in Go using a driver someone had already written, and this allowed me to read the temperature, humidity, and atmospheric pressure in a particular instant.

package main

import (



func main() {
	d, err := i2c.Open(&i2c.Devfs{Dev: "/dev/i2c-1"}, bme280.I2CAddr)
	if err != nil {

	b := bme280.New(d)
	err = b.Init()
	temp, pres, hum, err := b.EnvData()
	if err != nil {

	fmt.Printf("date=%s ", time.Now().Format(time.RFC3339))
	fmt.Printf("temp=%f ", temp)
	fmt.Printf("pres=%f ", pres)
	fmt.Printf("hum=%f\n", hum)

I collected this data every second with a crontab, and sent it off to a webserver. The next step was to make a small web page to interactively display the live data. I normally would have built something custom with D3, but I really didn’t want to spend any time on this, so I just used an off-the-shelf plotting library to put something together real quick. Unfortunately, this resulted in a 4.4MB page size, but this page is really only for my own use anyway, so whatever.

Here’s what the result looks like! :)

A graph of the temperature in my
A graph of the temperature in my flat

You can access the live version at met.vladh.net, which has real-time values from my flat, including humidity and atmospheric pressure.

Right away, I noticed some really interesting stuff in the data. First of all, it’s amazing how smoothly and regularly the temperature changed during Monday and Tuesday, when I was away. I guess that, without any human intervention, and in particular without any ventilation, the temperature changes quite gradually.

You probably noticed the sudden drop in temperature on the 20th, which is when I got back home and opened all the windows. At this point it had gotten cooler outside than it was inside, so ventilation really helped decrease the temperature.

Since then, constant shuffling about and opening and closing windows seems to cause constant spikes in temperature and humidity. I guess this makes sense, but it’s kind of cool and unexpected to see the magnitude of these changes.

The heat wave is (thankfully) long over, but it’s going to be fun looking at these graphs in the future!

Spreadsheet Formula Parsing

Lately, I’ve been working on a spreadsheet program. I think spreadsheets are cool and I often need to use them, but the current software could be a lot better. :) You basically have to choose between impossibly overcomplicated Excel or an army of open-source clones that don’t learn from its mistakes.

Anyway, the really fun part about working on spreadsheet software is that you have to implement a programming language for it! I’m referring to the formula language we all know and love: SUM(A1:B3, 150) and all that.

I’ve started work on implementing something not too far from what Excel has. So far, I’ve written the lexer and the parser. Let’s take some sample input:

        AVERAGE(COL(A), ROW(20))
    ) / (1 + 2) * A2:B3:C4

The first step is to lex this into lexemes (e.g. SUM). Let’s run the lexer on the above expression.

name lparen literal comma name lparen cellref comma cellref range cellref comma name lparen name lparen name rparen comma name lparen literal rparen rparen rparen div lparen literal plus literal rparen times cellref range cellref range cellref rparen eof

Oof! Now we need to convert each lexeme to a token (e.g. TokenType::name), then parse all of the tokens into an AST (abstract syntax tree) made up of various kinds of expressions. For example, SUM() translates to the lexemes SUM, ( and ), which are of lexical type name, lparen, rparen, which all ends up being translated into an ExprCall, because this is a function call expression. Let’s run the parser.

  literal[str, hello]
            literal[i64, 20]
        literal[i64, 1]
        literal[i64, 2]

Looks about right! :)

The next step is to actually write the evaluator, which will walk this abstract syntax tree, evaluate all the expressions and return the result of the whole thing. In our above case, it would probably be, like, hello57 or something, depending on what’s in your spreadsheet.

Update: The code for the formula evaluator is now open-source and available at git.sr.ht/~vladh/sheets-formula-evaluator.


So far, I’ve only really posted infrequent manicured content on my website so I thought it would be nice to have a place to more regularly share random things as I work on them, even if this means having small silly posts. To avoid things getting lost in the noise, if a microblog post ends up being particularly good, I’ll promote it to a full website post.

People I follow like Drew DeVault and 100 rabbits have monthly “status updates”, but my updates currently aren’t organised enough for something like this.

One person I know who does something similar is Bill Wurtz with his “expert mode”. You’d think nobody would bother to look through an HTML document with a million tiny posts, but I’ve thoroughly enjoyed looking at everthing Bill has done, even the random everyday bits.

I know this is what people normally use social media for, but the last thing I want to do is host everything I write on the website of a corporation that monetises outrage and bickering. There’s the Fediverse, but self-hosting feels nice.

Unlike content for my website or clumsy computer, the stuff on the microblog isn’t well-suited for teaching, and I don’t go out of my way to explain things so beginners can understand them. Honestly, I’ll probably post about things I don’t understand very well.

Overall, I’ll share things that brought me joy and helped me learn, whether related to programming or otherwise. Thanks for coming along on the ride. :)