Tech
2024
Message order in Matrix: right now, we are deliberately inconsistent -
Mini-rust in Rust 005: Making our lexer an iterator -
Mini-rust in Rust 004: Refactoring our lexer -
Mini-rust in Rust 003: Much prettier errors -
Mini-rust in Rust 002: Errors while lexing -
Mini-rust in Rust 001: Lexing an int -
Rust 101 - 53: Exercises for module G (q4) -
Rust 101 - 52: Exercises for module G (q3) -
Rust 101 - 51: Exercises for module G (q2) -
Rust 101 - 50: Exercises for module G (q1) -
Rust 101 - 49: Foreign function interfaces (interacting with other languages) -
Rust 101 - 48: Exercises for module F (q3) -
Rust 101 - 47: Exercises for module F (q2) -
Rust 101 - 46: Exercises for module F (q1) -
Rust 101 - 45: Unsafe types and examples -
Rust 101 - 44: Undefined behaviour -
Rust 101 - 43: The two meanings of "unsafe" in Rust -
Rust 101 - 42: Why do we need unsafe? -
Rust 101 - 41: Exercises for module E (q2b) -
Rust 101 - 40: Exercises for module E (q2a) -
Rust 101 - 39: Exercises for module E (q1b) -
Rust 101 - 38: Exercises for module E (q1a) -
Rust 101 - 37: Async runtimes -
Rust 101 - 36: What async and await really do -
Rust 101 - 34: What is async? -
Rust 101 - 33: Exercises for module D (q3) -
Elected to the Matrix Foundation Governing Board! -
Rust 101 - 32: Exercises for module D (q2) -
Rust 101 - 31: Exercises for module D (q1) -
Rust 101 - 30: Good patterns and not so good -
Rust 101 - 29: Trait objects and object safety -
Rust 101 - 28: Dynamic dispatch -
Why I won't link to AI resources -
Rust 101 - 27: Exercises for module C (q2) -
Rust 101 - 26: Exercises for module C (q1) -
Rust 101 - 25: Threads, Mutexes, channels, Send and Sync -
Rust 101 - 24: Parallelism and Rayon -
Rust 101 - 23 Exercises for module B (q3) -
Rust 101 - 22 Exercises for module B (q2) -
Rust 101 - 21 Exercises for module B (q1) -
Rust 101 - 20: Unit, integration and benchmark tests -
Rust 101 - 19: Creating a nice API -
Rust 101 - 18: Dependencies and Cargo.toml -
Rust 101 - 17: Exercises for module A3 (part 2) -
Automated backups from Signal to Nextcloud -
Rust 101 - 16: Exercises for module A3 (part 1) -
Rust 101 - 15: Lifetime bounds -
Rust 101 - 14: Some standard library traits -
Rust 101 - 13: Type Parameters and Associated Types -
Rust 101 - 11: Exercises for module A2 -
[Fixed in FF 123] Deleting an Indexed DB store can be incredibly slow on Firefox -
Don't store normal arrays of numbers in Indexed DB - use UInt8Array instead -
Keep your Indexed DB keys and values small if you want good performance! -
Rust 101 - 9: Vecs, Boxes and slices -
Rust 101 - 8: Writing methods using impl blocks -
Rust 101 - 7: Error handling with panic and Result -
2023
Follow this blog on the fediverse! -
Rust 101 - 6: Structs and Enums -
Rust 101 - 4: Exercises for module A1 -
Rust 101 - 3: Memory and ownership -
Rust 101 - 2: Language basics -
Combining two function types with & (ampersand) in TypeScript (intersection) -
Accessing services on the host from a Docker container or a Podman one -
Rust WASM hello world - no need for webpack! -
Estimating software tasks and stories: avoid time-based estimates -
Maths: The Fun Parts - Graphs video -
Maths: The Fun Parts - Groups video -
Maths: The Fun Parts - Sets video -
Live code reviews make life better -
2022
Outreachy August 2022 update -
Transcoding video files for playback in a browser -
Matrix is a Distributed Real-time Database Video -
Building cross-platform Rust for Web, Android and iOS - a minimal example -
Improving my vimrc live on stream -
Comparison of Matrix events before and after "Extensible Events" -
2021
Streaming to Twitch and PeerTube simultaneously using nginx on Oracle cloud -
New game: Tron - frantic multiplayer retro action -
Preventing Virgin Media hijacking my DNS -
What to cache when building Rust using Gitlab CI or similar -
Printing the version of a Maven project -
Minimal example of a Maven pom for a mixed Kotlin and Java project -
Importing/migrating from one peertube server to another -
Matrix is the only (chat) game in town -
Suspending the computer using Kupfer -
Uploading to PeerTube from the command line -
Republishing Bartosz Milewski's Category Theory lectures -
Announcing I-DUNNO 1.0 and web-i-dunno -
Automatically filling in the UK COVID test results page with Selenium IDE -
Toggle window decorations on Linux GTK3 with Python3 -
Making Smolpxl work on phones and tablets -
Recommendation against the use of WhatsApp in your company -
Streaming video with Owncast on a free Oracle Cloud computer -
Is your program a function or a service? -
2020
Shutdown order consistency: how Rust helps -
Schema upgrades should be reversible (also other transformations, actually) -
Announcing Smolpxl Scores - a high score table for your game -
Dovecot not working after upgrade to Ubuntu 20.04.1 (dh key too small) -
Play and create little retro games at Smolpxl -
shareon.js.org now has a Share to Mastodon button -
Coding a tiny game in JavaScript video -
short - command line tool to truncate lines to fit in the terminal -
Set the date (EXIF) of a photo on Linux -
Example Android project with repeatable tests running inside an emulator -
Creating a tiny Docker image of a Rust project -
Keeping track of podcast times with a simple bash script on Linux -
Custom Bash tab completion for my program -
Struggling with Rust to figure out the right types for a function signature -
Converting HTML slides to a PDF with Firefox -
Support the Software Freedom Conservancy -
2019
KotlinJS: First impressions (formed by writing Snake) video -
Dependency Injection frameworks: reasons to avoid them video -
Coding workshop example worksheets -
Building an all-in-one Jar in Gradle with the Kotlin DSL -
Creating a self-signed certificate for Apache and connecting to it from Java -
ACCU Talk "How Kotlin makes your Java code better" -
ACCU Talk "How Git really works" -
Examples of Kotlin making your Java code better video -
Rabbit Escape 0.12 out now, with water -
Convert a video to a GIF with reasonable colours -
Python Async basics video (100 million HTTP requests) -
London Python Meetup January 2019 - Async Python and GeoPandas -
Run bash inside any version of Linux using Docker -
Windows missing from grub menu after Ubuntu install -
2018
Interesting Characters (UTF-16, utf-8, Unicode, encodings) video -
Graft Animation Language on Raspberry Pi -
My experience upgrading to Elm 0.19 -
Bulk adding items to Wunderlist using wunderline on Ubuntu MATE -
Writing a new Flarum extension on Ubuntu -
Ubuntu "compose" key for easy unicode character input -
Redirecting all requests to https and www using .htaccess in Apache -
Example of a systemd service file -
Installing Flarum on Ubuntu 18.04 -
Connecting to Slack from an IRC client using slirc -
Using Matrix to connect to Slack from an IRC client on Ubuntu -
Clever Things People Do In Groovy So You Have To Know About Them video -
Examples of SQL join types (LEFT JOIN, INNER JOIN etc.) -
Fixing Slack emojis in HexChat -
Ideas on how lexing will work in Pepper3 -
Deleting commits from the git history -
Questions and answers about Pepper3 -
2017
TECH(K)NOW Day workshop on "Writing a programming language" -
FileZilla with proxy not working with strange characters in the password -
HTML5 CSS Toolbar + zoomable workspace that is mobile-friendly and adaptive -
Broken Levels Challenge - Egham Raspberry Pi Jam July 2017 -
Women Who Code workshop on "Write your own programming language" -
Running a virtualenv with a custom-built Python -
Making 100 million requests with Python aiohttp -
Python - printing UTC dates in ISO8601 format with time zone -
Python 3 - large numbers of tasks with limited concurrency -
Basic ideas of Python 3 asyncio concurrency -
C++ iterator wrapping a stream not 1-1 -
How to write a programming language ACCU talk -
C++ iterator wrapper/adaptor example -
C++ iterator example (and an iterable range) -
Make Android Gradle display unit test failure messages -
A story about magic and how we treat each other -
Automated UI tests on Android -
Submitting a package to F-Droid -
Resources for year 6 teachers on coding and programming -
2016
Setting up a sane Maven project -
How to write a programming language - Part 3, The Evaluator -
How to write a programming language - Part 2, The Parser -
Mousedown events delayed or sluggish on mobile -
How to write a programming language - Part 1, The Lexer -
Gracefully shutting down Firefox, to avoid the crash/session dialog -
Elm makes me happy (old: Elm 0.17) -
2015
New open source project on work time - git-history-data -
Vim as editor for Claws Mail -
Avoiding postfix error "status=deferred (unable to look up host" -
Finding the download count of GitHub releases -
Android: using a TextView to show rich text in an AlertDialog -
Difficult merges in Git - don't panic! -
ZX Spectrum BASIC Web Server -
Docker fails to start on Ubuntu 15.04 -
Preventing Audacity from crashing when using PulseAudio -
Code for detecting when you leave an Android app -
Mocks are Bad, Layers are Bad -
Prediction result: corporate Linux -
Detecting whether an Android app is stopping (or starting) -
Order of Android Activity lifecycle events -
Preventing Kupfer switching to existing windows -
Rabbit Escape 0.3.1 - now with zoom! -
Treat warnings as errors in a (Gnu) Makefile -
Encapsulation as passing on responsibility -
Why Rabbit Escape is Open Source / Free Software -
How to make your own levels for Rabbit Escape -
Rabbit Escape v0.1 out now for Linux, Windows and Mac video -
Rabbit Escape (a bit like Lemmings) v0.1 released for Linux, Windows and Mac -
JAX-RS (using Apache CXF) in embedded Tomcat example -
Vim persistent buffer list combined with saved sessions -
2014
LibreOffice spell check not working in Lubuntu -
Is it ok to represent dates as Unix time (seconds since the epoch) in JSON? -
Using hexdump to represent a binary file in Java source code -
Disabling screensaver on LXDE -
Android development - saving state -
Android development - Rabbit Escape really working on Android -
Showing urgent (flashing) windows on all desktop in LXDE's taskbar (window list) in Lubuntu -
Launch an urgent window using Python and Xlib with the UrgencyHint flag -
Android programming - a non-Android, Android Game -
Don't use email auto-forwarding (emails will go missing) -
Fetchmail "mda" option makes emails bypass the spamassassin filter in postfix -
Android programming - a menu using Activities and Intents -
Android programming - setting up Android Studio -
Absolute Truth in programming languages -
Best GCC warning flags for compiling C++ -
What git server should I use? -
Renewing self-signed certificate for ejabberd -
OpenID security in a REST API -
avconv performance slow in Ubuntu 14.04 trusty -
Does test-driven development harm clarity? -
Token-based security in a REST API -
Avoid mocks by refactoring to functional -
Using the final keyword in interface method parameters does nothing -
Using xscreensaver to lock the screen in Lubuntu -
2013
Using if:set, unless:set etc. with macrodefs in Ant -
Using if:set, unless:set etc. to execute a task conditionally in Ant -
Behaviour of Java String.split() when some answers are the empty string -
Checking the case of a filename on Windows -
Passing several values through a pipe in bash -
Using gnome-mplayer to play DVB radio without asking whether you want to resume -
C++14 "Terse" Templates - an argument against the proposed syntax -
setUp and tearDown considered harmful -
Why use git for source control? -
Set the volume in OpenBox/LXDE (or on the command line) with PulseAudio and Ubuntu -
Everybody loves build.xml (test-driven Ant) -
Everybody hates build.xml (code reuse in Ant) -
Dry run mode for Ant (ant -n, ant --dry-run) -
My First Raspberry Pi Game " Part 12 " Scoring, done! -
My First Raspberry Pi Game " Part 11 " Being less rude -
2012
My First Raspberry Pi Game " Part 10 " Red square -
My First Raspberry Pi Game " Part 09 " Lots more words -
My First Raspberry Pi Game " Part 08 " Success and failure -
My First Raspberry Pi Game " Part 07 " A green circle -
Launching an OSGi app on the command line -
My First Raspberry Pi Game " Part 06 " A better class of waiting -
My First Raspberry Pi Game " Part 05 " Say something -
My First Raspberry Pi Game " Part 04 " A small black screen -
Length of Open Source licenses -
My First Raspberry Pi Game " Part 03 " It's like a magic spell -
My First Raspberry Pi Game " Part 02 " Saying hello -
My First Raspberry Pi Game - Part 01 - Before we start -
Running Dojo DOH tests in a browser without a web server -
Bash associative array examples -
Running Dojo 1.7+ DOH unit tests on the command line with Rhino -
Goodness in programming languages, part 3 " not doing the same thing more than once -
Tail Call Optimisation in C++ - lightning talk video -
Tail Call Optimisation in C++ published in Overload journal -
Scheme 4: Recursion - how to write functions in Scheme video -
Scheme 2: Basics - pairs and lists video -
Scheme 1: Feel the cool video -
Generalising tail call optimised C++ -
Performance of tail call optimised C++ -
Tail call optimisation in C++ -
Lighting talk - Tail call optimisation in C++ -
Scheme: pairs, lists and recursion -
What timezone Python thinks I'm in -
Freeview dvb-t scan gives "tuning failed!!!" after 18th April switchover -
Goodness in programming languages, part 2 " getting your code running -
Goodness in programming languages, part 1 - syntax and layout -
Ethernet not working on Ubuntu with Realtek RTL8111/8168B -
2011
Entertain your baby using your Android phone -
rdesktop swallows keyboard events -
Reclaiming desktop space with Ubuntu's window-picker-applet -
Switching workspace in GNOME via the command line -
Anatomy of an interpreter: the Evaluator -
How to ask technical questions in person -
2010
Ubuntu Lucid upgrade - a catalogue of disaster and pain -
2009
Don't design for performance until it's too late -
Technorati appear to have broken openid delegation -
NNDB 0.1 -
CBeebies and other channels not working with mplayer -
Firefox keyword search for finding C++ keywords -
Flaws in the software patents system -
IGCC - a real-eval-print loop for C/C++ -
Diffident - command line side-by-side diff editor -
Separate regular expressions, or one more complex one? -
2008
Fixing the vertical panel window list on Ubuntu Hardy -
An actual difficult bug fixed -
Public bzr branch of FreeGuide -
Finally released last.fm support for GSSMP -
2007
lighttpd on Ubuntu - alias.url doesn't work when included in a module config file -
FreeGuide updated to latest XMLTV, and bug fixes -
FreeGuide - putting recording on hold -
(Badly wrong) usage statistics for FreeGuide -
Procmail Maildir messages disappearing -
lastfmsubmitd on Ubuntu Dapper -
Digital TV on Dapper with my Hauppauge WinTV Nova-T card -
Restoring a backup with Duplicity -
Remote encrypted backup with duplicity -
Creating .deb and RPM packages -
2006
Another FreeGuide release candidate -
FreeGuide 0.10.4 release candidate -
A Quick and desperate introduction to data recovery -
Keyboard layout change in Ubuntu -
FreeGuide source layout (and SVN migration) -
Donation -
Setting up my ideal email system 4 -
2005
Setting up my ideal email system 3 -
Setting up my ideal email system 2 -
Setting up my ideal email system -
Prince of Persia - The Sands of Time -
The dangers of learning to code -
Constantly changing passwords -
FreeGuide packaging and plugins -
DIYBlog -
RSS -
What is going on with FreeGuide? -
Google -