Real Django site

Monday 13 September 2021

Big changes behind the scenes here at, but only a small change for you.

My hosting provider was being acquired, and they said they would migrate my site to the new host. Then they wrote last month to say they couldn’t migrate it (no word why), and that I had six weeks to find a new home.

I briefly tried to just move the site as it was, but PHP 5 was in the mix. Rather than learn how to move it to PHP 7, I bit the bullet and converted it to a real Django-served site.

For 13 years this site has been built with Django, but served as static HTML pages. The comments were handled by PHP code. As part of this move, the site is now served directly by Django on the host, with Django-implemented comments.

This should all be invisible to readers of the site, except for one thing: comments are now written as Markdown instead of as neutered HTML. Having a Django foundation means I will be able to make changes more easily in the future.

Behind the scenes, there is still plenty of strange tech: content is in XML, loaded into a SQLite database locally, then rsync’ed to the server.

Some dormant areas of the site aren’t serving properly yet, but the important stuff works. If you see a problem, please let me know.

Me on Bug Hunters Café

Monday 23 August 2021

I was a guest on the Bug Hunters Café podcast: episode #12, The Café Within.

Bug Hunters Café is a fun open-ended conversation about bugs and other programming topics, hosted by Jason C McDonald and Bojan Miletić. It’s whimsically set in a science-fiction-themed café.

We talked about a bunch of things: testing,, printers, abstractions, Python’s unfortunate readability, kudzu, IRC, Python Discord,, sitting up straight, asking and answering questions, yes and no, studying data structures, singletons, and more.

It was great to have an extended discussion, and it was fun to play along with the café setting.

Pythonic monotonic

Thursday 12 August 2021

In a recent conversation, someone shared some code from a book about technical job interviews. They wanted to know if I agreed that the code was “Pythonic.”

The problem was to find the runs of increasing and decreasing values in a list, and to produce a sequence of the runs, but to reverse the decreasing runs, so that they are also increasing. This was the “Pythonic” code:

import itertools

def mono_runs_pythonic(seq):
    class Monotonic:
        def __init__(self):
            self._last = float("-inf")

        def __call__(self, curr):
            res = curr < self._last
            self._last = curr
            return res

    return [
        list(group)[::-1 if is_decreasing else 1]
        for is_decreasing, group in itertools.groupby(seq, Monotonic())

mono_runs_pythonic([1, 2, 3, 2, 1, 4, 5, 6, 7])
# --> [1, 2, 3], [1, 2], [4, 5, 6, 7]

My first response was that I don’t like this code, because I had to read it with my eyebrows. That is, I furrow my brow, and read slowly, and scowl at the code as I puzzle through it. This code is dense and tricky.

Is it Pythonic? I guess in the sense that it uses a number of Python-specific constructs and tools, yes. But not in the sense of Python code being clear and straightforward. It uses Python thoroughly, but misses the spirit.

I tried my hand at my own solution. It came out like this:

def mono_runs_simpler(seq):
    seqit = iter(seq)
    run = [next(seqit)]
    up = True
    for v in seqit:
        good = (v > run[-1]) if up else (v < run[-1])
        if good:
            yield run if up else run[::-1]
            run = [v]
            up = not up
    if run:
        yield run

This code also uses some unusual Python techniques, but is clearer to me. I’m not sure everyone would agree it is clearer. Maybe you have an even better way to do it.

Aside from the question of which code is better, I also didn’t like that this code was presented as a good solution for a job interview. Studying code like this to learn intricate tricks of Python is not a good way to get a job. Or, it might be a good way to get a job, but I don’t like that it might work. Job interviews should be about much deeper concerns than whether you know little-visited corners of the Python standard library.

Aptus v3

Sunday 25 July 2021

After a hiatus of almost 13 years, I’ve made a new release of Aptus, my Mandelbrot explorer. I got re-interested in it as a way to make Zoom backgrounds during the pandemic.

I started by moving it from Python 2 to Python 3.9. Then the wxPython GUI needed to move up a few versions, but it wasn’t working too well. So I built a new browser-based user interface. A compute server in FastAPI and a UI in vanilla JavaScript are the new GUI.

There are features from the old GUI that aren’t available yet (You Are Here is my favorite), but it’s very usable.

Intricate Mandelbrot

Coverage 6.0 beta 1

Sunday 18 July 2021

I’ve just published 6.0 beta 1. The latest changes are not monumental, but I would love for you to test it.

The version bump to 6.0 is because I’ve dropped support for Python 2 and Python 3.5. But also because the changes to how third-party code is handled felt potentially disruptive. Please read that blog post for details.

The other big thing happening with is Python 3.10. Because of PEP 626 (“Precise line numbers for debugging and other tools”), there have been many changes to how Python reports line numbers. depends on those line numbers, so there have been more than a few bug reports written against Python as the work has progressed.

It will be important to test with 3.10, but to be fair, there have already been a few problems reported in the latest version, 3.10 beta 4. So if you use beta 4, you’ll want to avoid re-reporting the known problems:

If you can build 3.10 from source, that would be a great thing to use for testing, or get ready to jump on 3.10.0 rc1 when it comes out on August 2.


Math factoid of the day: 59 icosahedra

Wednesday 16 June 2021

Today’s math factoid of the day: there are 59 icosahedra.

I’ve long been fascinated by stellation, the process of extending a polyhedron’s faces to form new structures. The word stellation is from the Latin root for star, so it means to make star-like. The star that graces the upper-left corner of this site is a stellated dodecahedron.

To understand stellations, let’s start with two dimensions. Consider a regular pentagon. If we extend the sides of the pentagon, they will intersect again, making a five-pointed star:

Pentagon extending to become a five-pointed star

(image from

Looked at this way, the original pentagon is just the first 2D area enclosed by the sides’ five infinite lines. When we extend the sides, we’re finding five more areas (the points) enclosed by those same five lines. The five-pointed star is a stellation of the pentagon.

With a pentagon, there are no more stellations: extending the sides even more won’t find any more intersections, so no new areas are enclosed. But more complex shapes can have more stellations. As an example, a 9-sided polygon will have three stellations in sequence:

Three stellations of a 9-sided polygon

(image by Tomruen, CC BY-SA 3.0, via Wikimedia Commons.)

Going to three dimensions, stellating a polyhedron doesn’t extend edges, it extends faces. Here’s a video my son Ben made showing a dodecahedron producing three stellations. The faces each lie in one of 12 infinite planes, which intersect in a few different ways, producing new shapes:

The 12-sided dodecahedron only has those three stellations. Extending the planes further doesn’t produce any more intersections, so no new volumes are enclosed. The star on this site is the last (third) stellation of the dodecahedron.

What about the 20-sided icosahedron, how many stellations does it have? Things get much more complicated. In 1938, H.S.M. Coxeter and his co-authors wrote a famous book about the enumeration of the icosahedron’s stellations. First, rules had to be considered about what would count as a stellation, and what would not.

Like the 9-sided polygon, the dodecahedron has a simple linear sequence of stellations, each building on the previous, like nested Russian dolls. But the icosahedron is not so tidy. The book describes intricate rules that I won’t get into for determining what would be considered a stellation.

They counted 58 stellations of the icosahedron. When you include the original icosahedron itself in the list, you get the title of the book: The Fifty-Nine Icosahedra.

Jan Albert Vroegop has a beautiful gallery of all 59, but here is a sampling (from Maurice Starck’s page):

10 of the 59 stellations

BTW, you can buy 3D-printed stellations, but trigger warning: some of them are called icosahedra when they are really dodecahedra!