Normul normalizes URLs. It expands shortened URLs:

>>> from normul import normul
>>> normul('')
{'type': 'other', 'normalized': '', 'original': ''}

And shows useful links for hosted-images:

>>> normul('')
{'image': {'full': '', 'thumbnail': ''}, 'type': 'image', 'original': '', 'normalized': ''}

You can find the simple but convenient sourcecode here.

Cantor never bores (1)

Given a set of countable sets [tex]K[/tex], such that [tex]K[/tex] is totally ordered by inclusion, videlicet for every [tex]A,B\in K[/tex] either [tex]A\subseteq B[/tex] or [tex]A\supseteq B[/tex]. Intuitively, for at every step in this chain one element at least must be added, one expects the set [tex]K[/tex] to be countable as well.

Suppose [tex]K[/tex] is countable. Then the union, [tex]\bigcup K[/tex] is a countable union of countable sets, hence countable. (Suppose [tex]k: \mathbb N \to K[/tex] is an enumeration of [tex]K[/tex] and [tex]f_i: \mathbb N \to k(i)[/tex] enumerations of the elements of the chain. Then [tex]f_0(0), f_1(0), f_0(1), f_2(0), f_1(1), f_0(2), \ldots[/tex] enumerates [tex]\bigcup K[/tex].)

Thus [tex]\bigcup K[/tex] is an upper bound of [tex]K[/tex]. In the poset of countable subsets of some set [tex]U[/tex], of which [tex]\bigcup K[/tex] is a subset, every non-empty chain has an upper bound. Hence, using Zorn’s lemma there is a maximal element, say [tex]M[/tex].

Suppose [tex]U[/tex] is uncountable, then there exists a [tex]\star \in U \backslash M[/tex]. [tex]M \cup \{\star\}[/tex] is most definitely also countable and [tex]M \subset M \cup \{\star\}[/tex] which contradicts [tex]M[/tex]’s maximality. We are forced to conclude that there exists an uncountable chain of countable sets.

Cantor’s set theory keeps surprising.

Update: an example of such a chain is the set of the countable ordinals.

Another update: a “more concrete” example are the downsets in [tex]\mathbb Q[/tex] without the empty set and [tex]\mathbb Q[/tex] itself. These downsets correspond to real numbers, see Dedekind Cuts.


At the faculty for sciences there are canteens for students. In each of these, there’s sound equipment connected to linux boxes. On each of those linux boxes, we run a music-request-server called Marietje. I just finished writing a front-end in Javascript. It wasn’t a pain. As instead, the use of jQuery was a bliss.

The frontend for one of those boxes and the source code (see the ajax folder).

Damned DOM (1)

When I wanted to react to any changes to a input textbox immediately, my first instrinct was to use onChange. onChange, however, is called when the input loses focus. onKeyPress then? Isn’t called on backspaces. onKeyDown, maybe? It does get called, but the effect of the keystroke isn’t yet applied, for the return value determines whether it that is done in the first place. (Same story for onKeyPress by the way.) onKeyUp does work a bit, except if someone is holding down a single key, for a while.

The solution: hook onKeyUp and use setTimeout with a timeout of 0. Yugh. I hate DOM.

Big Fat Disclaimer: I actually tested this only on one browser.

Unicode to ASCII (1)

When I want to generate usernames from real names, which can contain non-ascii characters, you can’t simply ignore the unicode characters. For instance, is the right e-mail address for Daniëlle, isn’t.

There’s trick. Unicode has got a single code for ë itself, but it has also got a code which (simplified) adds ¨ on top of the previous character. The unicode standard defines a normal form in which (at least) all such characters, which can be, are represented using such modifiers. If you then simply ignore the non-ascii representable codes, you’ll get the desired result.

In python: unicodedata.normalize('NFKD', txt).encode('ASCII', 'ignore').

However, this isn’t the right solution. For instance, in german, one prefers ue as a replacement of ü over u.

Django annoyances: no reverse select_related


for page in Page.objects.all():
  print page.title
  for comment in page.comments.all():
    print comment

There will be a single query to fetch all pages, but there will be for every page another query to fetch its comments. Luckily, Django has got a nice trick up its sleave: select_related. Would I use instead of Page.objects.all(), Page.objects.select_related('comments').all() then Django will use a single joined query to prefetch comments for each page.

However, Django’s select_related only supports forward one-to-many references. No many-to-many; certainly no reverce many-to-many; no reverse one-to-many and no, not even reverse one-to-one (yet). A developer claims it’s impossible (which is bullshit), another asks for patches, which means he doesn’t care doing it himself.

It’s quite easy to manually code around the missing reverse select_related, but it takes too many ugly lines compared to the single word it could’ve been.

On-demand singleton for Python

Some singletons eat slightly more resources, than you want to give them for free. For instance, if you have a home-brew threadpool singleton, you don’t want it to create its threads if you are not going to use it. The solution: a simple function that creates a stub which proxies attribute access to an ad-hoc created instance.

Usage: create_ondemand_singleton('mylibrary.Threadpool', MyThreadPoolClass).