Rebuild of DHondt.EU

18 August 2019
It was long overdue but a few weeks ago I completely overhauled, which is a spin-out microsite for the calculation of election results using the D'Hondt formula. It was previously a bit of a mish-mash presentation of several different calculator implementations, some dating back 10-20 years, but now the focus is more on pre-set election data-sets. From a technical stand-point the previous PHP-based backend has been replaced with a Django-based one, and the CSS styling simplified a bit to make it more robust.


Writing various applications for calculation of D'Hondt election results is something that goes back to the 1990s, and in the mid-late 2000s I made various web-based versions that at some point around the time of the 2009 Euro-Elections were being linked to from elsewhere on the internet. For reasons I have long-forgotten I decided it best to spin out the relevant section of personal site into a self-contained website, which went live sometime early-2010 — given the timing it was probably a half-hearted attempt at building up a portfolio of websites. From what I remember someone did approach me in the latter half of 2012 with regards to buying the domain, but since this coincided with my pre-emigration clear-out I did not have the time nor inclination to seriously consider it. Spin forward to this year with my huge clear-out of domain registrations I felt that I either ought to do a better job with the site or simply get rid of it completely, and I predictably chose the latter.

These days a D'Hondt calculator by itself is nothing special and I felt that the configurability of party names and colours was not useful in practice, so I decided to make a pivot to much greater use of pre-set data-sets — most notably for future elections, saving the need for long URLs. An intentional use-case of mine is sending links to other people illustrating different outcomes. Most of the complexity of the site would be managing the preset data-sets rather than the D'Hondt calculation itself, so I felt it worth the investment of ditching PHP in favour of Python — I had already moved the site onto its own server a while back, so the legacy reasons for using PHP no longer applied. I got rid of the downloadable calculators because they were all for Windows and I did not consider it worth the expense of getting the executables signed.

Changes to Django

Last time I used Django was sometime in 2015 so I would have most likely used v1.7, and a lot has changed since then. Django dropped Python 2 support completely with the v2.0 release in December 2017, and in the process they allegedly cleared out a lot of work-arounds such as extensive use of the Six compatibility layer so that the same code could work with both Python 2 and Python 3. Whatever the reasons Django on the whole seems a lot cleaner than what I remembered it being, but a major down-side of this is that trying to use my previous Django projects as references caused more trouble than it solved.

Greater use of built-ins

Django these days seems to make use of basic Python built-ins directly rather than using container objects. For instance when rendering a template, in the past something like this would be used:

def pageAbout(request): template = loader.get_template("about.html") params = { 'title': ' Election results calculator', 'error': None } context = RequestContext(request, params) return HttpResponse( template.render(context) )

Whereas the latest Django requires just a dictionary:

def pageHome(request, strTemplate='home.html'): template = loader.get_template('home.html') context = { 'title': ' Election results calculator', 'error': None } return HttpResponse( template.render(context) )

While this meant that previous Django code I had written had to be dumped on the whole I think this is a good change. When I ported wxLED to Python 3 I noticed that functions tended to return iterators rather than lists, which although made prototyping harder was understandable from a memory consumption stand-point — I have the suspicion that the removal of several Django-specific wrapper classes is in some way related to this change in Python.

Automatic escaping of HTML

By default Django will automatically HTML-escape any strings, including ones that are hard-coded. I found this out the hard way because I initally wanted to be able to specify extra HTML headers in a variable that would be output verbatim. In other words:

context = { extraHeader: '<script> ... </script>' }

..and then in the template:

<head> ... {{ extraHeader }} </head>

In hindsight this probably was not a good way of doing things anyway and I later found out that escaping can be disabled, but it is nevertheless a gotcha.

Using Python 3

The more I read into it the more I am convinced that Python versions 3.0 thru 3.2 were completely botched, most notably by removing the Python 2 u-prefix for Unicode strings, and the subsequent versions 3.3 thru 3.4 were still of questionable usability. I certainly did well to completely ignore Python 3 until this year, because if I tried using any version earlier than 3.5 I most likely would have condemned it as being too dogmatic and flatly refused to look at it again. Instead any evaluation of and move to Python 3 was something that I was putting off rather than avoiding on strong principle. Python 3.6 still has issues but the pain it inflicts is not quite enough to overcome the inertia of switching to a new language.

Whilst the likes of Rust and Go have popped onto my radar over the years, things like the latter making bracing style part of the specification are enough to put me off giving them a proper look. Finally giving up on C++ earlier this year has made me ever more conservative towards to new programming languages — Of all the things I have written in the past it is now only those I wrote using C or Bash that I have much faith in the future support of.

Value of all this

In hindsight Django is rather heavy-weight and something like Flask would have been a better choice. The site does not make any use of Django's database and login facilities, and at a glance the templating sub-system seems pretty similar to the ones Flask uses. At the time I did consider not using a framework at all and instead use WSGI or some other FastCGI-like interface directly, but in the end felt this would be more effort than it was worth. I had already moved the site onto its own server, and the move over to Python from PHP had already relegated efficiency as a major concern —if the latter was not the case I would have used C or C++. On the plus side reimplementing an existing site of's small scale was a good vehicle for getting back up to speed with Django, and given the infrequency which I build websites I feel it better to stick to just one framework. Soon afterwards I started a separate project using Django that did need all the database/admin stuff, so I had less to re-learn on this later project.