Marc 'BlackJack' Rintsch Python, Retrocomputing, and Other Nonsense… en-us Fri, 21 Jan 2022 00:00:00 +0100 <![CDATA[Finally updated software page]]> Finally updated software page

No, not the software itself, that’s still all Python 2. But I finally fixed the links, (long) after Bitbucket stopped hosting Mercurial repositories, from the project pages at Bitbucket. It’s all back to self hosted source archives again.

So the next step would be to port those from Python 2 to Python 3…

Fri, 21 Jan 2022 00:00:00 +0100 <![CDATA[Digits int() doesn’t dig]]> Digits int() doesn’t dig

Some time ago I wrote in More Than Just ASCII Digits about all the unicode characters Python’s int() function converts to numbers.

Recently I’ve discovered a discrepancy between those characters and the isdigit() method — there are characters where isdigit() returns True but int() does not convert them.


Wed, 03 Oct 2018 00:00:00 +0200 <![CDATA[Chasing a dot on a HTML5 canvas]]> Chasing a dot on a HTML5 canvas

A forum question about how to detect a collision of two balls for a school project (in Python) lead me to write my first HTML5 <canvas> element code.

Move the mouse over the square below and try to catch the blue dot with the red one.

Sorry, this needs a browser with <canvas> support.


Sat, 16 Apr 2016 00:00:00 +0200 <![CDATA[More Than Just ASCII Digits]]> More Than Just ASCII Digits

Python’s int() converts more than just ASCII digits. It also converts decimal digits from other scripts.

>>> int('42')
>>> int(u'୨୩')

It’s also possible to mix differnt scripts. int() only cares about the decimal value of each digit character.

>>> int(u'௧౩౩೭')

The following snippet creates CSV data for all digits int() can convert:

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import sys
import unicodedata

def main():
    for i in xrange(sys.maxunicode + 1):
            character = unichr(i)
            value = int(character)
        except ValueError:
                    character, value, i,

if __name__ == '__main__':

And here’s the table generated by that script:


Tue, 08 Mar 2016 00:00:00 +0100 <![CDATA[ version 0.0.2]]> version 0.0.2

A software I use from time to time but a source code I haven’t touched for almost ten years, except for changing some small things when moving from a private Subversion repository to a public Mercurial one hosted at Bitbucket.

There is no new functionality, just updated the code which was written with ancient Python 2.3 in mind. Some modules where deprecated (md5 and sha1), command line handling is now done with argparse, and the Checksums class was replaced by a function because a class with just __init__() and one other method usually isn’t a real class but just a function in disguise. Quite a poor design choice I’ve made ten years ago. :-)

The doc target is gone from the Makefile because epydoc seems to be dead.

Source code can be found at the project’s page at Bitbucket.

Tue, 07 Apr 2015 00:00:00 +0200 <![CDATA[PySensors now under LGPL]]> PySensors now under LGPL

I’ve got an email asking why PySensors, a Python binding to libsensors, is released under the GPL. It was because it was written to use the two latest libsensors APIs (3 and 4) and the shared library for the next to last API version is GPL licensed.

The latest API was introduced in 2010 and the libraries for that are dual licensed: GPL or LGPL. So I decided supporting only the latest API version and relicensing the Python bindings to LGPL.

Removing the code for API 3 made the package much simpler. Before there was the __init__ module wich imports common stuff for both APIs and a sub module for each API version. The api3 module is gone now, and contents of common and api4 moved into the __init__ module.

Changes in package structure (red=deleted, gray=moved):

digraph changes { node [shape=box]; edge [dir=none];  "sensors"; subgraph {     rank=same;      "__init__";     "api3" [color=red];     "api4" [color=gray];     "common" [color=gray];     "cli";     "stdc"; }  "sensors" -> "__init__"; "sensors" -> "api3" [color=red]; "sensors" -> "api4" [color=gray]; "sensors" -> "common" [color=gray]; "sensors" -> "cli"; "sensors" -> "stdc";  "api4" -> "__init__" [color=gray, dir=forward]; "common" -> "__init__" [color=gray, dir=forward]; } ]]>
Tue, 19 Aug 2014 00:00:00 +0200 <![CDATA[ version 0.4.0]]> version 0.4.0

More than nine years passed since I touched the source code of this tool. I still use it on a regular basis and needed/wanted LZMA compression as this has found its way into GNU tar for some time now.

After all this time only Python 2.7 is supported as older 2.x versions are obsolete or at least fading from general use. I feel sorry for the poor souls stuck on CentOS systems. ;-)

Head over to the software page for downloading the tool.

Tue, 29 Apr 2014 00:00:00 +0200 <![CDATA[Table of contents in Tinkerer blogposts]]> Table of contents in Tinkerer blogposts

