Whilst experimenting with std::visit
on Godbolt, I was surprised how noisy the generated assembly was. For all the main compilers there seemed to be a lot of calls and vtables being generated, and it all seemed unecessary given that so much could be determined at compile time. I tried using std::variant.index(), std::get() and std::get_if() – initially in a big switch statement – and found that the compiler could be coerced into generating far more minimal code:
Author: Alex Allmont
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))( cylinder( r1=handle_taper_radius, r2=handle_top_radius, h=handle_height, segments=30 ) ) top_radius = top_diameter / 2 base_radius = base_diameter / 2 ball_height = ball_radius + height / 2 return union()( handle, difference()( cylinder( r1=base_radius, r2=top_radius, h=height, segments=60 ), translate((0, 0, ball_height))( sphere( r=ball_radius, segments=40 ) ) ) ) # 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.
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) { (void)*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 use(x); // Mutating value passes ownership, has_been_moved set on original x use_mut(std::move(x)); // Uncomment for owner_already_borrowed = 1 //use(x); // Uncomment for owner_already_moved = 1 //use_mut(std::move(x)); // 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%:
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.