Exam Prep

Me to eldest child: Good luck with that physics exam today. (Joking) Remember – everything reduces down to the Schrödinger equation in the end, so that’s really all you need to know anyway.

Child: Would that be the time-independent version, or the time-dependent one?

Me: Err…

Child: Relativistic or non-relativistic formulation?

Me: Just do well in the exam, please.



A couple of years ago, in response to a challenge from one of my children, I wrote a poem. It’s not a good poem, and even a Vogon would be embarassed by it. But nevertheless, a poem it is. A while back I found it tucked inside a book and, since there is unlikely to be a follow-up, immediately thought I should expose myself to ridicule by posting it here. It’s really bad.


For those who can’t read my writing:

Plato, in the cave,

Watches the firelight shadows dance.

And dreams of Wittgenstein

In the trenches

Lit by flickering phosphorous flares.

Neither of us know what any of this means,

Do we?

No, he says, but at least

We tried



Passwords UX

I’ve just been through the process of claiming a tax refund. To do this I first had to create  something called a Government Gateway Account. As well as giving me the slightly queasy feeling that I would now exist forever on yet another database I also, inevitably, had to create yet another password that I will henceforth have to remember. Also forever. Here’s the password creation screen:

Government Gateway Account password creation screen

Government Gateway Account password creation screen

This does not fill me with confidence. Not at all. Not even close.

Firstly the 12 character maximum length just screams “we store your password in plain text in a CHAR(12) column, so there” at me. Like its 1993 and we’re using CGI or something. No hashing. No salting. Just a nice text column that our legacy platform can read, and that the techs can run a SELECT on when you forget your password or they fancy a giggle.

And the no special characters rule instantly activates my “we don’t do SQL injection mitigation at the backend, and we don’t care” detector. Because the platform probably dates from before the time that anyone considered that it might be connected to the internet.

Oh, and the big fat BETA at the top: I get that it’s probably meant to look exciting, but it doesn’t fill me with hope. This is my government ID. Where’s the smartcard authentication? Can I use my Yubikey? Nah, none of that stuff.

Bah. Whatever. As long as I get my refund.



// TODO: Requires testing on staging env. ** Do not run on production ** 
public bool Validate(Terms brexit)
    if (this.EU.Commission.Approves(brexit))
        if (this.EU.Countries.All(country => country.Approves(brexit))
            if (this.EU.Parliament.Approves(brexit))
                if (this.UK.ConservativeParty.Approves(brexit))
                    if (this.UK.Parliament.Approves(brexit))
                        return true;  // TODO: Gives "unreachable code" error!!??

    throw new HardBrexitException("No deal", brexit);  // Fallthrough

Time and Memory

Your child fusses with his uniform for a few moments, then goes around to the back of the car to get his bag. You watch him walk away across the car park towards the school buildings. He looks back only once and gives a gesture that might be a wave. You rest your chin on the steering wheel and watch him in the bright, cool autumn day with the leaves on the ground and try to fix the moment in your mind. It occurs to you that in a few decades time, when they are both grown and gone out into the world, you’ll remember moments like this. And then you think: what will it feel like to have carried such memories over such a distance? And then you realise that you’ll also remember thinking about that too: the anticipation of an understanding not then available to you. Time is so strange. The child is gone and you drive away to your work and the world’s new day.



Perhaps God has many more seasons
in store for us —
or perhaps the last is to be
this winter
that guides back the waves
of the Tyrrhenian Sea
to break against
the rough pumice cliffs.
You must be wise. Pour the wine
and enclose in this brief circle
your long-cherished hope.

— Horace, Odes



Today I am remembering my old friend Panayiota Pastra — Yiota to everyone — who died a year ago today.

We met when we were neighbours in Walley Range, Manchester, in the mid-nineties. She was a postgrad student at UMIST and I had been working for software companies in south Manchester for a couple of years. We would often sit in her flat drinking Greek-style coffee and just talking. She took me to bars where there was good ouzo and you had to shout over the noise of crowds of Greek people good-naturedly arguing with each other. I took her up Mam Tor on a very windy day. We cooked meals for each other (badly I’m sure, for my part, and expertly for hers) and she introduced me to Robert Frost.

When she moved to Glasgow to do her PhD, I drove her there with all her possessions. I visited a number of times before she moved on again to France, and then back to Greece. And we kept in touch over the years; first by letter and then in that strange, disconnected way that the internet makes possible. She went on to become a highly-regarded academic and teacher, eventually moving back to the UK. Then she told me she was ill, and a few email exchanges later she was gone. She left a husband and a young family.

She was a good and brave and dear friend at a difficult time in my life. And then a more distant but no-less important internet friend for a large span of my adult years. I miss her.

Yiota in Glasgow in 1997


Two trips

Some pictures from two backpacking trips, taken two months apart, and under very different conditions.

Back in mid-March I headed up to the Lake District to try to catch the very last of the winter conditions. With impeccable timing I managed to choose the weekend that the “Beast from the East II” blew-in and caused a fair amount of difficulty. My route started at Ravenglass, proceeded over Muncaster Fell to Eskdale Green, then up Miterdale to Burnmoor Tarn before descending to Wasdale. Then the next day, over Sty Head to finish as Rosthwaite, and then home.

Conditions were by no means full-on winter, and the snow cover was fairly modest; but it was extremely cold, with icy sleet and snow blowing in on a strong westerly wind. Crampons and goggles were frequently needed, but I didn’t use my ice axe. This wasn’t a long or ambitious walk but it was sufficient given the conditions (and limited daylight).

Here’s your author nearing Burnmoor Tarn, and looking grumpy after about half an hour of being sandblasted by high-speed wind-blow spindrift:

Approaching Burnmoor Tarn

And here’s the icy conditions at Sty Head the next day:

Styhead Tarn

The tarn was almost completely frozen over, and crampons were essential right down to the valley floor.

The full gallery is here.


Two months later I made the journey up to Mull with the intention of walking up the island, and then along the Ardnamurchan peninsula. The weather was very different: very hot and bright with little breeze. Finding water was often a problem, and by the time I got to Ardnamurchan I was content to just head over to the other side of the peninsula for the night and return the next day.

Coastline near Fionnphort

A hot day on forest tracks at the edge of Loch Frisa

Port Eigin-aig

The full gallery for this trip is here.


I’d like to get up to Scotland again before the year is out – especially as we’re not having our usual family holiday there this year. And I’ve also got some ideas for a weekend Forest of Bowland to Howgills walk, and a couple of days in the northern Cumbrian fells (preferably in late Autumn). And next year some trips earlier in the winter – probably in mid-January. This has been a promising start though.


Notes on generating printable Keras documentation

It started when I wanted to print the documentation for Keras so that I could peruse it on a train journey. Obviously this is a weird thing to want to do in at least two different ways, but sometimes you’ve just got to have ink on paper.

The online HTML documentation for Keras is built from extended markdown files, and can (in theory – hence this post) also be used to generate a PDF file. However, when I tried it there turned out to be a few “issues”, so I thought I’d document this in case anyone (including future-me) wants to go on the same journey. I’m not going to document the process of discovery I went though, just what seems to be the easiest route to getting a printable PDF. Note that these instructions are for Windows.

Ready? Lets go.

Part 1: Install the prerequisites.

1. Install Python 3.6 if you don’t already have it.

2. Download and install mkdocs. I used pip3 to do this. It will install itself into <user>\AppData\Local\Pandoc and you’ll need to add this to your path.

3. Download and install mkdocs-pandoc.

4. Download and install MiKTeX. mkdocs-pandoc emits LaTeX and expects you to have a way to convert this to PDFusing pdflatex.exe, which is included in MiKTeX (and probably other TeX distributions). Choosing the option to automatically install missing packages will save time later. Add C:\Program Files\MiKTeX 2.9\miktex\bin\x64 to your path.

5. Download the Keras repo from Github and unzip keras-master.zip. You’ll need this because it includes the documentation source files.

Part 2: Generate the PDF

1. In an command window, go to keras-master/docs. You’ll see a readme.md file containing instructions for building the docs. We’ll be following this outline but adding some workarounds.

2. Run python autogen.py and wait for errors to occur:

Traceback (most recent call last):
File “autogen.py”, line 559, in <module> readme = read_file(‘../README.md’) File “autogen.py”, line 532, in read_file return f.read() File “C:\Program Files\Python36\lib\encodings\cp1252.py”, line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] UnicodeDecodeError: ‘charmap’ codec can’t decode byte 0x81 in position 7411: character maps to <undefined>

