Anything involving the straightforward writing of code, without worrying about what runs it later, ends up here.

I’m very much an amateur, and mostly write in Python, so be kind to me ;)

Too Many Directories

My PhD has too many directories in it. I have—currently—three parts, and each of those has several chapters. All the chapters have been written independently, so I have a structure which more or less looks like this: titlepage.tex thesis.tex -- 1.part1 | +- 1.chapter1 | +-- standalone.tex +-- title.tex +-- chapter1.tex +- 2.chapter2 etc, only with three parts and sensible names. Each of the chapters builds to a separate pdf with standalone. [Read More]

Migrating Home Assistant (and thoughts on over-engineering)

Home Automation is largely a gimmic. Even the founder of Home Assistant writes blog posts pointing out that turning the lights on from your phone is pretty pointless, except for showing off (not that I’ve ever turned a light on from my phone to show off…). Another of these posts tries to think of a useful smart light and comes up with: Imagine a brave new world where you walk into a room and the light is already on, as you have naturally come to expect after years of living with such a technology. [Read More]

Hacked

I got hacked. There are all kinds of fun exploits people use to get into systems they’re not supposed to be in. In my case they used ssh. Normally ssh is secure. None of my passwords are brute-forceable. (Yes, you shouldn’t have public-facing password ssh… but that’s no fun when you’re on someone else’s computer and need to get in in a hurry.) But in a moment of weakness I had needed a blank slate to test an environment regression against. [Read More]

Python Is (sort-of) Functional

I recently had to parse a csv file which looks like this: "key","val" "key","val" "key","val" "col1","col2","col3","col4" ... row data here The obvious, imperative solution would be: from csv import DictReader def parse(f): props = {} for line in f: if not line.strip(): break k, v = line.strip().replace('"', "").split(",") props[k] = v reader = DictReader(f) data = list(reader) return props, data With the walrus operator we can save a few lines at the cost of non-obvious syntax: [Read More]

“Modern Authentication”: Outlook365 in Emacs

A few weeks ago I received an email from the university stating: Further to our previous communication advising about a change to basic authentication for Durham mailboxes, on 28th October 2021 we will be removing the ability to connect to University email via IMAP and our records indicate that you currently access email in this way. This, apparently, is down to the fact that Basic authentication is no longer secure enough to support modern working as it does not support security features such as Multi-Factor Authentication (MFA). [Read More]

Cleaning Scanned Pdfs

This post is largely a log so I remember how to do it next time, but if anyone else has a bunch of scans to convert, read on… Background Frequently in academia—and probably in much of the modern world—one has to handle things which began life as books, hit the glass of a scanner, and became pdfs. Scanning is hard, and unless one has a lot of patience, the resulting pdfs are generally pretty all over the place: sometimes pages are upside down, frequently the book (which was not made to lie flat) does not want to flatten on the glass, and often the scanner has simply picked a nearby standard page size. [Read More]

Anti Rsi

There are lots of anti-rsi packages out there for windows. I even found a few for Linux. None did what I wanted them to do: to enforce short and long breaks at configurable intervals, allowing me to push them back when I was in the middle of something, but getting increasingly insistent that I actually took them. Enter anti-rsi, a python script which does everything an anti-rsi package needs to do and nothing more. [Read More]

Volatile Tmp

What does one do with temporary files? For things one really doesn’t need, there’s /tmp, which is wiped on boot—though sometimes it’s a ramdisk, and one should be wary of dropping large files into ramdisks. But what about e.g. downloaded isos, pdfs prepared for printing, and the like? Things one needs now, might need tomorrow, but definitely won’t need in a year’s time? Like most people I used to use ~/Downloads and go through it (with ncdu) every time it got too large. [Read More]

CLI Countdown Timer

Stop procrastinating and do some work

I wrote this a while ago, and it’s been in use ever since: a very simple script which counts down (or up) while printing the remaining time. Controlled with standard job control, it’s one up on sleep as you can see how long is left. This is occasionally handy; if I only have ten seconds on the clock before lunch I’ll not start something new, but if I’ve got fifteen it might make sense. [Read More]

ChuffChuff (cheaply)

On a rainy day here I wondered exactly when I should book a ticket up to Durham for another term. Most of the booking websites will help you, but not much: it’s tiresome to check a few days to see what the price variation is—and it can be fairly enormous. I was also curious as to what the long term trends might be: they don’t just seem to go down. All of which suggested some code to screenscrape all the tickets from somewhere and analyse them. [Read More]