While upgrading the blog software used for this blog I wanted to fix a problem with table of contents (TOC) within blog posts. Activating a TOC with just this reStructuredText directive:

.. contents::

leads to a problem with the headline of the post on the home page. Because it will already become a local link to the entry in the TOC it won’t work as a link to the posts page anymore. Not even the link to the TOC does work if it is not on the home page because only the introduction part or teaser is displayed there because blog posts with TOC usually tend to be looong posts.

So I opened Issue #23 at the Github project and got the following snipped as workaround:

.. contents::
    :depth: 2

This excludes the title from the TOC leaving it ”free” to use as link to the blog post itself. Thanks to Christian Jann for this solution.

So can you expect more long posts from me in the future? Well there is at least one in the drafts folder, but it still needs some polishing. So don’t hold your breath…

Thu, 12 Sep 2013 00:00:00 +0200 <![CDATA[Pygments highlights CBM BASIC & ca65 assembler sources]]> Pygments highlights CBM BASIC & ca65 assembler sources

Since version 1.6 the syntax highlighter Pygments has support for CBM BASIC V2 and assembler sources in ca65 format. ca65 is the macro assembler of the cc65 C cross compiler package.

The language list does not have entries for them, but the lexer list in the documentation knows about Ca65Lexer in the lexers for assembly languages section and CbmBasicV2Lexer in the lexers for other languages section.


Let’s see the highlighter in action. Both examples solve assignment 3 of the HP Codewars 2012. It is about interpreting a sequence of given Reversi moves and printing the resulting board state.

Example of BASIC…

 10 cp$="w":op$="b":dimb$(7,7):fori=0to7:forj=0to7:b$(i,j)=".":next:next
 20 b$(3,3)="w":b$(4,3)="b":b$(3,4)="b":b$(4,4)="w":dimtx(7),ty(7):goto140
 30 inputl$:ifl$="end"then end
 40 y=asc(left$(l$,1))-asc("a"):x=val(right$(l$,1))-1:b$(y,x)=cp$
 50 forxd=-1to1:foryd=-1to1:if(xd or yd)=0then130
 60 xt=x:yt=y:tc=0
 70 xt=xt+xd:yt=yt+yd
 80 ifxt<0orxt>7oryt<0oryt>7thentc=0:goto120
 90 t$=b$(yt,xt):ift$<>op$then110
100 tx(tc)=xt:ty(tc)=yt:tc=tc+1:goto70
110 ift$<>cp$thentc=0
120 iftc>0then fori=0totc-1:b$(ty(i),tx(i))=cp$:next
130 next:next:t$=cp$:cp$=op$:op$=t$
140 fori=0to7:forj=0to7:printb$(j,i);:next:print:next:print:goto30


Sat, 16 Mar 2013 00:00:00 +0100 <![CDATA[Python – Das umfassende Handbuch]]> Python – Das umfassende Handbuch

Ein kleiner “rant” über Python - Das umfassende Handbuch von GalileoComputing.


Dieser Text bezieht sich auf das OpenBook, also die Version zu Python 2.x. Ob sich in der aktuellen Buchauflage, die Python 3 behandelt, an den angeführten Kritikpunkten etwas geändert hat, kann ich nicht sagen.

Vielleicht ist es ein wenig unfair ein Buch nur nach einem Kapitel zu beurteilen, aber gerade das Thema objektorientierte Programmierung (OOP) bereitet vielen Einsteigern Probleme und in diesem Kapitel versagt das Buch dem Leser pythonisches Programmieren näher zu bringen. Wer Programme im Stil dieses Kapitels abfasst, schwimmt innerhalb der Python-Gemeinschaft gegen den Strom. Teilweise ist das gezeigte nicht nur kein idiomatisches Python, sondern schlicht fehlerhaft. Das Buch, oder zumindest das OOP-Kapitel 12 Objektorientierung, hinterlässt den Eindruck, dass die Autoren Peter Kaiser und Johannes Ernesti ein Thema suchten um Geld mit einem Buch zu verdienen, sich umschauten welche Sprache, zu der es noch relativ wenig deutschsprachige Bücher gibt, sich dazu eignen könnte, und einfach losgelegt haben Wissen und Stil von anderen Sprachen 1:1 auf Python zu übertragen.


Sun, 18 Nov 2012 00:00:00 +0100 <![CDATA[First Post]]> First Post

And here it is — the first post in my new blog. It is easter and I felt my website needs a little „resurrection”. ☺

Blogs are around for some time now, but I still have that old static website which evolves way too slow. To avoid going completely modern and web 2.0 crazy, this blog is a static one. Built with Tinkerer which is based on Python’s documentation tool Sphinx.

I am actually considering moving the content of the old website completely to the blog. Maybe the blog format encourages me to update more often.

Mon, 09 Apr 2012 00:00:00 +0200