Household 3D Print – Bath Plug

My bath has – well, had – a push-action bath which would seal when pushed down and unseal when pushed again. Over-engineered crap like this is bugbear of mine. An old-fashioned plug or tap is intuitive to use, and very grabbable in a Gaudi-like way. My experience of modern ‘bathroom innovation’ is just bad UX. The prime example of this was a tap in a restaurant bathroom which had a plain cube on top. Should I turn it or push it? Nope, I tilt it. Naturally.

These designs just add entropy to the universe; they fuel consumer insanity and replace old wisdoms with trends. Case in point, the push-plug in my bathroom was a nightmare to clean and eventually broke off. My bachelor solution for the past week was to simply tape over the hole with gaffa, which works surprisingly well!

Today I thought it would be a good bit micro-DIY to make a new one and test my 3D printing skills. I cracked open a Jupyter notebook and wrote the following.

from solid import *
import math
import viewscad

def make_plug(
    top_diameter: float,
    base_diameter: float,
    height: float,
    ball_radius: float,
    handle_height: float,
    handle_diameter: float
    handle_top_radius = handle_diameter / 2
    handle_taper_radius = handle_top_radius / 2

    handle = translate((0, 0, 1))(

    top_radius = top_diameter / 2
    base_radius = base_diameter / 2
    ball_height = ball_radius + height / 2

    return union()(
            translate((0, 0, ball_height))(

# Bespoke just for my bath!
plug = make_plug(41, 38, 10, 40, 16, 20)

The radii were roughly measured and I did a very low-res print but I was surprised that the test came out really well. Here’s the initial draft.

And amazingly the test print is a perfect fit. A little PVC tape around it will make a good seal. I’ll iterate this a bit, the final print will be in white, higher res, and with bevelled edges.

Blog Code

Hypothetical Rust-ish Borrowing in C++

Last night I got into a insomniac code-spiral about replicating some of Rust’s borrowing warnings in C++. In place of Rust’s initial variable declararion of let I use wrapper Owner<T> in C++ that internally tracks ownership. Passing to another Owner<T> will take the ownership, or a Borrower<T> class can accept a properly owned value and reference it as a constant.

// Function borrowing a value can only read const ref
static void use(Borrower<int> v) {

// Function can mutate value via ownership which generates 'warnings' if used again incorrectly
static void use_mut(Owner<int> v) {
  *v = 5;

int main() {
  // Rather than just 'int', Owner<int> tracks the lifetime of the value
  Owner<int> x{3};

  // Borrowing value before mutating causes no problems

  // Mutating value passes ownership, has_been_moved set on original x

  // Uncomment for owner_already_borrowed = 1

  // Uncomment for owner_already_moved = 1

  // Uncomment for another owner_already_borrowed++
  //Borrower<int> y = x;

  //Uncomment for owner_use_after_move = 1;
  //return *x;

Miyazaki Film Title Generator

This code combines random components of words to produce silly Miyazaki-inspired film titles. Such classics as:

  • Tolo Pippi’s Marvellous Leaf
  • Being Onto
  • Chibot Pom’s Jolly Bramble
  • Poko Trollpi and Tombo Go’s Coat Pushing Whistle
  • Tolo Pom and Asbo Go
  • Chi Pop’s Flambuoyant Sponge Popping Service
  • Kabee Go’s Wandering Jelly
  • Tolopa Popyo’s Functional Castle Sniffing Service

Doodles for Lossless Compression of CV Data

I’ve been developing a few electronics ideas that require storing CV data. I thought for a first stab ‘keep it small’, so I’ll try it with an 8k or 16k AVR chip, and I am curious how many seconds of data, sampling at say 100Hz, that I could store in that space. Obviously it will get saturated at some point, but that’s a subject for a later doodle where I need to get into lossy compression (for example, make space by removing small deltas from it).

A friend recommended run length compression on deltas. I did some experiments with that in a jupyter session using smoothed random noise as test data. Here are those early experiments where, speaking very loosely, things compress to around 30%:

Blog Music

MIDI Responsive Qt

Challenge: get MIDI keyboard to update Qt controls for some live jam experimentation. Task list:

  • Use a particular channel for a controller. In future I could make a hardware device that changes channel on a button press, say.
  • Respond to dials changing to update Qt controls. Should be as simple as binding MIDI signal to Qt slot.

MidiJam Bootstrap

I had a moment of clarity on how to get my MIDI jamming tools working this morning. I made a sketch, it was all crystal clear in my mind, and had the typical ‘right, let’s do this!’ moment that all programmers experience, before having all joy boiled out of it by a cascade of tool and API issues.


Shopping List: The Zombie dash

For the past week I’ve been self-isolating whilst Covid-19 precautions are ramping up in the UK. I have asthma but it’s so mild that I’m probably not what the government would classify as vulnerable. Unfortunately this puts me between a rock and a hard place for supplies; shops have no slots for delivery or pick-up, and I don’t want to deprive someone genuinely vulnerable of that service. So in a week when I need food I may be facing a zombie hoard in Sainsbury’s, coughing might-be-Covid on the onions and lingering around the Easter eggs.