This is happening because autogen.py is trying to read files that don’t match the default file encoding. We’ll need to hack autogen.py, so open it in an editor ando to the first place that f.read() is called, which for me was line 532. Change the previous line from

with open(path) as f:


with open(path, encoding=”latin1″) as f:

Save autogen.py and run the command again. You should get a similar error on a different line (it was line 563 for me) so fix it the same way. Save autogen.py and run the command yet again. This time it should complete successfully and generate a bunch of markdown files in the sources directory.

3. Run the mkdocs serve command. This does some stuff and starts a local web server. Since this blocks the command window, you’ll need to start another command window and go to the docs directory.

4. In the new command window, run mkdocs build. This generates an html web site in the site directory. This may not be strictly necessary, but its a useful check that things are working.

5. At this point we leave the instructions in readme.md behind. Run the command mkdocs2pandoc > keras.pd. This creates a single large markdown file (keras.pd) that is optimised for generating PDFs.

6. The markdown document has a few problems at this point, which we can rectify by hand-editing it. I used notepad++ for this.

  • Change the top-level heading on the first line from #Home to #Introduction.
  • The markdown document contains a number of HTML <span> tags with level five headings on the next line. This causes pandoc (see step 7 below) to output the tag’s alt-text but fail to render the heading correctly. The solution is to add a line between them by using search and replace to replace </span>\r\n##### with </span>\r\n\r\n#####.
  • The markdown contains HTML <img> tags that pandoc won’t handle. Either remove these manually or (as I did) leave them in and pandoc will render the alt text. Annoying but I can live with it.

7. Run the command pandoc –toc -f markdown+grid_tables+table_captions -V geometry:margin=2.5cm –pdf-engine=xelatex -o keras.pdf keras.pdYou’ll probably see some warnings: just ignore them. If you chose not to allow MiKTeX to automatically install missing packages then you be asked for permission to install various things as they are needed. The default LaTeX stylesheet renders pages with large margins, so I overrode this by setting them to 2.5 cm (about one inch) – tweak this according to preference. I also specified xelatex as the PDF engine because the default engine had fatal problems with some Unicode characters in the document. The table of contents defaults to three levels: if you want more detail then add –toc-depth=4 to the command.

At the end of all this, you’ll see you have a keras.pdf file. Load this into your favourite PDF viewer or print it out according to your preference.