• Wakealarm: Device or resource busy

    The other day I wanted a box doing regular (like, daily) file system backups and really not much else to switch off while idle and then wake up for the next backup. Easy, I thought, install the nvram-wakeup package and that's it.

    Alas, nvram-backup mumbled something about an unsupported BIOS that sounded suspiciously like a lot of work that would benefit almost nobody, as the box in question houses an ancient Supermicro board that's probably not very common any more.

    So, back to the roots. Essentially any x86 box has an rtc that can wake it up, and Linux has had an interface to that forever: Cat a unix timestamp (serialised to a decimal number) into /sys/class/rtc/rtc0/wakealarm, as discussed in the kernel documentation's sysfs-class-rtc file:

    (RW) The time at which the clock will generate a system wakeup event. This is a one shot wakeup event, so must be reset after wake if a daily wakeup is required. Format is seconds since the epoch by default, or if there's a leading +, seconds in the future, or if there is a leading +=, seconds ahead of the current alarm.

    That doesn't tell the full story, though. You see, I could do:

    BACKUP_AT="tomorrow 0:30"
    echo `date '+%s' -d "$BACKUP_AT"` > /sys/class/rtc/rtc0/wakealarm
    

    once, and the box came back, but when I then tried it again, the following happened:

    echo `date '+%s' -d "$BACKUP_AT"` > /sys/class/rtc/rtc0/wakealarm
    bash: echo: write error: Device or resource busy
    

    Echoing anything with + or += did not work either; I have not tried to ascertain why, but suspect that's functionality for more advanced RTC chips.

    Entering the error message into a search engine did bring up a lkml thread from 2007, but on lmkl.iu.edu the thread ends with an open question: How do you disable the wakealarm? Well: the obvious guess of echo "" does not work. My second guess, however, did the trick: You reset the kernel wakealarm by writing a 0 into it:

    echo 0 > /sys/class/rtc/rtc0/wakealarm
    

    – after which it is ready to be written to again.

    And now that I've written this post I notice that the 2007 thread indeed goes on, as on narkive, and a bit further down, Tino summed up this entire article as:

    Please note that you have to disable the old alarm first, if you want
    to set a new alarm. Otherwise, you get an error. Example:
    
    echo 12345 > /sys/class/rtc/rtc0/wakealarm
    echo 0 > /sys/class/rtc/rtc0/wakealarm
    echo 23456 > /sys/class/rtc/rtc0/wakealarm
    

    Ah well. Threading is an important feature in mail clients, even if they're just archives.

  • Stahlhelmdiplomatie

    Was früher Kanonenbootdiplomatie war, hat sich heute offenbar zu Stahlhelmdiplomatie entwickelt. Einerseits, weil „wir“ welche in die Ukraine liefern, statt den Mist, den wir mit unserer Zündelei dort angerichtet haben, etwas zu entspannen. Andererseits, weil die Außenministerin – die „Chefdiplomatin“ also – sich ernsthaft martialisch in den Abendnachrichten zeigt, und zwar sozusagen vor der Haustür des aktuellen Erbfeinds Russland:

    Annalena Baerbock mit Stahlhelm in der Ukraine

    Beschnittener Screenshot aus der Tagesschau vom 8.2.2022: Außenministerin Baerbock beim Staatsbesuch in der Ukraine. Rechte bei der ARD.

    Wer das für Diplomatie hält, glaubt auch an die These von den Schlafwandlern. Was niemand tun sollte. Der erste Weltkrieg ist nicht ausgebrochen, er wurde gemacht. Von einer Öffentlichkeit (ich definiere das jetzt mal nicht näher; weite Teile der Presse gehörten und gehören da auf jeden Fall mal dazu), die Härte, Treue und Verlässlichkeit gefordert hat. Und von einer Regierung, die sich auch auch irgendwas wie vier Jahre in das Gemetzel hinein nicht geschämt hat, die Kriegsrhetorik vom August 1914 auf Wachstrommel zu bellen:

    Na ja, und so sieht es jetzt halt wieder aus. Leider oder zum Glück, so stelle ich gerade fest, depubliziert der DLF seine Presseschauen nach sieben Tagen (trotz allem: Buh!), so dass die übelsten Ausfälle jetzt schon wieder hinter Paywalls verschwunden sind, aber all das Gerede von „nicht zurückweichen“, „klare Kante gegen Russland zeigen“, „der Provokation entgegentreten“, Waffen liefern, Truppen schicken, härter drohen: So schnell kann es gehen zwischen dem zerknirscht-geschichtsklitternden Erinnerungsjahr 2014 und patriotischem Taumel nach der Mode von 1914.

    Dabei ist mir ja schon völlig unklar, was sich all die Russland-EntgegentreterInnen eigentlich als Ausgang der ganzen Angelegenheit vorstellen. Versteht mich nicht falsch: Es ist bestimmt kein Fehler, wenn ein augenscheinlich wirklich an Zauber, Auferstehung und heiligen Krieg glaubender Christ wie Achim Schönbach lieber nicht mehr die Marine befehligt. Aber wer Russland die Krim wieder abnehmen will, wird sich zwischen einer der folgenden Alternativen entscheiden müssen:

    1. Irgendeine russische Regierung gibt sie freiwillig ab. Die Frage beiseite, was sie dazu bewegen könnte, es wäre wohl das letzte, was sie täte. Weder das Militär noch große Teile der Bevölkerung würden das hinnehmen – das wäre nach übereinstimmenden Angaben von osteuropäischen KollegInnen und Ex-Studis in etwa so, als würde die BRD Mallorca, Helgoland und Sylt an Serbien übergeben. Also, so richtig, mit: Kein Urlaub mehr dort für Deutsche. Diese Alternative existiert mithin eigentlich nicht, und es bleiben realistisch nur die beiden anderen.
    2. Irgendwie zwingen „wir“ Russland ohne Krieg zur Aufgabe der Krim. Die Folge wäre ein Revanchismus in Russland, der garantiert die Größenordnung des Revanchismus in der Weimarer Republik angesichts von Versailles erreichen würde. Das wäre nicht nur für Russland furchtbar; mit Sicherheit wären damit alle Hoffnungen auf Ausgleich für die nächsten 30 Jahre futsch. Es gäbe auch praktisch sicher eine wild drehende Aufrüstungsspirale. Wer könnte es einer Bevölkerung, die mindestens ebenso patriotisch betaumelt ist wie „unsere“ verdenken, Russland nach so einer Nummer so stärken zu wollen, dass es eine solche Schmach nicht nochmal hinnehmen müsste? Gut, ich kann das, weil es klar durchgeknallt ist. Aber es ist nicht durchgeknallter das das, was „wir“ im Augenblick aufführen.
    3. Wir machen mal wieder einen Krimkrieg, weil der letzte so ein Höhepunkt der Zivilisation war. Tut euch den Gefallen und blättert ein wenig im verlinkten Wikipedia-Artikel. Wer sowas ernsthaft will, möge erstmal die wunderbaren Thursday Next-Bücher von Japer Fforde lesen – Hauptperson ist eine Veteranin eines in einer Alternate History eingefrorenen Krimkriegs – und sich danach bitte schleunigst auf den Weg zurück in Kreise zivilisierter Menschen begeben.

    Alle drei Alternativen sind offensichtlich Quatsch. Nichts davon ist auch nur im Entferntesten wünschbar. Mit welchen Gedanken im Kopf kann sich also irgendwer darüber erregen, wenn irgendwer anders – und sei es auch ein frömmelnder Marinechef – das Offensichtliche feststellt: Chruschtschows Laune von 1954, als er die Krim an die Ukraine übergab, war nie mehr als das, eine Laune (eines Diktators, Autokraten, oder wie immer das heute heißt, zumal) nämlich, und gewiss nichts, für das irgendwer sterben sollte.

  • Werkstattbericht: Kohlendioxid auf dem Balkon

    Im November hatte ich mich gefragt, was wohl die recht deutlichen Spitzen der CO₂-Konzentration auf meinem Balkon verursachen mag, die sich da immer mal wieder zeigen. Um Antworten zu finden, habe ich seit Ende Dezember eine längere Messreihe laufen lassen und derweil vierstündlich Windrichtungen von der Open Weathermap aufgenommen. Das, so hoffte ich, sollte zeigen, woher der Wind weht, wenn die Konzentration auffällige Spitzen hat.

    Leider gibt ein schlichter optischer Vergleich von Konzentration (oben) und Windrichtung (unten; hier als Cosinus, damit das Umschlagen von 0 auf 360 Grad nicht so hässlich aussieht) nicht viel her:

    Zwei unterbrochene Kurven, die jeweils recht munter vor sich hinwackeln

    CO₂-Konzentration auf meinem Balkon und Windrichtung für Heidelberg aus der Open Weathermap zwischen Ende Dezember 2021 und Anfang Februar 2022. Die Lücken ergeben sich aus fehlenden Daten zur Windrichtung.

    Tatsächlich hilft es ein wenig, wenn mensch das anders plottet. Unten bespreche ich kurz das Programm, das Wind- und CO₂-Daten zusammenbringt. Dieses Programm produziert auch folgenden Plot in Polarkoordinaten:

    Scatterplot in Polarkoordinaten: Im Wesentlichen ein oranger Ring

    CO₂-Konzentration auf meinem Balkon gegen meteorologische Windrichtung (also: Herkunft des Windes, hier gezählt ab Nord über Ost, so dass das orientiert ist wie eine Landkarte) und farbkodierte Windgeschwindigkeit (in Meter pro Sekunde). Das ist ein PNG und kein SVG, weil da doch viele Punkte drauf sind und Browser mit so großen SVGs immer noch ins Schlingern kommen.

    Ich hatte mich seit einem Monat auf diesen Plot gefreut, weil ich erwartet habe, darin eine ordentliche „Beule“ zu sehen dort, wo die CO₂-Emission herkommt. Gemessen daran ist wirkliche Ergebnis eher ernüchternd. Dort, wo ich die Abgasfahne des Großkraftwerk Mannheim sehen würde, etwas unterhalb der 270°-Linie, ist allenfalls ein kleines Signälchen und jedenfalls nichts, was ich wirklich ernst nehmen würde.

    Etwas deutlicher zeichnet sich etwas zwischen 280 und 305 Grad ab, also Westnordwest. Das könnte die Ladenburger Chemieindustrie oder die BASF in Ludwigshafen sein; zu letzterer haben die kritischen Aktionäre im letzten Jahr angesagt, sie emittiere als Konzern 20 Megatonnen Kohlendioxid im Jahr. Wenn, was nicht unplausibel ist, die Hälfte davon am Standort Ludwigshafen anfällt, würden sich diese 10 Mt ganz gut vergleichen mit den 8 Mt, die ich neulich fürs Großkraftwerk gefunden hatte – die Abschätzung von dort, so eine Abgasfahne könne durchaus die Konzentrationsspitzen erklären, kommt also auch für die BASF hin. Allerdings wird deren Emission angesichts des riesigen Werksgeländes natürlich auch verteilter sein…

    Also: Überzeugend ist das alles nicht. Ein anderes Feature ist jedoch schlagend, wegen weniger Übermalung – die bei beiden Plots ein echtes Problem ist; nächstes Mal muss ich mit halbtransparenten Punkten arbeiten – noch mehr, wenn ich den Polarplot „ausrolle“, also den Winkel von unten nach oben laufen lasse:

    Scatterplot kartesisch: ein starker dunkler Klops bei 230 Grad

    In dieser Darstellung fällt ins Auge, dass die CO₂-Konzentration bei starken (dunkle Töne) Südwest- (um die 225°) -strömungen recht drastisch fällt. Das passt sehr gut zu meinen Erwartungen: Südwestwind schafft hier in der Rheinebene Luft durch die Burgundische Pforte, hinter der im Mittelmeerraum auch jetzt im Winter eifrig Photosynthese stattfindet. Wer drauf aufpasst, sieht die Entsprechungen auch im Polarplot von oben, in dem dann sogar auffällt, dass reiner Südwind gelegentlich noch besser photosynthetisierte Luft heranführt, auch wenn der Wind nicht ganz so stark bläst.

    Demgegenüber ist mir eigentlich alles, was sich im nordöstlichen Quadranten des Polarplots (und hier zwischen 0 und 90 Grad) abspielt, eher rätselhaft. Der doppelseitige Sporn bei genau 90 Grad ist vermutlich auf Datenmüll der Wetterstation zurückzuführen: Wahrscheinlich hat die einen Bias, der bei wenig Wind diese 90 Grad ausspuckt. Selbst nach meiner Interpolation (vgl. unten) ist das noch zu ahnen, wenn mensch die Verteilung der Geschwindigkeiten insgesamt (in rot) und die der Geschwindigkeiten rund um einen auffälligen Hügel rund um 90° Windrichtung herum (in blau) ansieht:

    Zwei Histogramme über Geschwindigkeiten, bei dem das blaue nur im linken Bereich ist

    Die elegante Schleife, die von (0, 500) über (70, 540) nach (90, 510) führt und die im Polarplot ganz alleine außen vor sich hinläuft, dürfte ziemlich sicher teils physikalisch sein. Dass das da so einen Ring macht, dürfte zwar ein Artefakt meiner gewagten Interpolation sein (vgl. Technics). Der Anstieg als solcher und wohl auch die grobe Verortung dürften aber ganz gut hinkommen. Sieht mensch sich das im zeitlichen Verlauf an, entspricht die Schleife der höchsten Spitze in der ganzen Zeitreihe.

    Nur leider ist im Nordosten von meinem Balkon nicht mehr viel: Ein paar Dutzend Häuser und dann der Odenwald, also für fast 10 km nur Bäume. Na gut, und ein Ausflugsrestaurant.

    Die aus meiner Sicht plausibelste Interpretation für diese Stelle basiert auf der Beobachtung, dass in der fraglichen Zeit (am 10.1.) wenig Wind wehte, die Temperaturen aber ziemlich niedrig lagen. Vielleicht schauen wir hier wirklich auf die Heizungen der Umgebung? Der Schlot unserer lokalen Gemeinschafts-Gasheizung ist in der Tat so in etwa im Nordosten des Balkons – und vielleicht wurde ja sonst nicht so viel geheizt?

    Technics

    Die wesentliche Schwierigkeit in diesem Fall war, dass ich viel engmaschiger CO₂-Konzentrationen (alle paar Minuten) habe als Windrichtungen (bestenfalls alle vier Stunden), und zudem viele Windrichtungen aus welchen Gründen auch immer (offensichtlich wäre etwa: zu wenig Wind) fehlen. Auf der positiven Seite erzeugt mein Open Weathermap-Harvester weathercheck.py eine SQLite-Datenbank, so dass ich, wenn es nicht furchtbar schnell gehen muss, recht bequem interessante Anfragen laufen lassen kann.

    Mein Grundgedanke war, die beiden einem CO₂-Wert nächsten Wind-Werte zu bekommen und dann linear zu interpolieren[1]. Das ist schon deshalb attraktiv, weil die Zeit (als Sekunden seit 1.1.1970) als Primärschlüssel der Tablle deklariert ist und deshalb ohnehin ein Index darauf liegt.

    Dabei sind aber je nach Datenverfügbarkeit ein Haufen Fälle zu unterscheiden, was zu hässlichen if-else-Ketten führt:

    def get_for_time(self, time, col_name, default=None):
      res = list(self.conn.execute(f"SELECT timestamp, {col_name} FROM climate"
        " WHERE TIMESTAMP BETWEEN ? AND ?"
        " ORDER BY ABS(timestamp-?) LIMIT 2",
        (time-40000, time+40000, time)))
    
      if len(res)!=2:
        if default is not None:
          return default
        raise ValueError(f"No data points close to {time}")
    
      elif abs(res[0][0]-time)<200 and res[0][1] is not None:
        return res[0][1]
    
      elif res[0][1] is None or res[1][1] is None:
        if default is not None:
          return default
        raise ValueError("One or more limits missing.  Cannot interpolate.")
    
      else:
        t1, v1 = res[0]
        t2, v2 = res[1]
        return (v1*(t2-time)+v2*(time-t1))/(t2-t1)
    

    Die Fallunterscheidung ist:

    1. Es gibt überhaupt keine Daten innerhalb von einem halben Tag. Dann kann ich nur einen Fehler werfen; zumindest in unseren Breiten sind Windrichtungen eigentlich schon über kürzere Zeiträume hinweg nur lose korreliert.
    2. Innerhalb von 200 Sekunden der gesuchten Zeit gibt es einen tatsächlichen Messwert, und dieser ist nicht NULL. Dann gebe ich den direkt zurück.
    3. Einer der beiden Werte, die um die gesuchte Zeit herum liegen, fehlt (also ist NULL). Dann kann ich nicht interpolieren und muss wieder einen Fehler werfen. Hier wäre es nicht viel unplausibler als die Interpolation, wenn ich einfach einen nicht-NULL-Wert nehmen würde; aber es wäre doch nochmal ein Stückchen spekulativer.
    4. Ansonsten mache ich einfach eine lineare Interpolation.

    NULL-Werte machen die Dinge immer komplex. Aber wenn ihr euch überlegt, wie viel Stress sowas ohne SQL wäre, ist das, finde ich, immer noch ganz elegant. Im echten Code kommt noch etwas Zusatzkomplexität dazu, weil ich Winkel interpolieren will und dabei immer die Frage ist, wie mensch die Identität von 360 und 0 Grad einrührt.

    Eine vorsorgliche Warnung: aus der Art, wie ich den Spaltennamen hier reinfummele, folgt, dass, wer den Parameter kontrolliert, beliebiges SQL ausführen kann. Sprich: wer diesen Code irgendwie Web-zugänglich macht, darf keine unvalidierte Eingabe in col_name reinlassen.

    Eingestandenermaßen ist diese Sorte von datenbankbasierter Interpolation nicht furchtbar effizient, aber für die 100000 Punkte, die ich im Augenblick plotten will, reicht es. Siehe: Den Code.

    [1]Klar: Windrichtungen über Stunden linear zu interpolieren ist in den meisten Wetterlagen eher zweifelhaft. So, wie ich meine Plots mache, ist es aber nicht wesentlich verschieden davon, die Punkte über den Bereich zu verschmieren. Das wiederum wäre konzeptionell gar nicht so arg falsch.
  • Antisprache: Innovation, Teil 1

    Foto: Jede Menge Autofelgen

    Alufelgen für Autos: Ist das Innovation oder kann das weg?

    Mag „Chancengleichheit“ auch der Klassiker der Antisprache sein: „Innovation“ verdient jedenfalls einen Großpreis fürs Lebenswerk. Der Grundtrick dabei ist, menschenfeindlichen Quatsch gegen Kritik zu immunisieren, indem er als neu und schon von daher nützlich und gut – das ist der antisprachliche Subtext der „Innovation“ – hingeredet wird. Kritisiert dennoch jemand, kann im Wesentlichen jeder Mumpitz verteidigt werden mit dem Argument, ewig Gestrige hätten ja schon das Rad oder das Buch oder Antibiotika verdammt.

    Das ist Antisprache, denn natürlich ist es vernünftig, bei irgendwelchen Plänen oder Techniken erstmal zu überlegen, ob sie überhaupt einem nachvollziehbarem Zweck dienen könnten und dann, ob dieser Zweck in einem irgendwie erträglichen Verhältnis zum Dreck steht, den das Zeug macht. Dass es gelegentlich wirklich nützliche Erfindungen gibt (Rad, Buch, Antibiotika, LED-Scheinwerfer am Fahrrad), bedeutet nicht, dass solche Überlegungen irgendwie rückwärtsgewandt sind. Im Gegenteil. Ohne sie bekommen wir noch regelmäßiger Mist wie, sagen wir, Stuttgart 21 oder gar die Autogesellschaft. Ich gebe zu, dass „Technikfolgenabschätzung“ klingt wie ein sonnengebleichter Bürokratenfurz. Aber es ist trotzdem keine schlechte Idee.

    Demgegenüber kann „Innovation” auf eine etwas befremdliche Weise durchaus unterhaltsam werden, etwa wenn mit ernstem Gesicht so offensichtlich absurdes Zeug vorgetragen wird, dass ich den Verdacht von Kommunikationsguerilla kaum vermeiden kann. Ein gutes Beispiel für diese Kategorie (vielleicht unfreiwillig) kenntlicher Antisprache war Teil der CES-Berichterstattung in Forschung aktuell vom 8. Januar.

    Darin versucht Mary Barra, Vorstand von General Motors, ab Minute 4:20 ihr „softwaredefiniertes“ Auto mit folgenden Beispielen schmackhaft zu machen (Übersetzung DLF):

    Das macht es Kunden möglich, die Software ihres Fahrzeuges zu aktualisieren und neue Inhalte drahtlos herunterzuladen. [...] Die Technik ermöglicht es beispielsweise, eine Softwareoption herunterzuladen, um die Beschleunigung des Fahrzeugs zu erhöhen.

    Wow. Die Updateritis muss, wenn mein weiteres soziales Umfeld nicht komplett exotisch ist, so in etwa der unpopulärste Aspekt der „Digitalisierung“ überhaupt sein. Das zu ermöglichen (und damit: zu verlangen, denn was ins Netz kann, muss für rasche Bugfixe geplant werden) soll jetzt ein Argument sein, sich eine „Innovation“ einzutreten?

    Der zweite Teil von Barras Sales Pitch ist eigentlich noch wilder: GM hat ja meine Sympathie, wenn es seine Fahrzeuge per Computer runterregelt. Aber so offen zugeben, dass sie planen, künstlich verschlechterten Kram zu verkaufen – denn mal ehrlich: solange mensch keinen neuen Motor runterladen kann, sind die Extra-PS, die ein Download liefern kann, in einem bereits ab Werk ordentlich designten System eher dürftig –, um obendrauf den KundInnen Freischaltungen für Krempel anzudrehen, den sie eigentlich schon bezahlt haben: das ist schon stark.

    Hätte Frau Barra das in einem Beichtstuhl gesagt, hätte ihr nach so offenen Bekenntnissen Absolution erteilt. Wenn sie hinreichend viel Reue gezeigt hätte.

  • Inlining xs:include in XML Schema

    Screenshot: Fragmented XSD schema

    Please don't do it like this: for users of a schema, having to pull it in a dozen fragments is just pain and no gain. See below for a program that lets you heal this particular disease.

    While I'm a big fan of XML – which is governed by a very well-written standard and is (DTDs aside) about as easy to process as something context-free can be –, I have always been a lot more skeptical about XML Schema, which is horrendously complex, has a few nasty misfeatures[1] and generally has had a major role in giving XML a bad name.

    But well, it's there, and it won't go away. That ought to be reason enough to not encumber it with further and totally avoidable pain. As, for instance, splitting up a single schema into fragments of a couple of lines and then using xs:include liberally to re-assemble the fragments at the client side. Datacite, I'm looking at you. Regrettably, they're not the only ones doing that. And as opposed to splitting a domain mapping into different schemas – which might improve re-usability, this lexical splitting really helps nobody except perhaps the authors.

    The use of xs:include is a pain in particular when one tries to implement redistributable validators, as these then need to keep a lot of files in a defined hierarchy. Just pointing to the vendor's site is not an option, because the software would hit that every time it validates something, which is, if nothing else, a privacy and stability problem.

    Well, today I had another case of XSD splititis, and this time it was bad enough that I decided to merge the fragments. I had expected people had written “inliners” expanding xs:include in XSDs into standalone XSDs. After all, it's basically a lexical thing (well, excepting namespace mappings and perhaps re-indentation). Five minutes of operating a search engine didn't bring up anything, though, and so I wrote a quick cure: expand-xsd-include.py.

    I'll be the first to admit that it is a hack at this point, mainly because I blindly discard the root tags for the included documents. That's wrong because these might add or, worse, change the mapping from prefixes to XML namespaces. In its current state, this will fail badly if included documents use different or extra mappings and declare them in the root element; declarations further down are ok.

    Another problem resulting from keeping namespace processing off on the parser is that I hardcode the prefix for the XSD schema to xs. If your schema uses something else, change XSD_PREFIX in the script.

    Mending these deficiencies wouldn't be an undue effort, and if you have XSDs that need it, let me know and I'll do proper namespace processing. Or perhaps, in addition, teach the thing to pull the input files via http. Meanwhile, I suspect that the large majority of atomised XSDs can be merged with this code, and so I thought I might as well put it online in its slightly embarrassing shape.

    Let me know if you use it. And if you distribute fragmented XSDs: Why not use the script to assemble your XSD before publishing it?

    [1]The worst XSD misfeature IMHO are the namespaced attribute values; where XML has been designed to be parsable without external DTDs (ok, not generally, but under well-defined conditions, and it's been a long time since I saw a document that didn't meet those), parsing results with namespaced attribute values depend on whether or not the parser knows the XSD. And that would even be bad without the ugly schemaLocation hacks in both schema and schema instance.
  • Relevante Personalien

    Demo-Foto: Schild "Solidarität mit Florida-Rolf" und eine GEW-Fahne

    Eine regierungskritische Studidemo 2003 in Frankfurt: „Solidarität mit Florida-Rolf“ klingt lustig, war aber eine beißende Kritik an Durchsetzung von Sozialabbau mittels populistischer Hetze, die damals (und zumindest noch in die ersten Hartz-Gesetze hinein) ein die Bildzeitung, Rot-Grün und die DGB-Spitze einschließender Mainstream war.

    Hatte ich mich gestern noch lustig gemacht darüber, dass Personalien derzeit in den Nachrichten vor heißen Corona-Stories laufen, lese ich heute von einer, die ich doch weit vorn in eine Nachrichtensendung gesetzt hätte: Wenn nicht noch ein Wunder geschieht, wird Yasmin Fahimi neue Vorsitzende des DGB.

    Nun ist es (nicht nur) in Gewerkschaften ganz normal, dass sich mit jeder Hierarchiebene die zahmen, karriereorientierten, konservativen Personen anreichern[1]. Die Causa Fahimi ist jedoch so extrem, dass die taz zu loben ist für die Platzierung von Anja Krügers treffendem Kommentar auf der ersten Seite der taz vom Donnerstag. Auch ich als mäßig aktives GEW-Mitglied kann diese Geschichte allenfalls mit einer guten Lupe von einer schleichenden Selbstentleibung des DGB zu unterscheiden.

    Dass die IG BCE, innerhalb des DGB an reaktionärer Gesinnung nur noch von der Gewerkschaft der Polizei überboten, jetzt nochmal den DGB-Vorsitz übernimmt, und dann noch mit einer rechten SPDlerin, das ist ein offener Affront gegen alle, die in den Gewerkschaften eine Wiederholung der Katastrophe von 2002 verhindern wollen. Damals hielten die DGB-Gewerkschaften weitgehend ruhig, als Rot-Grün einen auch im Rückblick atemberaubenden Abbau von sozialen Rechten und Möglichkeiten betrieb, mit absehbaren Folgen für die Motivation der Mitgliedschaft wie auch die politische Orientierung von Menschen, die eigentlich gewerkschaftlich organisiert sein müssten und jetzt stattdessen AfD wählen (ich habe dafür immer noch keine bessere Umschreibung gefunden als „Turkeys voting for Christmas“).

    Ein vergleichbarer Angriff auf soziale Rechte wird vermutlich auch von der gegenwärtigen Regierung kommen. Dochdoch, es gibt schon noch einiges zu demontieren in den Überresten des Sozialstaats. Wenn der DGB im Kampf gegen diese Demontagen mit dem Gesicht einer SPD-Jasagerin dasteht, ist das der Königsweg. In die Irrelevanz.

    Und das ist auch dann keine gute Nachricht für die Einzelgewerkschaften, wenn in denen bereits jetzt meist nur Augenrollen kommt, wenn wieder Leute für irgendwelche DGB-Gremien gesucht werden. So hatte sich Joe Hill die O.B.U. nicht vorgestellt.

    [1]Vgl. auch Schurken und Engel. Entgegen dem dort simulierten Konkurrenzprinzip kann ich im Gewerkschaftsfall aber aus erster Hand berichten, dass die Reproduktion des Schurkigkeitsgradienten im Wesentlichen durch eine Art Kooptation passiert, bei der jeweils in der höheren Ebene arbeitende FunktionärInnen sich ihren Nachwuchs sorgfältig und listenreich aus den niedrigeren Ebenen handverlesen und dabei Menschen präferieren, deren Politikverständnis nicht zu weit von dem ihren abliegt. Diese Personen dann auch durchzusetzen ist einfach, weil verständlicherweise kaum mehr jemand Lust hat auf Gewerkschaftsarbeit, also alle froh sind, wenn sich überhaupt irgendwer findet.
  • SARS-2 ist in etwa fertig

    Ich beobachte derzeit fasziniert die Reihenfolge der Beiträge in Nachrichtensendungen. Wir haben Corona-Zahlen, die noch vor zwei Monaten helle Panik ausgelöst hätten – 200000 gemeldete Neuinfektionen am Tag, eine bundesweite 7-Tages Inzidenz über einem Prozent –, und entsprechende Meldungen kommen zumindest bei ARD und DLF, wenn überhaupt, weit hinter Mumpitz wie der Frage, ob wohl ein Herr Merz oder ein Herr Brinkhaus der CDU-Fraktion im Bundestag vorsitzen wird (mal ehrlich: Wer wirds merken?).

    Aber vielleicht ist das auch besser so; denn auch wenn sich das derzeitige Tempo wahrscheinlich noch nicht durchhalten lässt, wenn sich die Altersverteilung der Infizierten nach oben verschiebt, mag es sein, dass es ohne grobe Notbremsen gerade jetzt geht, und wenn der nächste Winter halbwegs normal laufen soll, sollten wir auch gar nicht so arg einbremsen (und auch nicht im Interesse der 70-Jährigen).

    Gestern allerdings hätte es eine spektakuläre Nachricht gegeben, die ich ganz vorne in meine Sendung gepackt hätte, wenn ich Redakteur wäre: Mit Omikron ist SARS-2 in gewissem Sinn fertig. Woher ich das weiß? Nun, meine Lieblingsrubrik im RKI-Wochenbericht kommt schon seit langem von der Arbeitsgemeinschaft Influenza (AGI; ich hatte die schon mal zitiert), die Woche um Woche berichtet, was so umgeht an Erregern von Atemwegserkrankungen. Im Bericht von gestern findet sich das auf Seite 14, und da steht:

    In der virologischen Surveillance der AGI wurden in KW 3/2022 in insgesamt 66 von 112 eingesandten Proben (59 %) respiratorische Viren identifiziert. Darunter befanden sich 23 Proben mit SARS-CoV-2 (21 %), 15 mit humanen saisonalen Coronaviren (hCoV) (13 %), zwölf mit Rhinoviren (11 %), elf mit humanen Metapneumoviren (10 %), jeweils drei Proben mit Parainfluenzaviren (3 %) bzw. mit Respiratorischen Synzytialviren (RSV) (3 %) sowie eine Probe mit Influenzaviren (1 %).

    Das ist spektakulär, weil, wenn ich nichts übersehen habe, nie zuvor während der ganzen Pandemie SARS-2 in den Infektionszahlen unsere gewohnten humanen Coronaviren überholt hat.

    Und es heißt ziemlich sicher: SARS-2 ist jetzt bis auf einen kleinen Faktor so gut an den Menschen angepasst, wie das Coronaviren halt können – die anderen vier hatten ja schon mindestens hundert Jahre Zeit für ihre Optimierung (der jüngste könnte seit 1889 umgehen; zumindest vermuten viele Leute, die Russische Grippe könne die letzte wirklich tödliche Coronapandemie vor SARS-2 gewesen sein), und wenn SARS-2 in deren Liga aufgestiegen ist, wird es wohl keine weltbewegenden Erfindungen mehr machen können; in diesem Sinne wäre es, na ja, „fertig“.

    Mensch könnte spekulieren, SARS-2 könne einen Vorteil haben, weil es für die meisten Menschen hier immer noch neu ist, während sie die anderen vier schon aus dem Kindergarten kennen. Per Bauchgefühl bezweifele ich den Vorteil allerdings, denn die vielen Geimpften – und niemand ist gegen eines der anderen Coronaviren geimpft – machen es SARS-2 vermutlich ziemlich ähnlich schwer wie die vorhergegangenen Infektionen den anderen.

    Zum Schluss nochmal Fanpost an die AGI: Ich halte das für hochrelevante Forschung mit minimalem Eingriff in die Privatsphäre von Kranken, small data im besten Sinn (wobei ich zugebe, dass mir das noch besser gefallen würde, wenn das Sample etwas größer wäre; in Zeiten wie diesen sollten sich doch 500 bis 1000 Proben finden). In meiner Fantasie sind die AGI-Leute und ihre Sentinelpraxen so wie die Waldläufer im Herrn der Ringe, die durch die Wildnis ums Auenland streichen und, ohne dass es viele merken, die Augen offen halten. Helden!

  • Wes Brot ich ess…

    Ein schrumpeliger Apfel

    Würdest du diesen Apfel in einem Supermarkt kaufen? Geht nicht mehr. Ich habe ihn vorhin gegessen. Also: Das, was Wurm und Balkonlagerung davon übrig gelassen haben. Auf der anderen Seite dürfte das Ding einen Behandlungsindex um die Null gehabt haben – siehe unten.

    Neulich hat die Parteistiftung der Grünen, die Böll-Stiftung, einen Pestizidatlas herausgegeben, eine Sammlung von Infografiken und Karten über den Einsatz von Giften aller Art in der Landwirtschaft. Wie üblich bei diesen Atlanten, haben sie das dankenswerterweise unter CC-BY publiziert, und besser noch: Die Sachen sind auch ohne Javascript leicht zugänglich[1].

    Ich hatte mir davon einige Kopfzahlen erhofft, denn ich habe wirklich kein gutes Gefühl dafür, was so an Giften auf den Feldern (und Weinbergen!) in meiner Umgebung landet und was das bedeutet. In der Hinsicht hatte ich kein Glück. Im Atlas gibts zwar haufenweise Zahlen, aber wirklich überzeugen konnten mich nur wenige, oft genug, weil sie letztlich Metriken ohne Bedeutung sind. Ein gutes Beispiel für diese Kategorie ist die Masse der Agrochemikalen (verwendet z.B. auf S. 11, S. 15, S. 44), die wohl als Proxy für „Umfang des Gifteinsatzes“ stehen soll.

    Das halte ich für profund fehlerhaft. Neonikotinoide, Glyphosat und DDT (um mal ein paar Pole aufzumachen) sind in spezifischer Giftigkeit, Wirkprofilen, Umweltauswirkungen, Kinetik und eigentlich jeder anderen Hinsicht fast völlig verschieden voneinander. „Eine Tonne Pestizid“ sagt daher so gut wie nichts aus. Obendrauf kommt noch ein kleiner Faktor Unsicherheit, ob sich die Masse auf Wirkstoffe, fertige Rezepturen oder irgendwas dazwischen bezieht, aber das wird wohl in diesem Geschäft kaum mehr als einen kleinen Faktor ausmachen – verglichen mit dem Grundproblem (in dem wir vermutlich über Faktoren von einigen tausend sprechen) wohl vernachlässigbar.

    Ähnlich schwerwiegende Einwände hätte ich zur breiten Mehrheit der Zahlen in dem Atlas: Vage beeindruckend, aber immer ein gutes Stück unterhalb der Schwelle von Wohlfundiertheit und allgemeinen Anwendbarkeit, die ein paar Ziffern zu einer Orientierung gebenden Kopfzahl machen könnten.

    Es gibt jedoch auch ohne schlagende Zahlen von werkübergreifender Bedeutung einige Einsichten, die wertvoll sind, so etwa auf S. 33 die Bankrotterklärung der Idee, durch grüne Gentechnik den Pestizideinsatz zu reduzieren. In Brasilien, wo transgene Pflanzen die Landwirschaft vollständig dominieren, sind 2019 47% mehr Pestizide ausgebracht worden als 2009. Gut: Soja (darauf schaut der Rest der Grafik, und das wird wohl auch den Pestizidverbrauch dominieren) ist in diesem Zusammenhang ein schlechtes Beispiel, denn das populäre transgene Soja („Roundup ready“) ist ja gerade designt, um große Mengen Herbizide zu überleben. Dazu sind wieder blind Massen angegeben, und die angesichts galloppierender Rodungen in Brasilien vermutlich rasch wachsende Anbaufläche wäre eigentlich auch noch einzurechnen, wenn die Zahlen einen analytischen Blick erlauben wollten.

    Aussagekräftiger wären für die behandelte Frage Zahlen für Mais gewesen (nämlich den mit der Bt-Abwehr gegen den Maiszünsler) und folglich auch Insektizide beim Mais. Aber seis drum: Die Grafik zeigt auch ohne methodische Strenge, dass es so nicht weiter gehen kann.

    A propos Mais: Dass der mit recht wenig Chemie auskommt, hat mich schon verblüfft:

    Mit "Schlechte Nachrichten für Apfel-Fans" überschriebene Grafik

    Grafik von Seite 14 des Pestizidatlasses. Die Caption im Atlas deutet an, dass der „Behandlungsindex“ etwas wie die mittlere Anzahl von Anwendungen von Pflanzenschutzmitteln ist; ob das wirklich so ist: Wer weiß? CC-BY Pestizidatlas

    Dass Wein heftig pflanzengeschützt wird, ist hier in der Gegend unübersehbar. Bei Hopfen und Äpfeln überrascht es mich aber, denn hiesige Apfelbäume in Streulagen, um die sich im Wesentlichen niemand kümmert, liefern durchaus sehr essbare Äpfel; hinreichend viele und große, um mir den ganzen Winter über die Basis für mein Frühstücksmüsli zu liefern (das Foto oben zeigt den von heute).

    Klar haben fast alle Hautdefekte, und in vielen wohnte auch mal ein Wurm – aber das tut ihrer Essbarkeit wirklich keinen Abbruch. Aus dieser Erfahrung heraus hätte ich erwartet, dass schon mit recht moderaten Interventionen supermarktkompatible Äpfel erreichbar wären. Das stimmt offenbar so nicht. Die letzten 50% zum makellosen Produkt – und wahrscheinlich auch die Spalierzucht in Monokultur – scheinen Äpfel von einer ganz einfachen zu einer ganz heikelen Kultur zu verwandeln.

    Meine Lieblingsgrafik ist schließich auf Seite 39:

    Eine Kopfzahl gibt auch das nicht her. Als Beleg für das alte Motto „Wes Brot ich ess, des Lied ich sing“ kann das aber durchaus durchgehen. Und als Illustration dafür, wie problematisch es ist, Wissenschaft – wie wir das in unserer Drittmittelkultur nun mal tun – über Geld zu regulieren.

    [1]Na ja, blöderweise ist ohne Javascript so ein doofes animiertes GIF neben jedem Ding, das runtergeladen werden kann. Tipp an die WebseitenmacherInnen: Wenn ihr diese Sorte Gimmick schon braucht, stattet ihn doch wenigstens mit einem display: none im CSS aus. Per Javascript könnt ihr das display-Attribut dann nach Bedarf konfigurieren. Nettoeffekt: UAs ohne JS (aber mit elementarem CSS) sehen keine blinkenden Trümmer.
  • PSA: Grobe Schnitzer beim Trauern

    Gestern um halb eins ist in Heidelberg ein Mann in einen Uni-Hörsaal gelaufen und hat mit einem Gewehr eine Frau erschossen, ist danach wieder rausgegangen und sich irgendwie selbst mit seiner Waffe umgebracht So ein Geschehen in einem Hörsaal, in dem ich vor vielen Jahren auch mal „Mathematische Methoden der Physik“ gehört habe, überhaupt, Leute mit Gewehren im botanischen Garten, in dem ich auch regelmäßig rumlaufe: Das lässt mich natürlich nicht kalt.

    Den bundesweiten Aufschrei, der folgte, finde ich allerdings angesichts der Wurstigkeit, wenn etwa Menschen überfahren werden, sich ohne Ballerei umbringen oder auf der Straße an genereller Verwahrlosung sterben, ziemlich unangemessen. Ich will mich jedenfalls nicht hinstellen und entscheiden, welcher Tod „überflüssiger“ oder „entsetzlicher“ war.

    Zum Glück muss ich das nicht. Ich könnte dazu den Mund halten. Der Rektor der Uni Heidelberg, das will ich gerne zugestehen, kann sich diesen Luxus nicht erlauben. Und so hat er rund fünf Stunden nach dem Ereignis eine Art Trauermail über den uniweiten Verteiler verschicken lassen. Es ist diese, die mich zu diesem Public Service Advisory bringt, denn der Rektor hat zwei Dinge getan, die in solchen Trauermails wirklich niemand haben will:

    1. Die Thoughts-And-Prayers-Phrase verwendet („Das Rektorat ist in Sorge um die Opfer und in Gedanken bei ihnen, ihren Freunden und Angehörigen”). Mal ehrlich: alle wissen, dass die Gedanken eines Rektorats, in dessen Uni gerade ein riesiger Polizei- und Presseauflauf stattfindet, überall sein werden, aber fast sicher nicht bei Freunden und Angehörigen von Opfern. Das ist wahrscheinlich noch nicht mal schlimm, denn die Betreffenden hätten auch dann nichts von diesen Gedanken (zum Glück hat das Rektorat auf „Gebete“ verzichtet), wenn sie bei ihnen wären. Klar ist ein wenig Lügen zum Trost erlaubt, aber bitte nicht mit einer Phrase, die so abgedroschen ist, dass sie sogar für Memes verbrannt ist.
    2. Die Mail von der Adresse kum@uni-heidelberg.de abgeschickt (ok, ich kann nicht genau sagen, ob das der Absender war, denn die Liste hat die Header weitgehend umgeschrieben, aber das Reply-to ist kum@). Kum wie „Kommunikation und Marketing“. Die Nachricht ist: Das ist ein Problem für unser Marketing, und da müssen wir mit Kommunikation Schaden begrenzen. Niemand erwartet, dass der Rektor Mail an rektor@ oder vielleicht eitel@ selbst liest – aber es würde die ganze Nachricht doch ein wenig authentischer wirken lassen, hätte er einen dieser Absender verwendet.

    Nun: Was mensch zum ersten Mal macht, vermurkst mensch. Hoffen wir, dass das Rektorat keine Übung in dieser Sorte Prosa bekommen muss.

  • Geschichte: Carl Benz bei Wilhelm I

    Schlechte Fotomontage: Ein Benz-Portrait in einer Versailles-Spiegelsaal-Variante

    Die Audienz des Herrn Benz (in weißer Uniform) wurde auch im Bild festgehalten.

    Bei Recherchen im Deutschen Nationalarchiv bin ich auf eine Mitschrift einer Art Ansprache – heute würde das wohl sales pitch genannt werden – gestoßen, die Dr. Carl Benz, Mannheim, Eigentümer der dortigen Fabrik für Maschinen zur Blechbearbeitung, gelegentlich einer Audienz bei Kaiser Wilhelm I am 23. Mai 1880 gehalten haben soll. Ich habe sie abgetippt und orthographisch aktualisiert:

    Hochgeehrte kaiserliche Majestät, allerdurchlauchtigste, großmächtigste, allergnädiste Hohheit etc pp,

    Erlaubt mir, Carl Friedrich Michael Benz, Absolvent der polytechnischen Hochschule zu Karlsruhe, Euch untertänigst einen Vorschlag zu unterbreiten, welcher einen ebenso ernsten wie drängenden Missstand aus der Welt zu schaffen verspricht. Namentlich sind nicht nur die Straßen der Hauptstadt Ihro Reiches verunziert von den Hinterlassenschaften zahlloser Rösser. Nein, diese sind in allen Städten wie Dörfern in Ihro Obhut ein beständiges Ärgernis, zu schweigen von den Gefahren, die von ihnen für das öffentliche Wohlbefinden ausgehen. So vergeht wohl kein Tag, ohne dass sich ein tapferer Offizier seine tadellose Uniform durch einen unbedachten Schritt, gar ein unwürdiges Ausrutschen, besudelt mit dem kreatürlichen Schmutz.

    Es wird Zeit, dieses Ärgernis aus der Welt zu schaffen. Ich bin dazu in der Lage, und zwar mittels meines patentierten pferdelosen Wagens, kurz, meines Motorwagens. Er vermag Menschen mit großer Geschwindigkeit zu bewegen, ohne dass dazu Pferde oder anderweitig die Straßen verunreinigende Tiere benötigt würden. Wird es erst genug von meinen Wagen geben, wird unser gütiger Herrscher Seine Städte nicht mehr wiedererkennen.

    Um diesen großen Schritt zur höheren Kultivierung des deutschen Volkes, ja, ich will der Hoffnung Ausdruck geben, der Völker des ganzen Erdenkreises, zu tun, werden nur einige kleine Erweise von Gunst und Gnade nötig sein, abgesehen von einer unbedeutenden Zuwendung aus der Privatschatulle Eurer Majestät. Zuvorderst müssten Majestät einige Aufwendungen für den Ausbau des Straßennetzes veranlassen.

    Natürlich werden meine Wagen gewisse gesetzliche Privilegien benötigen. Ihnen ist die Hälfte des Straßenraums für ihre Bewegung zu reservieren. Der Aufenthalt von Personen muss dort verboten werden. Vielleicht kann ihnen an einzelnen Stellen per Lichtzeichen das gelegentliche Betreten der Straßen Ihro Majestät kurzfristig gestattet werden. Ein weiteres Drittel der Wege und Plätze werden Ihro Untertanen nicht mehr betreten können, da ja die Motorwagen zu akkomodieren sind, während sie nicht fahren. Ich erwarte zuversichtlich, dass dem Gesinde auch nach diesen Anpassungen von Gesetz und Gebrauch hinreichend Raum verbleiben wird und es den kaiserlichen Privilegien für meine Motorwagen freudig und ohne Murren folgen wird.

    Ich erwähne beläufig, dass Jahr um Jahr einige tausend Flaneure und auch Insassen der Motorwagen bei allfälligen Kollisionen sterben werden. Unter den Überlebenden wird es fraglos zahlreiche Beschädigte geben, die, so steht zu befürchten, dem Ruhm des Vaterlandes nicht mehr im gewohnten Maße werden dienen können. Ich habe weiter überschlagen, dass einige weitere Zehntausende an feinem Staub und anderen Miasmen der Motorwagen zugrunde gehen werden, und noch einmal so viele an Lärm und dergleichen. Nun: Auch Pferde töten Menschen. Und fraglos sind dies sehr überschaubare Opfer im Vergleich zum reichlichen Nutzen und Gewinn, da unsere wunderbaren Städte von den dampfenden Hinterlassenschaften der Pferde befreit werden.

    Ohne die Errungenschaft unnötig profanisieren zu wollen, darf ich in aller Kürze anmerken, dass meine Erfindung auch den Geldfluss in Ihro Gnaden Imperium beflügeln wird, da das fleißige Volk ein rundes Siebtel mehr wird arbeiten müssen für die Freude und Gnade, einen Motorwagen besitzen und bewegen zu dürfen. Ich kann indes bereits jetzt versprechen, dass sie das gerne tun werden, dass sie im Gegenteil heftig ringen werden dafür, mehr arbeiten zu müssen. Genauso werden sie ganz aus eigenem Willen ihre Kinder nicht mehr auf der Straße spielen lassen. Dies wird nicht nur das Unwesen der sprichwörtlichen Straßenjungen zu einem Ende bringen, es werden so auch weniger junge, vielleicht hoffnungsvolle Talente unter den Rädern meiner Motorwagen zermalmt.

    Um diese kleinen Preise können Ihro Untertanen dann täglich eine oder zwei Stunden in ihren Blechkäfigen verbringen und mit großer Anspannung durch Glasscheiben auf andere Untertanen blicken, die zumeist ebenfalls in Blechkäfigen dahinrasen. Es wird viel Ärger und Hader sein zwischen den Männern in ihren Käfigen, was gewiss überaus förderlich sein wird zur Ertüchtigung des Volkes im Wettstreit der Nationen und zur Vertiefung der Liebe des Volkes zu Ihro Majestät. Manchmal werden sie auch gar nicht dahinrasen, sondern in ihren Käfigen hintereinander stehen, ohne zu wissen warum. Auch das werden sie willig hinnehmen, denn sie werden wissen: Der große Kaiser hat uns erlöst vom Pferdemist.

    Es könnte sein, dass dieses Dokument nicht ganz authentisch ist, denn Forschungs- und Industrieförderung im heutigen Sinn hat es damals noch nicht gegeben. Außerdem hat Benz wahrscheinlich nicht genau kommen sehen, was seine Erfindung in der Welt anrichten würde. Denn auch wenn er wohl kein sehr netter Mensch war, er hätte es andernfalls hoffentlich gelassen.

    In Wahrheit wird es wie so oft gewesen sein: Die allerabsurdesten Dinge haben sich in langen Entscheidungsketten entwickelt, in denen jede einzelne Entscheidung zumindest nachvollziehbar ist. Es hat ja niemand ahnen können, dass am Schluss etwas rauskommt wie unsere Autogesellschaft.

  • Explaining Tags in Pelican

    Right after I had celebrated the first anniversary of this blog with the post on my Pelican setup, I decided to write another plugin I've been planning to write for a while: taginfo.py.

    Nachtrag (2022-10-07)

    Don't take it from here; rather, see https://codeberg.org/AnselmF/pelican-ext

    This is for:

    Blog screenshot

    that is, including explanations in on pages for tags, telling people what the tag is supposed to mean.

    To use taginfo, put the file into your plugins folder, add taginfo to the PLUGINS list in your pelicanconf.py, and then create a folder taginfo next to your content folder. In there, for each tag you want to comment, create a file <tagname>.rstx (or just rst). Such a file has to contain reStructuredText, where pelican's extensions (e.g., {filename} links) do not work (yet). I suppose it wouldn't be hard to support them; if you're interested in this plugin, feel free to poke me in case you'd like to see the extra pelican markup.

    To make the descriptions visible, you need to change your tag.html template (typically in theme/templates/tag.html) in order to arrange for tag.make_description() to be callsed when rendering the document. Me, I'm doing it like this:

    {% block content_title %}
    <h1>Tag <em>{{ tag }}</em></h1>
    <div id="taginfo">
            {{ tag.make_description() }}
    </div>
    {% endblock %}
    

    (And I still find jinja templates exceptionally ugly).

  • How I'm Using Pelican

    I started this blog on January 14th last year. To celebrate the anniversary, I thought I could show how I'm using pelican (the blog engine I'm using); perhaps it'll help other people using it or some other static blog generator.

    Posting and Writing

    First, I structure my content subdirectory (for now) such that each article has the ISO-formatted date as its name, which makes that source name rather predictable (for linking using pelican's {filename} replacement), short, and gives the natural sort order sensible semantics.

    Also, I want to start each post from a template, and so among the first things I did was write a little script to automate name generation and template instantiation. Over the past year, that script has evolved into post.py3.

    Nachtrag (2022-03-15)

    I've changed a few things in the meantime; in particular, I am now opening a web browser because I got tired of hunting for the URI when it was scrolled off the screen before I first had something to open, and to make that work smoothly, I'm building the new post right after creating its source.

    It sits next to pelican's Makefile and is in the blog's version control. With this, starting this post looked like this:

    $ ./post.py3 "How I'm Using Pelican"
    http://blog/how-i-m-using-pelican.html
    remake.sh output/how-i-m-using-pelican.html
    

    Nachtrag (2022-05-26)

    The output is now a bit different, and now I do open the browser window – see below.

    What the thing printed is the URL the article will be seen under (I've considered using the webbrowser module to automatically open it, but for me just pasting the URL into my “permanent” blog browser window works better). The second line gives a command to build the document for review. This remake.sh script has seen a bit of experimentation while I tried to make the specification of what to remake more flexible. I've stopped that, and now it's just:

    #!/bin/bash
    pelican --write-selected "$1"
    

    When you add:

    CACHE_CONTENT = True
    LOAD_CONTENT_CACHE = True
    CONTENT_CACHING_LAYER = 'generator'
    

    to your pelicanconf.py, rebuilding just the current article should be relatively quick (about 1 s on my box). Since I like to proofread on the formatted document, that's rather important to me.

    Nachtrag (2022-05-26)

    N…no. This part I'm now doing very differently. See Quick RST Previews.

    If you look at post.py3's code, you will see that it also fixes the article's slug, i.e., the path part of the URL. I left this to Pelican for a while, but it annoyed me that even minor changes to a blog title would change the article's URI (and hence also the remake statment). I was frankly tempted to not bother having elements of the title in the slug at all, as I consider this practice SEO, and I am a fanatical enemy of SEO. But then I figured producing shorter URIs isn't worth that much, in particular when I'd like them to be unique and easy to pronounce. In the end I kept the title-based slugs.

    The script also picks the local file name as per the above consideration with some disambiguation if there's multiple posts on one day (which has only happened once in the past year). Finally, the script arranges for adding the new post to the version control system. Frankly, from where I stand now, I'd say I had overestimated the utility of git for blogging. But then, a git init is cheap, and who knows when that history may become useful.

    I'm not using pelican's draft feature. I experimented with it for a while, but I found it's a complication that's not worth anything given I'm always finishing a post before starting the next. That means that what otherwise would be the transition from draft to published for me is the make install. The big advantage of starting with status:published is that under normal circumstances, an article never changes its URI.

    Local Server Config and Media

    Another pelican feature I'm not using is attaching static files. I have experimented with that initially, but when the first larger binary files came in, I realised they really shouldn't be under version control. Also, I never managed to work out a smooth and non-confusing way to have pelican copy these files predictably anyway.

    What I ended up doing is have an unversioned, web-published directory that contains all non-article (“media”) files. On my local box, that's in /var/www/blog-media, and to keep a bit of order in there, the files sit in per-year subdirectories (you'll spot that in the link to the script above). The blog directory with the sources and the built documents, on the other hand, is within my home. To assemble all this, I have an /etc/apache2/sites-enabled/007-blog.conf containing:

    <VirtualHost *:80>
      ServerName blog
      DocumentRoot /home/anselm/blog/output
    
      Alias /media /var/www/blog-media
    
      ProxyPass /bin/ http://localhost:6070/
    
      <Directory "/home/anselm/blog/output">
        AllowOverride None
        Options Indexes FollowSymLinks
        Require all granted
      </Directory>
    
      <Directory ~ "/\.git">
        Require all denied
      </Directory>
    </VirtualHost>
    

    which needs something like:

    127.0.0.1 localhost blog
    

    in your /etc/hosts so the system knows what the ServerName means. The ProxyPass statement in there is for CGIs, which of course apache could do itself; more on this in some future post. And I'm blocking the access to git histories for now (which do exist in my media directory) because I consider them fairly personal data.

    Deployment

    Nachtrag (2022-07-10)

    I'm now doing this quite a bit differently because I have decided the procedure described here is a waste of bandwidth (which matters when all you have is GPRS). See Maintaining Static Blogs Using git push.

    When I'm happy with a post, I remake the whole site and push it to the publishing box (called sosa here). I have added an install target to pelican's Makefile for that:

    install: publish
      rsync --exclude .xapian_db -av output/ sosa:/var/blog/generated/
      rsync -av /var/www/blog-media/ sosa:/var/blog/media/
      ssh sosa "BLOG_DIR=/var/blog/generated/ /var/blog/media/cgi/blogsearch"
    

    As you can see, on the target machine there's a directory /var/blog belonging to me, and I'm putting the text content into the generated and the media files into the media subdirectory. The exclude option to the rsync and the call to blogsearch is related to my local search: I don't want the local index on the published site so I don't have to worry about keeping it current locally, and the call to blogsearch updates the index after the upload.

    The publication site uses nginx rather than apache. Its configuration (/etc/nginx/sites-enabled/blog.conf) looks like this (TLS config removed):

    server {
      include snippets/acme.conf;
      listen 80;
      server_name blog.tfiu.de;
    
      location / {
        root /var/blog/generated/;
      }
    
      location /media/ {
        alias /var/blog/media/;
      }
    
      location /bin/ {
        proxy_pass http://localhost:6070;
        proxy_set_header Host $host;
      }
    
      location ~ \.git/ {
        deny all;
      }
    }
    

    – again, the clause for /bin is related to local search and other scripting.

    Extensions

    Nachtrag (2022-10-07)

    Don't take the code from here; rather, see https://codeberg.org/AnselmF/pelican-ext

    In addition to my local search engine discussed elsewhere, I have also written two pelican plugins. I have not yet tried to get them into pelican's plugin collection because… well, because of the usual mixture of doubts. Words of encouragement will certainly help to overcome them.

    For one, again related to searching, it's articlemtime.py. This is just a few lines making sure the time stamps on the formatted articles match those of their input files. That is very desirable to limit re-indexing to just the changed articles. It might also have advantages for, for instance, external search engines or havesters working with the HTTP if-modified-since header; but then these won't see changes in the non-article material on the respective pages (e.g., the tag cloud). Whether or not that is an advantage I can't tell.

    Links to blog posts

    The citedby plugin in action: These are the articles that cite this post right now.

    The other custom extension I wrote when working on something like the third post in total, planning to revisit it later since it has obvious shortcomings. However, it has been good enough so far, and rather than doing it properly and then writing a post of it own, I'm now mentioning it here. It's citedby.py, and it adds links to later articles citing an article. I think this was known as a pingback in the Great Days of Blogs, though this is just within the site; whatever the name, I consider this kind of thing eminently useful when reading an old post, as figuring out how whatever was discussed unfolded later is half of your average story.

    The way I'm currently doing it is admittedly not ideal. Essentially, I'm keeping a litte sqlite database with the cited-citing pairs. This is populated when writing the articles (and pulls the information from the rendered HTML, which perhaps is a bit insane, too). This means, however, that a newly-made link will only …

  • Variable Inflation

    Relativ parallel verlaufende Kurven

    Dieser Artikel hat nach langen Windungen leider keine Pointe. Und zwar im Wesentlichen wegen dieser Grafik, generiert vom Rechner für die persönliche Inflationsrate des statistischen Bundesamts. Siehe unten.

    Ich fletsche hier ja regelmäßig die Zähne in Richtung von allerlei Metriken, also Zahlen, die (meist) Unmessbares messen sollen und damit in aller Regel Politiken rechtfertigen, die schlecht sind für die, bei denen diese ankommen.

    Der ganz große Klassiker im Metrik-Geschäft ist das Bruttosozial- oder -inlandsprodukt (BSP bzw. BIP), dessen Wachstum im allgemeinen Bewusstsein als Synonym für wachsenden Wohlstand gilt, zumal in seiner Form als BIP pro Kopf. In Wirklichkeit versucht die Metrik zu messen, wie viele „Waren und Dienstleistungen“ (womit es schon losgeht: was ist das?) „hergestellt“ (realistisch: verkauft) werden, und zwar von StaatsbürgerInnen (BSP) oder innerhalb der Staatsgrenzen (BIP).

    Das Bruttosozialprodukt und der Krieg

    Dass das BIP wesentlich mit Wohlstand korreliert sei, ist offensichtlich falsch – selbst die Produktion von Wohlstandsvernichtern wie Autos und anderen Waffen erhöht das BIP –, und das wurde auch schon breit kritisiert. Der entsprechende Abschnitt in der Wikipedia ist nach Maßstäben diese Genres eher zahm.

    Diese Klarstellung im Hinblick auf Wohlstand ist wichtig, aber etwas unfair, denn, a propos Waffen: Historisch sollte das BSP das mit dem Wohlstand gar nicht machen. Besonders aufschlussreich in der Hinsicht fand ich einen Artikel in der taz vom 2.5.2015, der daran erinnerte, dass sich das BSP in seiner heutigen Form vom Gottseibeiuns der Marktradikalen, John Maynard Keynes, in einem Artikel mit dem sprechenden Namen How to Pay for the War ersonnen wurde und sich letztlich als Metrik der wirtschaftlichen Kriegsfähigkeit durchgesetzt hat. Die taz-Autorin Ulrike Herrmann implizierte 2015, dass das BSP dafür offenbar taugte, denn es hat ja die Keynes-Seite gewonnen – mehr kann mensch von einer Metrik nicht erwarten.

    Ich selbst glaube zwar nicht, dass BSP-Rechnungen auf Seiten der Nazis irgendwas am Kriegsverlauf geändert hätten, aber für meinen nächsten Gedanken will ich trotzdem mal annehmen, das BSP sei im zweiten Weltkrieg eine kriegsnützliche Metrik gewesen. Von dort aus möchte ich behaupten, dass es unter Bedingungen weitgehender reproduktiver Selbstbestimmung allenfalls noch sehr kurzfristig für die Bewertung der Kriegsfähigkeit taugt. Solange sich nämlich in Kriegen immer noch in erster Linie junge Leute (statt, sagen wir, Roboter) erschießen, braucht es für deren Führung hinreichend Nachwuchs. Den immer noch dominierenden Modus der Reproduktion, unbezahlte Arbeit von Müttern an ihren Kindern, erfasst das BIP jedoch nicht.

    Als das Konzept entstand, war die Vorstellung klarerweise, dass Frauen ganz von selbst Kinder kriegen und aufziehen. Das stimmt nicht mehr, und daher wäre mein Rat an die BIP-MacherInnen: Wenn euer BIP weiter wie gehabt funktionieren soll, müsst ihr auch die Herstellung von Kindern verrechnen.

    Tatsächlich wäre es überhaupt kein Stilbruch, sowas irgendwie ins BIP reinzufummeln. Denn natürlich weiß niemand, wie viel wirklich verkauft oder gar hergestellt (denkt an all die handgestrickten Babysachen, von denen keine Statistikbehörde je erfahren wird) wird, und die Grenze zwischen Ware und Nicht-Ware ist ziemlich beliebig. Gewiss, das Steueraufkommen ist ein brauchbarer Indikator, aber mehr eben nicht. Viele Variablen liegen zwischen dem und irgendwelchen Gesamtproduktions- oder Einkommensziffern. Auch auf der legalen Seite der Demarkationslinie zur Schwarzarbeit passiert viel Austausch, ohne dass davon irgendwer etwas mitbekommt.

    Mit solchen Gedanken im Kopf habe ich vor einiger Zeit GDP: A Brief but Affectionate History von Diane Coyle (Princeton 2014; gibts bei der Imperial Library of Trantor) mit viel Interesse gelesen. Darin geht es zum Beispiel um die Beliebigkeiten in den BIP-Berechnungen (englisch Gross Domestic Product oder GDP) – der Klappentext erwähnt Ausschläge von 60% über Nacht für Ghana –, ebenso wie über die historischen Diskussionen, was alles zum „Volkseinkommen“ gehören soll: Kriegsausgaben? Staatsausgaben überhaupt? Gesundheitsausgaben? Oder in dem Bereich vielleicht nur Pillen, nicht aber die Arbeit von ÄrztInnen? „Dienstleistungen“ (was immer das ist) an sich, und wenn ja, wie bewertet?

    Dennoch: Kopfzahlen

    Die tatsächlichen Regeln für die Berechnung von BIP-artigen Metriken sind also im Gegensatz zur munteren Betrachtung in der Wikipedia in weiten Bereichen biegsam. Zwar mag eine genaue und ehrliche Zweckbestimmung helfen, die eben aufgeworfenen Fragen, sagen wir, intersubjektiv zu beantworten, aber letztlich ist das Konvention, und selbst für das BIP in der Keynes-Definition ist da viel zu vereinbaren. Die international offenbar populärste Konvention stellt Coyle vor, namentlich das System of National Accounts, das sich in den vergangenen siebzig Jahren von fünfzig auf 722 Seiten aufgebläht hat.

    Das allerdings schafft schon wieder Beliebigkeit. Aus meiner Erfahrung mit 50-seitigen Standards, für die nach einer Weile Validator-Programme verfügbar wurden (und zeigten, dass notdürftig funktionsfähig aussehende Dienste voll mit Fehlern waren), kann ich zuversichtlich sagen: Solange es keinen rechnergestützten Validator gibt (und das ist hier bis zur Erfindung starker KI eigentlich undenkbar), sind 722 Seiten voll Regeln so gut wie überhaupt keine Regeln: Das System ist fast sicher in sich höchst widersprüchlich, und auch mit dem besten Willen (der nur bei wenigen Statistikbehörden und Ministerien vorausgesetzt werden darf) werden Menschen ständig Fehler machen.

    Wie auch immer: Als Kopfzahl ist es ja vielleicht trotzdem ganz nützlich zu wissen, dass das BIP der BRD laut IWF 2019 knapp 4 Billionen Dollar betrug, das der USA etwas über 20 Billionen Dollar und das eines ordentlichen und großen Trikontstaats wie z.B. Nigeria 500 Milliarden Dollar. Sicher sind diese verschiedenen Dollars nicht annähernd vergleichbar, aber die Zahlen taugen doch für schnelle Überschlagsrechnungen, wenn verkündet wird, der Börsenwert von Apple sei jetzt, was, zwei Billionen Dollar (etwa: die AktionärInnen von Apple könnten für ein halbes Jahr die BRD leerkaufen und Nigeria für vier Jahre), oder wenn die Frage ist, wie viel der Bund mit einem Bundeshaushalt von (außerhalb von Corona) 350 Milliarden Euro an „den Märkten“ reißen kann – natürlich immer mit der Maßgabe, dass über Messfehler, Umrechnungen, Inflationsanpassung und so fort da schnell ein Faktor zwei dabei ist.

    Persönliche Inflation

    Der größte Unsicherheitsfaktor innerhalb der Serie einer Behörde wird wahrscheinlich die Inflationsanpassung sein, angefangen dabei, ob sie vorgenommen wurde oder nicht. Erstens ist sie ein exponentieller Effekt. Nehmen wir mal an, dass die Inflationsrate im Schnitt bei den 2% pro Jahr liegt, die diverse Zentralbanken gerne hätten, und dass sie tatsächlich ein Maß ist, wie viel mensch so kaufen kann. Nach der Königsformel „Verdoppelungszeit ist 75 Zeiteinheiten[1] durch prozentuale Rate“, liegen inflationsbereinigte und rohe BIPs schon nach 37 Jahren um einen Faktor zwei auseinander.

    Nun liefert aber auch eine Bereinigung um Inflation und Währungseffekte kaum Zahlen, die mit Erfahrungen von Konsummöglichkeiten korrelieren. Seht etwa die nach PPP bereinigten historischen Vergleichswerte zum BIP an: Es ist abwegig, dass sich irgendeine Sorte von „gefühltem“ Konsum für der BRD zwischen 1990 und 2019 von 1437 auf 4672 Milliarden Äquivalent-Euro verdreifacht haben soll. Wer damals schon gelebt hat, wird sich erinnern, dass sich – abgesehen davon, dass es noch keine SUVs und nur wenig Mobiltelefone gab – das allgemeine Konsumniveau hier im Land nicht wesentlich geändert hat.

    Zweitens also ist die Inflation selbst eine wacklige Größe, womit ich endlich zum Link komme, der mich zur vorliegenden Diatribe inspiriert hat, weil ich ihn verkopfzahlen wollte: Labournet berichtet, dass rund die Hälfte der 8.4 Millionen MieterInnen in deutschen Großstädten mehr als 30% ihres Einkommens für Miete augeben müssen. Das fand ich schon für sich relevant, ich wollte aber vor allem den Punkt machen, dass solche Leute bei explodierenden Mietpreisen eine weit höhere Inflation haben werden als Menschen, die keine Miete zahlen müssen.

    Da VermieterInnen in der Regel eher reich und MieterInnen in der Regel eher arm sind, bedeuten Mieten, die stärker steigen als die Inflation, eine Art kalte Umverteilung von unten nach oben bei gegebenem BIP (ob pro Kopf oder anders). Die Inflationsschätzung basiert ja auf einem Warenkorb, den das statistische Bundesamt (Destatis) zusammenstellt, und wenn Leute viel mehr für Miete ausgeben als im Warenkorb repräsentiert und die Mieten viel stärker steigen als die Preise im Rest des Warenkorbs, ist ihre „persönliche Inflation“ viel höher als die Zahl aus den Nachrichten. Die BIP-pro-Kopf-Metrik nicht nur wegen ungleicher Einkommensverteilung zweifelhaft, sondern auch, weil sie obendrauf noch eine innere Kaufkraftkorrektur bräuchte.

    Das hatte ich nun auf der Basis der rasant steigenden Mieten illustrieren wollen und habe auf den Seiten des Statistischen Bundesamts herumgestöbert, um mein Gefühl zu erhärten, dass Mieten weit über der Inflation steigen. Das Gefühl hat seine Grundlage in meinem persönlichen WG-Zimmer-Index für Heidelberg. Ausweislich durchschnittlicher Aushänge würde ich für 1990 den mittleren Kurs etwa bei 150 Euro sehen, inzwischen eher bei 500 Euro (unter Annahme der DM-Euro-Konversion von 2001). Die Mieten hätten sich also in dreißig Jahren also gut verdreifacht, was einer Verdopplungszeit von 18 Jahren oder einer jährlichen Inflation von 75/18, also 4% entspricht; die berichtete Inflation lag in der Zeit von kurzen Phasen abgesehen jedoch deutlich unter 2 Prozent.

    Nun, es stellt sich raus: Das Konzept der je nach sozialer Schicht verschiedenen Inflationsrate illustriert das Amt selbst recht schön und bietet sogar einen Rechner für die persönliche Inflationsrate an – Kompliment an dieser Stelle dafür, dass da ein SVG-Download angeboten wird (wie überhaupt die Webseite den Eindruck hinterlässt, dass hier Leuten mit Verstand und Spaß bei der Sache relativ freie Hand gelassen …

  • Joe Hills Asche und die bessere Zukunft

    „I dreamed I saw Joe Hill last night, alive as you and me“ – so fängt ein Klassiker des Arbeiterlieds an, der mich spätestens bei „And smiling with his eyes,/ says Joe, what they could never kill/ went on to organize“ immer sehr ergriffen hat, auch in seinen Aktualisierungen wie etwa I dreamed I saw Judi Bari last night von David Rovics.

    Was ich nicht wusste: In das Bewusstsein der (halbwegs) modernen Linken hat das Lied Joan Baez gebracht, als sie es beim Woodstock Festival aufführte. Trivia? Klar. Noch viel mehr davon habe ich gestern gehört, als der Deutschlandfunk-Freistil vom 12.12.2021 („Die Asche von Joe Hill”) in meinem asynchronen Radio drankam.

    Diese Sendung hätte ich offen gestanden als außerhalb der Grenzen des öffentlich-rechtlichen Rundfunks liegend eingeschätzt. Einerseits, weil es um grenzwertig kannibalistische Praktiken geht – allerdings stark grotesk-gutgelaunte (lest zumindest mal die Zusammenfassung). Das ist nicht anders zu erwarten, da Abbie Hoffman im Spiel ist, der schon mal als Angeklagter in Richterroben auflief, sich mit dem Stinkefinger vereidigen ließ und wesentlichen Anteil hatte, dass um ein Haar ein Schwein US-Präsidentschaftskandidat (statt des heute zu Recht vergessenen Hubert Humphrey) geworden wäre.

    Andererseits finde ich die Sendung doch recht DLF-mutig, weil sie am Ende schon nachgerade revolutionär wird. Schon die Beschreibung der blutigen Repression gegen die Wobblies in den USA bereitet auf klare Worte vor:

    Mit dem Eintritt der USA in den ersten Weltkrieg erlebten die Wobblies eine brutale Verfolgung. Sie wurden als unpatriotisch gebrandmarkt [ich hoffe doch: zu Recht!], viele wurden verhaftet, einige gelyncht, manche verließen das Land.

    Dies ist natürlich auch eine Erinnerung daran, dass es schlicht keine größere Katastrophe gibt als Kriege und es wirklich Zeit wird, auch im Interesse des liberalen Rechtsstaats endlich Schluss zu machen mit all dem Militärquatsch.

    Vor allem aber schließt der Film mit der Sorte revolutionärem Optimismus, der mir in der derzeitigen radikalen Linken eigentlich fast überall fehlt. Ich mache ja die generelle Miesepetrigkeit, Coolness und Belehrsucht in unseren Kreisen schon etwas mitverantwortlich dafür, dass „konservative“ bis faschistische Gedanken in erstaunlich vielen Studihirnen (und, schlimmer noch, unter weniger Privilegierten) Raum greifen.

    Wie viel hoffnungsvoller klingt, womit Otis Gibbs die HörerInnen aus der Sendung entlässt (Übersetzung des DLF; das Original, wo ich es hören kann, scheint mir noch eine Spur ergreifender):

    Ich habe ein sehr gutes Gefühl, was die Zukunft angeht, und ich denke, es ist nur eine Frage der Zeit, bis sehr gute Sachen in Amerika passieren. Jetzt lastet noch eine Dunkelheit auf uns allen, und ich spüre sie wie jedeR andere auch. Aber ich treffe auch Menschen, die einem Mut machen, und sie sind alle jung. Sie sind Idealisten. Wir müssen nur diese schreckliche Zeit, in der wir leben, überleben, bis die jungen Leute das Ruder übernehmen und die Welt zu einem viel besseren Ort machen.

    So ganz von selbst wird das wohl nicht gehen, aber es ist jedenfalls der viel bessere Ansatz als… na ja, wie ich gerade damit zu hadern, dass unser schnarchiger DGB beängstigend nahe dran ist an der One Big Union, die Joe Hill und die Wobblies mal im Sinn hatten. Jaja, ich hadere ja schon nicht mehr.

  • Replacing root-tail when there is a compositor

    Since there hasn't been real snow around here this year until right this morning, I've been running xsnow off and on recently[1]. And that made me feel the lack of a compositor on my everyday desktop. Certainly, drop shadows and fading windows aren't all that necessary, but I've been using a compositor on the big screen at work for about a decade now, and there are times when the extra visual cues are nice. More importantly, the indispensable xcowsay only has peudo-transparency when there's no compositor ever since it moved to gtk-3 (i.e., in Debian bullseye).

    Well: enough is enough. So, I'm now running picom in my normal desktop sessions (which are managed by sawfish).

    Another near-indispensable part of my desktop is that the syslog is shown in a part of the root window (a.k.a. desktop background), somewhat like this:

    Windows, and a green syslog in the background

    This was enabled by the nice program root-tail for ages, but alas, it does not play well with compositors. It claims its --windowed flag does provide a workaround, but at least for me that failed in rather crazy ways (e.g., ghosts of windows were left behind). I figured that might be hard to fix and thought about an alternative. Given compositors are great for making things transparent: well, perhaps I can replace root-tail with a heavily customised terminal?

    The answer: essentially, yes.

    My terminal program is unicode-rxvt. In the presence of a compositor, you can configure it for a transparent background by telling it to not use its pseudo-transparency (+tr), telling it to use an X visual with an alpha channel (-depth 32) and then using a background colour with the desired opacity prefixed in square brackets. For a completely transparent terminal, that is:

    urxvt -depth 32 +tr -bg "[0]#000000"
    

    This still has the scrollbar sticking out, which for my tail -f-like application I don't want; a +sb turns it off. Also, I'm having black characters in my terminals by default, which really doesn't work with a transparent background. Making them green looks techy, and it even becomes readable when I'm making the background 33% opaque black:

    urxvt -depth 32 +tr +sb -bg "[33]#000000" -fg green
    

    To replace root-tail, I have to execute my tail -f, put the window into the corner and choose a somewhat funky font. To simply let me reference the whole package from startup files, I'm putting all that into a shell script, and to avoid having the shell linger around, all that this script does is call an exec (yes, for interactive use this probably would be an alias):

    #!/bin/sh
    exec /usr/bin/urxvt -title "syslog-on-root" +sb \
            +tr -depth 32 -bg "[33]#000000" -g 83x25-0-0 \
            -fg green -fn "xft:monofur-11:weight=black" \
            -e tail -f /var/log/syslog
    

    This already looks pretty much as it should, except that it's a normal window with frames and all, and worse, when alt-tabbing through the windows, it will come up, and it will also pollute my window list.

    All that needs to be fixed by the window manager, which is why I gave the window a (hopefully unique) title and then configured sawfish (sawfish-config, “Window Rules”) to make windows with that name depth 16, fixed-position, fixed-size, sticky, never-focus, cycle-skip, window-list-skip, task-list-skip, ignore-stacking-requests. I think one could effect about the same with a judicious use of wmctrl – if you rig that up, be sure to let me know, as I give you it would be nice to make that part a bit more independent of the window manager.

    There's one thing where this falls short of root-tail: Clicks into this are not clicks into the root window. That hurts me because I have root menus, and it might hurt other people because they have desktop icons. On the other hand, I can now mouse-select from the syslog, which is kind of nice, too. Let's see.

    [1]Well, really: Mainly because I'm silly.
  • Ach, Bahn, Teil 2: Maustracking ist Quatsch

    Screenshot: Blockiertes Javascript auf bahn.de

    F12 in den üblichen Browsern führt auf verschiedene Sorten von „Web-Inspektoren“. In deren „Network“-Tabs könnt ihr die Flügel'sche Metrik bestimmen: Wie viele Dateien von wie vielen Hosts zieht so eine Seite? Die Bahn-Seite schneidet dabei nicht gut ab, nicht zuletzt aufgrund des nutzerInnenfeindlichen Javascripts, das der Screenshot zeigt.

    Wieder mal habe ich auf bahn.de eine Fahrkarte gekauft, und wieder hakte es an vielen Ecken. Immer noch hat der Server darauf bestanden, ich sei eingeloggt (und hat mir nicht die Möglichkeit gegeben, mich einzuloggen), hat mir aber nicht meine Buchungs-Voreinstellungen („eine Person mit Bahncard 50“) angeboten, hat wieder ganze Seiten mit je nur einer einzelnen Frage ausgeliefert, hat kaputte Zahlungsoptionen angeboten, quittierte einen Browser-Reload mit hartem Ausloggen („fang einfach nochmal an“) und verlangte von mir ein Login beim Kartenkauf, obwohl es mich ja die ganze Zeit schon als eingeloggt geführt hat. Immerhin – niemand soll sagen, ich würde nur motzen – war das Captcha vom letzten Herbst endlich weg (eine Reaktion auf meine diesbezüglichen Mails aus dem Herbst-Blogpost habe ich natürlich nie bekommen).

    Jedenfalls reichen eigentlich ein, zwei Transaktionen auf bahn.de locker, um einige (modulo Ökonomie) leicht zu behebende Usability-Schwächen zu finden. Aber gut: Gerade bei Webseiten bin ich ja schon froh, wenn sie wenigestens ihre Quirks behalten und nicht alle paar Wochen wieder was anders (zumeist: anders kaputt) ist. Ich erwähne das alles überhaupt nur, weil bahn.de in meinem Browser mal wieder so hakelig war, dass ich nachgesehen habe, wessen Javascript mir die Bahn neben ihrem eigenen (das dürfen sie ausführen) noch andrehen will. Unter den geblockten Quellen befand sich ein Laden namens m-pathy.com. Dessen Homepage (kleines Lob am Rande: das geht, ohne Code von m-pathy.com auf der lokalen Maschine laufen zu lassen) radebrecht mit Deppen-Leerzeichen:

    m-pathy UX Insight G4 macht sichtbar, was Ihre Kunden erleben.

    Unsere Analyse Lösung ermöglicht die Auswertung tausender feingranularer Interaktionsdaten aus Mausspuren, Touch-Gesten, Klicks und Formularinteraktionen.

    Das Ergebnis sind belegbare und priorisierbare Handlungsempfehlungen für die Optimierung Ihrer klassischen oder mobilen Webseite.

    Also: Die Bahn sammelt und verarbeitet Daten über meine Mausbewegungen (na ja, natürlich nicht über meine, weil das Javascript dieser Leute bei mir nicht läuft, aber von fast allen anderen ihrer KundInnen), um so zu tun, als würde sie ihre Webseite „optimieren“.

    Da die Usability der Webseite zumindest in meinem „Erleben“ spürbar abgenommen hat – vor allem wohl wegen der Förderung von „Partnerangeboten“ und anderen Marktingkrams, aber seis drum –, würde ich schließen, dass „m-pathy UX Insight G4“ schlicht nicht funktioniert. Ok: Kann sein, dass die hautnahe Bespitzelung der NutzerInnen durch die Bahn funktioniert und sich eben nur niemand um „belegbare und priorisierbare Handlungsempfehlungen“ kümmert. Dann könnte die Bespitzelung aber auch unterbleiben, oder? Oder sind die Zwecke der Bahn ganz andere als die bei m-pathy angegebenen? Allein, mir würden da nicht viele einfallen. Was bitte soll aus meinen Mausbewegungen über der Bahn-Webseite für die Bahn schon folgen?

    Einfach mal offen (also: ohne Fragebogen) mit 10 oder 50 NutzerInnen der Webseite reden und ihnen zuhören wäre ganz klar gigantisch viel datensparsamer und, so bin ich sicher, auch erheblich wirksamer, wenn die Bahn die Seite wirklich verbessern wollte.

    Liebe Bahn, darf ich euch noch einen Neujahrsvorsatz vorschlagen? Es wäre: Buchen ohne Javascript, vielleicht sogar mit einem lokalen, Debian-paketierbaren Programm, das auf einer wohldokumentierten API aufsetzt.

  • Zu Fuß im Zug ins Netz

    Screenshot

    Wer hinreichend Geduld und Kompetenz hat, bekommt in den Zügen von Go-Ahead am Ende so eine Seite vom Captive Portal.

    Zu den ärgerlichen Folgen des Irrsinns vom „geistigem Eigentum“ gehören Captive Portals, also Webseiten, auf die mensch in öffentlichen WLANs erstmal umgeleitet wird. Erst, wer Familienpackungen Javascript ausführen lässt und schließlich per Häkchen lügt, er_sie habe die Nutzungsbedingungen gelesen und anerkannt, darf ins Netz. Allein fürs Öffnen dieser Sicherheitslücke („gehen Sie in irgendein unbekanntes Netz und lassen Sie ihren Browser allen Code ausführen, der da rauskommt, und dann ziehen Sie noch megabyteweise Bilder – vielleicht ist ja in einem der Bilder-Decoder auch noch ein Buffer Overflow“) verdient die Geistiges-Eigentum-Mafia Teeren und Federn.

    Na ja, und erstaunlich oft ist der Mist einfach kaputt. Eine besondere Kränkung für die Ingenieursabteilung meines Herzens ist, wenn die ganze aufregende Hi-Tech, mit der mensch in fahrenden Zügen ins Netz kann, prima geht, aber trotzdem kein Bit durch die Leitung zu kriegen ist, weil ein „Web-Programmierer“ im doofen Captive Portal gemurkst hat.

    Kaputt sah das WLAN für mich heute in einem Zug von Go-Ahead aus. Die Geschichte, wie ich mich dennoch ins Netz vorgekämpft habe, finde ich im Hinblick auf manuelles Fummeln an IP-Netzen instruktiv, und so dachte ich mir, ich könnte im nächsten Zug (betrieben von der Bahn und deshalb noch nicht mal mit kaputtem Internet ausgestattet) zusammenschreiben, was ich alles gemacht habe. Das Tooling, das ich dabei verwende, ist etwas, öhm, oldschool. So sollte ich statt ifconfig und route heute wohl lieber ein Programm mit dem schönen Namen ip verwenden. Aber leider finde ich dessen Kommandozeile immer noch ziemlich grässlich, und solange die guten alten Programme aus grauer Vorzeit immer noch auf eigentlich allen Linuxen rumliegen, kann ich mich einfach nicht zur Migration durchringen.

    Am Anfang stand die einfache ifupdown-Konfiguration für das Zug-Netz:

    iface roam inet dhcp
      wireless-essid freeWIFIahead!
    

    in /etc/network/interfaces.d/roam. Damit kann ich sudo ifup wlan0=roam laufen lassen, und der Kram sollte sich verbinden (wenn ihr die Interface-Umbenamsung der systemd-Umgebung nicht wie ich abgeschaltet habt, würde vor dem = einer der kompizierten „vorhersagbaren“ Buchstabensuppen der Art wp4e1 oder so stehen).

    Nur: das Netz kam nicht hoch. Ein Blick nach /var/log/syslog (wie gesagt: etwas altbackenes Tooling; moderner Kram bräuchte hier eine wilde journalctl-Kommandozeile) liefert:

    Jan  2 1████████ victor kernel: wlan0: associate with be:30:7e:07:8e:82 (try 1/3)
    Jan  2 1████████ victor kernel: wlan0: RX AssocResp from be:30:7e:07:8e:82 (capab=0x401 status=0 aid=4)
    Jan  2 1████████ victor kernel: wlan0: associated
    Jan  2 1████████ victor kernel: IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
    Jan  2 1████████ victor dhclient[18221]: Listening on LPF/wlan0/█████████████████
    Jan  2 1████████ victor dhclient[18221]: Sending on   LPF/wlan0/█████████████████
    Jan  2 1████████ victor dhclient[18221]: Sending on   Socket/fallback
    Jan  2 1████████ victor dhclient[18221]: DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 6
    Jan  2 1████████ victor dhclient[18221]: DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 14
    Jan  2 1████████ victor dhclient[18221]: DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 1
    Jan  2 1████████ victor dhclient[18221]: No DHCPOFFERS received.
    

    Das bedeutet: Das lokale „Router“ (Access Point, AP) hat mich ins Netz gelassen („associated“; das ist quasi das Stecken des Netzkabels), aber dann hat der DHCP-Server, der mir eigentlich eine IP-Adresse hätte zuteilen sollen (mit der ich dann übers lokale Netz hinauskommen könnte), genau das nicht getan: „No DHCPOFFERS received“.

    Wenn das so ist – der Rechner ist Teil von einem Ethernet-Segment, sieht mithin Netzwerkverkehr, bekommt aber keine IP-Adresse und kann also mit niemandem über TCP/IP reden –, lohnt sich ein Blick in die Pakete, die im Netzwerksegment unterwegs sind. Das geht mit fetten Grafikmonstern wie wireshark, aber für einen schnellen Blick tut es tcpdump allemal. Da wir aber noch keine Internet-Verbindung haben, können wir sicher keine IP-Adressen („192.168.1.15“) zu Namen („blog.tfiu.de“) auflösen. Tatsächlich würde der Versuch tcpdump schon zum Stehen bringen. Deshalb habe ich per -n bestellt, Adressen numerisch auszugeben:

    tcpdump -n
    

    Ich sehe dabei einen Haufen ARP-requests, also Versuche, die lokalen Adressen von Ethernet-Karten für IP-Adressen herauszufinden, von denen der Router meint, sie müssten im lokalen Ethernet-Segment sein, etwa:

    12:█████████383626 ARP, Request who-has 10.1.224.139 tell 10.1.0.1, length 28
    

    Aus dieser Zeile allein kann ich schon mal raten, dass das Gateway, also der Router, über den ich ins Internet kommen könnte, wohl die Maschine 10.1.0.1 sein wird. Dabei sind Adressen aus dem 10er-Block leicht magisch, weil sie nicht (öffentlich) geroutet werden und daher (im Gegensatz zu normalen IP-Adressen) im Internet beliebig oft vorkommen können. Sie sind deshalb für relativ abgeschottete Unternetze wie hier im Zug populär (ins richtige Netz gehts dann per Network Address Translation NAT) – und Maschinen mit .1 hinten dran sind konventionell gerne Router.

    Wenn ich mit dem Gateway reden will, brauche ich immer noch selbst eine IP-Adresse. Ohne DHCP-Server bleibt mir wenig übrig als mir selbst eine zu nehmen. Das ist normalerweise ein unfreundlicher Akt, denn wer eine Adresse wiederverwendet, die jemand anders in dem Teilnetz schon hat, macht die Verbindung für den anderen Rechner im Effekt kaputt. Insofern: Wer etwas wie das Folgende tut, sollte erstmal für eine Weile dem tcpdump zusehen und sicherstellen, dass sonst niemand mit der gewählten Adresse unterwegs ist. Wer öfter zu Stunts dieser Art genötigt ist, möge sich arping ansehen – damit kann mensch kontrolliert nachsehen, ob eine Adresse frei ist.

    In meinem Fall war es ruhig im Netz – es hat ja vermutlich auch kaum jemand sonst eine Verbindung bekommen. Ich fühlte mich also hinreichend sicher, irgendwas zu probieren, das der Router wohl als „im eigenen Netz“ akzeptieren würde. Die so geratene Adresse habe ich versuchsweise auf meine Netzwerkschnittstelle geklebt:

    sudo ifconfig wlan0 inet 10.1.0.105 up
    

    Ein guter erster Tipp für diese Zwecke ist eine Adresse, bei der nur das letzte Byte anders ist als in der Router-Adresse (in antikem Jargon: „im selben Klasse C-Netz“). In diesem Fall wäre es denkbar, noch mehr zu ändern, denn im antiken Jargon ist 10.0.0.0 ein A-Netz („die Netzmaske ist 255.0.0.0“), was mit dem Kommando oben (das nicht explizit eine andere Netzmaske gibt) den lokalen Rechner Pakete, die an eine 10.irgendwas-Adresse gehen, an wlan0 schicken lässt. Allerdings macht fast niemand mehr Routen nach diesen Regeln, und so ist es nicht unwahrscheinlich, dass der Router allzu weit entfernte Adressen routen will oder jedenfalls nicht einfach wieder ins lokale Netz-Segment zurückschickt. So in etwa ist die Logik, die mich auf die IP-Adresse oben gebracht hat.

    Wenn meine Vermutungen richtig waren, hätte ich nach dem ifconfig mit dem vermuteten Router bei 10.1.0.1 IP sprechen können. Der Klassiker zur Konnektivitätsprüfung ist ping, und wirklich:

    ping 10.1.0.1
    

    kriegte brav Paket für Paekt zurück. Wow! Immerhin schon IP!

    Ein DHCP-Server konfiguriert als nächstes normalerweise die „Default-Route“, also das, was der Rechner mit Paketen tun soll, für die er nichts anderes weiß. Rechner am Rande des Netzes (und wir ungewaschenen Massen sind eigentlich immer mehr oder weniger am Rande des Netzes) schicken in der Regel alle Pakete, die nicht ins lokale Netz gehen, an einen (und nur einen) Router, nämlich ihr Gateway. Dieses Gateway legt mensch mit meinen alten Werkzeugen so fest:

    sudo route add default gw 10.1.0.1
    

    Damit könnte ich im Netz sein. Ein schnelles ssh auf eine meiner Maschinen im Netz führt aber zu nichts: meine Maschine kann keine Namen auflösen. Ach ja, das ist noch etwas, das normalerweise ein DHCP-Server macht: der lokalen Maschine Adressen geben, an denen sie Namen auflösen kann (die DNS-Server). Über (inzwischen potenziell sehr komplizierte) Umwege enden diese Adressen in gewissem Sinn in der Datei /etc/resolv.conf; dort erwartet sie jedenfalls die C-Bibliothek.

    Nun ist aber der DHCP-Server gerade kaputt. Die Namen von DNS-Servern, die aus einem bestimmten Netz heraus funktionieren, kann mensch jedoch nicht raten. Manchmal – typisch bei privaten Netzen – tut es der Router selbst. Andererseits betreibt Google unter 8.8.8.8 einen DNS-Server, und so ungern ich Google-Dienste empfehle: Die 8.8.8.8 verwende ich in Notsituationen wie dieser. Nur bin ich ja immer noch im Captive Portal, und der Router mag meine Versuche, mit dem Google-DNS zu reden, unterbinden. Viele Captive Portals tun das nicht (aus relativ guten Gründen). Und wirklich:

    ping 8.8.8.8
    

    kommt gut zurück. Andererseits kann mir das Captive Portal natürlich alles vorspielen. Ist da wirklich ein DNS-Server?

    Das Tool der Wahl zum Spielen mit DNS-Servern ist dig [1]. Im einfachsten Fall bekommt dig einen Namen als Parameter, das wird hier zu nichts führen, denn noch hat mein Rechner ja kein DNS. Eine Stufe komplizierter übergibt mensch noch eine Nameserver-Adresse hinter einem @, also:

    dig blog.tfiu.de @8.8.8.8
    

    Und das kommt zurück! Mit der richtigen Information, nicht irgendeinem Mist, den sich das Captive Portal ausdenkt. Damit kann ich für meine temporäre Netzverbindung mein /etc/resolv.conf ändern zu:

    nameserver 8.8.8.8 …
  • Anachronismen

    Wer gestern vom Papst Generalabsolution haben wollte, bekam in der Vatikan-Übertragung folgendes Bild sehen:

    Schweizer Garde mit riesigen Helmen und OP-Mundschutz

    Quelle: Vatikan-Mitschnitt. Rechte beim Vatikan.

    Ich kann gar nicht genau sagen, warum genau mich das als symbolisch für Religion in der Moderne hingerissen hat: die Kombination aus offensichtlich unsinniger Tradition (die Rüstungen) und modernen Einsichten (Viren, Tröpfcheninfektion)? Das Festhalten an unsinnigen Prozeduren (hier: eng stehen, laut brüllen), auch wenn diese mit erkennbaren Risiken verbunden sind, die mensch leicht vermeiden könnte? Oder wars nur, dass die Mundschutze in dieser Situation annäheernd leere Demonstration waren, denn vergleichen mit dem, was dann nachher in den Umkleiden[1] stattfindet, ist das Infektionsrisiko am durchpusteten Petersplatz trotz des zu geringen Abstands fast vernachlässigbar (na gut, jedenfalls, wenn sich die Leute bereitgefunden hätten, aufs Rumbrüllen zu verzichten).

    [1]Oder der Kaserne? Leider geht aus dem Wikipedia-Artikel zur Schweizergarde nicht hervor, ob die Leute kaserniert sind oder nicht. Dafür steht dort zu lesen, dass auch der Papst statt auf ordentliche Schutzengel doch eher auf die Maschinenpistole 5 aus der Todesfabrik von Heckler und Koch in Oberndorf am Neckar setzt. Außerdem im Artikel: Ein Link auf die nachgerade klischeereine Geschichte um den Mord an dem Kommandanten Alois Estermann. Manchmal, so scheint es, stimmt der Bibelspruch doch: Wer das Schwert ergreift, wird durch das Schwert umkommen.
  • Keine Vollendung

    Vor gut 30 Jahren hat der Bundestag beschlossen, mit der Regierung nach Berlin umzuziehen. Es setzte sich damals ein Antrag durch, der von Willy Brandt und Wolfgang Schäuble unterstützt wurde – wie so oft hatte der Patriotismus großzügig weltanschauliche Differenzen zugekleistert.

    Der Titel des siegreichen Antrags von 1991: „Vollendung der inneren Einheit Deutschlands“.

    Diese „Sternstunde des deutschen Bundestags“ (Bundestagsverwaltung) kommentiert das SARS-2-Cornavirus am 23.12.2021 wie folgt:

    Deutschlandkarte mit Inzidenzen: die alten Grenzen sind unschwer sichtbar

    Aus: RKI-Bericht von heute, Rechte beim RKI

    Wer sich nicht mehr erinnert: vgl. Wikipedia.

  • Optimierte Inzidenz

    Mortalitätspunkte und eine Fit-Gerade in einem Logplot

    Abbildung 3 aus dem Paper von Levine et al, auf das ich unten ein wenig eingehe: das Risiko, an SARS-2 zu sterben, geht ziemlich genau exponentiell mit dem Alter (die Ordinate ist logarithmisch aufgeteilt). Diese Beobachtung führt ziemlich direkt zu einem Kult-Paper aus den wilden Jahres des Internet. CC-BY doi:10.1007/s10654-020-00698-1.

    Als das WWW noch jung war und das Internet jedenfalls nicht alt, im Dezember 1999 nämlich, haben Chris Gottbrath, Jeremy Bailin, Casey Meakin, Todd Thompson und J.J. Charfman vom Steward Observatory das bemerkenswerte Paper „The Effects of Moore's Law and Slacking on Large Computations“ auf astro-ph, der Astrophyik-Abteilung des Preprint-Servers arXiv, veröffentlicht. Obwohl das damals nach meiner Erinnerung hohe Wellen geschlagen hat (selbst slashdot, damals eine der wichtigsten Seiten im Netz, berichtete), haben sie es bis heute zu keiner Fachzeitschrift eingereicht. Keine Ahnung, warum nicht, denn ihr Punkt ist trotz ihres eher leichtfüßigen Stils[1] völlig korrekt und jedenfalls nicht ganz offensichtlich.

    Gottbrath und Freunde sagen nämlich, dass, wer eine riesige Rechenaufgabe und ein festes Budget hat, durch Warten schneller fertig werden kann. Das liegt daran, dass mensch nach 18 Monaten (das ist die konventionelle Zeitskala für Moore's Law) fürs gleiche Geld einen Rechner mit doppelt so vielen Transistoren kaufen kann und der wird mit etwas Glück doppelt so schnell sein wie der, den mensch heute kaufen würde. Sie berechnen auch, wie groß eine Rechnung sein muss, damit sich das Warten lohnt: mit dem 18-Monate-Gesetz ist die Grenze bei Aufgaben, die 26 Monate rechnen würden.

    Weil das Paper damals in meiner Blase intensiv herumgereicht worden ist, finde ich überraschend, dass es laut ADS nur sechs Mal zitiert (wenn auch von einer illustren Auswahl von Papern) worden ist und bei den üblichen Suchmaschinen bei Anfragen wie „Moore's Law optimal waiting“ nicht in Sicht kommt.

    Transistoren vs. SARS-2

    Gesucht hatte ich es wiederum, weil ich ja schon länger mit Niedriginzidenzsstrategien hadere. Ganz unabhängig davon, ob wir als Gesellschaft hohe Inzidenzen ohne Schrammen überstehen, dürfte inzwischen niemand mehr ernsthaft bestreiten, dass „am Ende“ alle SARS-2 gehabt haben werden – die Frage ist nur, wann („werden wir im Herbst 2022 wieder einen Lockdown brauchen?“) und auch, wie viele Menschen bis dahin wegen SARS-2 schwer krank geworden oder gar gestorben sein werden.

    An diesem Punkt ist mir das 1999er-Paper eingefallen, denn wir haben bei SARS-2 etwas ganz ähnliches wie Moore's Gesetz: Die Sterblichkeit nach einer Erstinfektion steigt exponentiell mit dem Alter. Das haben im September 2020 (also einige Monate, bevor Impfungen gegen SARS-2 epidemiologisch relevant wurden) Andrew Levin und Kollegen in ihrem Artikel „Assessing the age specificity of infection fatality rates for COVID-19: systematic review, meta-analysis, and public policy implications“ (doi:10.1007/s10654-020-00698-1) recht sorgfältig und beeindruckend gezeigt. Die Abbildung am oben im Post ist aus dieser Arbeit.

    Da hier das Risiko und nicht die Leistung zunimmt, ist jetzt allerdings die Frage nicht, ob mensch lieber etwas warten soll. Nein, je älter Leute werden, desto größer ist ihr Risiko, eine SARS-2-Infektion nicht zu überleben, und dieses Risiko wächst ziemlich steil. Der Gedanke, die Gesamtopferzahl könnte sinken, wenn sich Menschen anstecken, solange sie noch jünger sind und sie also die Infektion mit höherer Wahrscheinlichkeit überleben, liegt also nicht fern. Die zur Prüfung des Gedankens notwendige Mathematik läuft im Wesentlichen analog zu den Überlegungen von Gottbrath und Freunden.

    Ethisch ist es natürlich nicht analog, aber ich wollte dennoch wissen, wie viel das eigentlich ausmachen könnte. Deshalb habe ich mir folgendes Modell ausgedacht:

    1. Die Infection Fatality Rate, also die Wahrscheinlichkeit, an einer (erkannten oder unerkannten) SARS-2-Infektion zu sterben, ist inspiriert von der Abbildung oben

      IFR = exp((t − A1) ⁄ λ) ⁄ 100.

      Dabei ist t das Alter der erkrankten Person, A1 das Alter, in dem 1% der Infizierten versterben (das pro-cent ist auch der Grund für die Division durch Hundert), und λ so etwas wie die Steigung; nennt mensch das Alter, in dem die Todesrate auf 10% gestiegen ist, A10, so lässt sich leicht

      λ = (A10 − A1) ⁄ ln(10)

      ausrechnen.

    2. Eine ultrakompetente Regierung (oder Schwarmintelligenz auf Brillianzniveau cosmic) kriegt es hin, die Inzidenz konstant über viele Jahre auf i zu halten. In meiner Simulation bleibe bei der Interpretation als Wocheninzidenz und simuliere die Infektion von Woche zu Woche. Gegenüber den Inzidenzen in der realen Welt gibt es bei mir außerdem keine Dunkelziffer.

    3. Wer nicht an SARS-2 stribt, stirbt nach Gompertz (cf. Mortalität in der Wikpedia), es stirbt also jedes Jahr ein Anteil („General Fatality Rate”)

      GFR = S30⋅exp(G⋅(t − 30  a)).

      der t-jährigen. Dabei ist S30 die Sterberate für 30-jährige, die ich aus dem Wikipedia-Artikel als ungefähr 40/100000 pro Jahr ablese, und G der Gompertz-Sterbekoeffizient – ich bin nicht sicher, ob ich so eine Größe eigentlich nach mir benannt haben wollte -, den die Wikipedia als 0.08 ⁄  a gibt. Etwas jenseits von Gompertz lasse ich jede Woche 1/52 der fürs jeweilige Wochen-Alter berechneten Menschen sterben; das macht vor allem die Kurven von SARS-2-Opfern über der Zeit glatter.

    4. Wer eine SARS-2-Infektion überlebt hat, stirbt nicht mehr an SARS-2. Das ist sicher eine unrealistische Annahme, aber sie macht das Modell auch deutlich klarer.

    Bliebe noch die Schätzung der Parameter aus der Formel für die IFR. Aus der Abbildung am Artikelanfang lese ich per Auge A1 = 65  a und A10 = 83  a ab (wer von den a irritiert ist: das ist die Einheit, nämlich das Jahr).

    Hier liegt die zweite wesentliche Schwäche meines Modells: Nachdem inzwischen in den dabei mitspielenden Altersgruppen wirklich eine überwältigende Mehrheit geimpft ist, werden diese Zahlen heute garantiert anders aussehen als in der ersten Jahreshälfte 2020, als die Studien gemacht wurden, die Levine et al ausgewertet haben. Andererseits legen die immer noch recht erheblichen Sterbefallzahlen nahe, dass sich die Kurve wohl nur ein wenig nach rechts verschoben haben wird; ich komme gleich nochmal darauf zurück.

    Der Berg des Todes

    Habe ich dieses Modell, kann ich einer Gruppe von Menschen folgen, bis sich (fast) niemand mehr infizieren kann, weil alle entweder tot oder in meinem Sinne immun sind. Ohne es probiert zu haben, glaube ich, dass das Modell einfach genug ist, um es in eine geschlossen lösbare Differentialgleichung umschreiben zu können. Aber wer will denken, wenn es doch Computer gibt?

    Und so habe ich die Modellannahmen von oben einfach in ein paar Zeilen Python gepackt und folge dem Schicksal einer Kohorte von 100000 70-jährigen, bis alle tot oder genesen sind. Und das mache ich für einen Satz von Inzidenzen zwischen 20 und 2000. für Das Ergebnis:

    Eine Kurve mit einem deutlichen Maximum um die 100

    Ich gebe zu, dass ich mit dieser Kurvenform nicht gerechnet hatte. Dass ganz niedrige Inzidenzen die Todeszahlen drücken, ist zwar zunächst klar, denn bei, sagen wir, 20/100000/Woche würde es 100000 ⁄ 20 = 5000 Wochen oder fast 100 Jahre dauern, bis alle mal das Virus hätten haben können, und in der Zeit sind 70-jährige natürlich anderweitig gestorben.

    Das hohe und recht steile Maximum um die 100 herum hatte ich so aber nicht erwartet. Zu ihm tragen vor allem Leute bei, die erst nach einigen Jahren – und dann deutlich gebrechlicher – mit SARS-2 in Kontakt kommen. Bei einer 100er-Inzidenz sieht die Wochensterblichkeit über der Zeit (in Wochen) so aus (cf. make_hist_fig im Skript):

    Kurve mit einem Maximum zwischen 1000 und 1700 Wochen

    Diese Kurve wäre ziemlich zackig, wenn ich strikt nach Gompertz-Formel nur ein Mal im Jahr natürliche Tode hätte, statt die diese geeignet auf die Wochen zu verteilen.

    Die Menschen, die am Anfang der Pandemie 70 sind, sterben in diesem Modell also typischerweise nach 1000 Wochen oder fast 20 Jahren, wenn sie ihn ihren 90ern wären. Das mag etwas fantastisch klingen. Jedoch: Das RKI hat früher immer dienstags die Demographie der Verstorbenen veröffentlicht (z.B. Bericht vom 30.3.2021, siehe S. 12), und tatsächlich sind 20% der Coronatoten in der Altersgruppe 90-99.

    Aber klar: Das ist hypothetisch. Niemand kann die Inzidenzen konstant auf 100 halten, und niemand wird das vernünftigerweise wollen. Vor allem aber mag die Impfung die IFR-Kurve durchaus so weit nach rechts verschieben, dass der Sterblichkeitspeak, der hier noch bei 90-jährigen sitzt, jenseits der 100 rutscht, und dann betrifft das, bei heutigen Lebenswerwartungen, praktisch niemanden mehr.

    Zynische Metriken

    Als Gedankenexperiment jedoch finde ich das Ganze schon bemerkenswert: Wenn wir eine 1000er-Inzidenz aushalten können, würden wir nach diesem, eingestandenermaßen idealisierten, Modell 7% der 70-jährigen den Tod durch SARS-2 ersparen.

    Ein so starker Effekt muss eigentlich schon aufgefallen sein. Wenn das kein Fehler auf meiner Seite ist: steht das schon irgendwo in der epidemiologischen Literatur?

    Allerdings ist die, ach ja, Metrik „Wie viele Leute sterben an SARS-2?“ auch ziemlich nichtssagend. Weit üblicher zur Einschätzung der Frage, wie viel Geld (oder Nerven) mensch für Interventionen gegen Krankheiten ausgeben mag, sind die YLL, Years of Life Lost (cf. nochmal DALY in der Wikipedia). Diese Metrik ist zwar – ganz wie meine Rechnung hier – ein wenig zynisch, aber doch nachvollziebar genug, dass ich mir aus meinem Modell auch nochmal die Gesamtlebensjahre habe ausspucken lassen, die meine 100000er-Kohorte in den Läufen mit den verschiedenen Inzidenzen …

  • El-Cheapo Internationalisation in Pelican and Jinja

    This blog is mainly in German, but in particular computer-related posts I'm writing in (some version of) English, as I expect they might be useful and/or interesting to quite a few people who don't speak German. On the English-language pages, I was always a bit unhappy that the footers (and to a certain degree, menu items) were in German.

    Now, the standard way to “internationalize” programs is gettext, and sure enough, Pelican's template engine Jinja supports i18n with gettext. But my actual use case is mainly to replace large blocks (like the full footer, which has little markup but quite a lot of text), and having gettext-style message catalogues for those seemed unattractive to me.

    Instead, I thought I could somehow work thorugh jinja computed includes, perhaps with something like:

    {% import 'messages-'+article.lang+'.html' as messages %}
    

    For each language I want to support, I'd then have one messages file (messages-en.html, messages-de.html, …), a bit like the message catalogues in gettext, but containing jinja markup.

    The first question to answer was: What jinja markup? After a few experiments, it seems to me that using jinja blocks – which initially had seemed idiomatic to me – to write these messages files is at least tricky. After a while I rather settled for macros, such that the message file could contain something like:

    {% macro basefoot() -%}
     <footer id="main-footer" class="clearfix">
       <ul class="nobull">
       <li><a href="/pages/wer.html">[Wer?/Kontakt]</a>
         | <a href="/archives.html">[Archiv]</a></li>
       ...
    {%- endmacro }
    

    and the application in the template would then be:

    {% block footer %}
      {{ messages.basefoot() }}
    {% endblock footer %}
    

    This works nicely for internationalising large tree fragments and is not a lot worse than gettext for single strings (though I admit message catalogues are a bit nicer to work with when translating).

    The one big problem was how to select the messages. For all the infrastructure pages (archive, tags, categories), I'm happy to use the default language (who looks at them, after all?). Hence,

    {% import 'messages-'+DEFAULT_LANG+'.html' as messages %}
    

    in the base.html template sounded like a good idea and went well enough. Then I thought I could use:

    {% import 'messages-'+article.lang+'.html' as messages %}
    

    in article.html and something similar in page.html. But alas: That won't work, because, as in python, jinja imports only happen once per run and are simply namespace operations when repeated.

    I then tried to put the import statement into a named block, hoping that perhaps block overriding would suppress the default import. I suspect it wouldn't have because block content, I gather, is executed unconditionally, but never mind: it won't work anyway because (at least that's what I gather) blocks have python namespaces of their own, and hence imports in a block are not visible outside of it. Hence, once I put the import statement into a jinja block, my messages object is gone from where I need it.

    So, I ended up with the following hack in base.html:

    {# Yeah, hard-coding the various cases here *is* lame, but
       you can't override an import in a child templates as far
       as I can see, so this seems the least ugly option #}
    {% if article %}
    {% import 'messages-'+article.lang+'.html' as messages %}
    {% elif page %}
    {% import 'messages-'+page.lang+'.html' as messages %}
    {% else %}
    {% import 'messages-'+DEFAULT_LANG+'.html' as messages %}
    {% endif %}
    

    – this is ugly, breaks the encapsulation of the article and page templates, and it generally sucks, but for now it's good enough for me. I suppose the clean way to do this would be through a pelican extension providing a variable main_language (perhaps), computed in much the same way as this.

    Let's see if this hack falls on my feet; for now, I like the way this works out and that most of the stuff on the article pages is now English on English pages and German on German pages.

    Ceterum censeo: the more template languages I use for producing XML (and yes, I'm aware jinja has a much wider scope), the more I'm convinced the low adoption of stan is another instance of IT discarding a clearly superior design. What a pity it is that, for all I can see, all the popular templating engines work against the existing XML markup rather than, as in stan, with it.

  • Müdigkeit zur rechten Zeit

    Ich persönlich bin ja überzeugt, dass Public Health-Studien in einer mindestens ebenso dramatischen Replikationskrise stecken wie Studien in der Psychologie. Die Überzeugung resultiert in erster Linie aus einer Überdosis von Papern zu Broccoli oder Spirulina als „Superfoods“, aber eigentlich glaube ich im Groben gar keiner Studie, die Lebensgestaltung mit Lebenserwartung zusammenbringt, ohne eine wenigstens annähernd plausible mechanistische Begründung zu liefern (im Idealfall natürlich so stringent wie bei der erblichen Hypomagniesiämie).

    Manchmal jedoch sind epidemiologische Befunde einfach zu schön für Skepsis. Der Wille zum Glauben regte sich bei mir beispielsweise bei „Accelerometer-derived sleep onset timing and cardiovascular disease incidence: a UK Biobank cohort study“ von Shahram Nikbakhtian et al (doi:10.1093/ehjdh/ztab088). Politikkompatibel formuliert behauptet die Arbeit, mensch solle zwischen 10 und 11 ins Bett gehen, um möglichst alt zu werden; so in etwa war es auch in Forschung aktuell vom 9.11.2021 zu hören (ab 2:58).

    Piktogramme und Schlagworte

    Aus dem Paper von Nikbakhtian et al: Ein „graphical abstract“. Wer bitte ist auf die Idee gekommen, alberne Piktogramme würden beim Verständnis eines wissenschaftlichen Aufsatzes helfen? CC-BY-NC Nikbakhtian et al.

    Angesichts meiner spontanen Sympathie für das Ergebnis wollte ich ein besser fundiertes Gefühl dafür bekommen, wie sehr ich dieser Arbeit misstrauen sollte – und was sie wirklich sagt. Nun: abgesehen vom „graphical abstract“, das auf meinem crap-o-meter schon nennenswerte Ausschläge verursacht, sieht das eigentlich nicht unvernünftig aus. Die AutorInnen haben um die 100000 Leute eine Woche lang mit Beschleunigungsmessern schlafen lassen, und ich glaube ihnen, dass sie damit ganz gut quantifizieren können, wann da wer eingeschlafen und wieder aufgewacht ist.

    Dann haben sie fünf Jahre gewartet, bis sie in der UK Biobank – einer richtig großen Datenbank mit allerlei Gesundheitsdaten, in die erstaunlich viele BritInnen erstaunlich detaillierte Daten bis hin zu ihren Gensequenzen spenden[1] – nachgesehen haben, was aus ihren ProbandInnen geworden ist.

    Eigentlich nicht schlecht

    Ein Projekt, das sich fünf Jahre Zeit lässt, ist schon mal nicht ganz verkehrt. Weiter haben sie ihre Datenanalyse mit R und Python gemacht (und nicht mit proprietärer klicken-bis-es-signifikant-istware wie SPSS oder SAS, oder gar, <gottheit> bewahre, Excel), was auch kein schlechtes Zeichen ist. Klar, es gibt ein paar kleine technische Schwierigkeiten. So haben sie zum Beispiel notorische SchnarcherInnen („Schlafapnoe“) ausgeschlossen, so dass von ihren gut 100000 ProbandInnen am Schluss zwar gut 50000 Frauen, aber nur knapp 37000 Männer übrig geblieben sind.

    Dann gibt es Dinge, die in der Tabelle 1 (S. 4 im PDF) seltsam wirken, aber wohl plausibel sind. So schätzen sich ein Drittel der TeilnehmerInnen selbst als „more morning type“ ein – wo sind all die Morgentypen in meiner Bekanntschaft? Und warum schätzen sich 27% der Leute, die erst nach Mitternacht einschlafen, als „more morning type“ ein (14% sogar als „morning type“)? Kein Wunder, dass die armen Leute dann allenfalls sechs Stunden Schlaf kriegen, die Nach-Mitternacht-SchläferInnen sogar nur fünfeinhalb. Oh grusel.

    Und die Tabelle gibt her, dass die Diabetesrate bei den Nach-Mitternacht-SchläferInnen erheblich höher ist als bei den Früher-SchläferInnen (fast 9% gegen um die 5.5%) – ist das eine Folge von Chips auf dem Sofa beim Fernsehkonsum? Ganz überraschend fand ich schließlich den niedrigen Anteil von RaucherInnen, der in allen Gruppen deutlich unter 10% lag. Das, denke ich, würde in der BRD auch bei der betrachteten Altersgruppe (meist älter als 50) noch ganz anders aussehen. Aber ich vermute eher, dass RaucherInnen in der (nach meiner Erinnerung auf freiwilliger Rekrutierung basierenden) Biobank stark unterrepräsentiert sind. Das wirft dann natürlich Fragen bezüglich anderer Auswahleffekte in der Testgruppe auf.

    Wie dem auch sei: Das Ergebnis am Schluss war, grafisch zunächst sehr beeindruckend (Abbildung 2 in der Arbeit), dass Leute, die zwischen 10 und 11 einschlafen, deutlich weniger Herz-Kreislauf-Probleme haben als die anderen, ein Ergebnis, das mir gut gefällt, denn ich werde recht zuverlässig gegen 22 Uhr müde und bin dann froh, wenn ich ins Bett kann.

    Aber leider: Wenn mensch z.B. die erhöhte Diabetesrate rausrechnet, bleibt von dem Schlaf-Effekt nicht mehr viel übrig, jedenfalls nicht bei Männern, bei denen nur die Frühschläfer gegenüber Andersschläfern signifikant erhöhte Risiken hatten. Diese ließen sich recht zwanglos erklären, wenn das z.B. Schichtarbeiter gewesen wären, denn die Korrelation zwischen Schichtarbeit und Herzgeschichten ist wohlbekannt.

    Das ist aus meiner Sicht ohnehin die größte Schwierigkeit des Papers: Da Armut und Reichtum in westlichen Gesellschaften der beste Prädiktor für die Lebenserwartung ist[2], hätte ich gerne eine Kontrolle gegen die Klassenzugehörigkeit gesehen. Aber ich vermute, dass die Biobank solchen Einschätzungen aus dem Weg geht.

    Was verständlich ist, denn diese könnten ja den Schwefelgeruch des Klassenkampfs verströmen. Der wäre bei der vorliegenen Studie sicher auch deshalb besonders unwillkommen, weil die AutorInnen alle für den Gesundheitshöker Huma arbeiten, der, wenn ich den Wikipedia-Artikel richtig lese, auch im Geschäft mit Fitnesstrackerei unterwegs ist. In deren Welt jedoch ist jedeR seiner/ihrer Gesundheit Schmied, so dass für Klassenfragen besonders wenig Platz ist.

    Global Burden of Disease

    Eine weitere Entdeckung habe ich beim Reinblättern ins Paper gemacht, weil ich schon den ersten Satz nicht glauben wollte:

    Cardiovascular disease (CVD) continues to be the most significant cause of mortality worldwide, with an estimated 18.6 million deaths each year.

    Das schien mir gewagt, denn unter der (falschen) Annahme eines Gleichgewichts müssten bei rund 8 Milliarden Menschen mit einer Lebenserwartung von 100 Jahren 80 Millionen im Jahr sterben; auf einen Faktor zwei wird das trotz starken Wachstums vor allem in der zweiten Hälfte des 20. Jahrhunderts (senkt die Todesrate, weil ja mehr Menschen relativ jung sind) sowie gegenläufig geringerer Lebenserwartung schon stimmen. Wenn die 80 Millionen hinkämen, würden Herz-Kreislaufgeschichten 20% der Todesursachen ausmachen. Das soll schon die Nummer 1 sein? Tja – ich bin dem Literaturverweis gefolgt.

    Dabei kommt mensch bei den Global Burden of Disease-Daten (GBD) eines Institute for Health Metrics and Evaluation an der University of Washington heraus, einer Übersicht über das, woran die Leute auf der Welt so sterben und wie viele Lebensjahre was kostet. Nur nur, weil da „Metrik“ drinsteht, wäre an der ganzen Anlage der Daten schon viel zu kritisieren – die Wikipedia bespricht z.B. in ihrem Artikel zu DALY einige Punkte. Und natürlich ist das „Tool“, über das mensch die Daten nutzen soll, wieder so eine Javascript Only-Grütze.

    Aber spannend ist das doch, angefangen bei der Ansage von GBD, es stürben derzeit weltweit rund 56.5 Millionen Menschen pro Jahr. Dabei geben die GBD-Leute ein – Vorsicht, unverantwortlicher Natwi-Jargon – 2 σ-Intervall, also 95%-Konfidenzbereich, von 53.7 bis 59.2 Millionen; so große Fehlerbereiche verstärken tatsächlich mein Zutrauen zu diesen Daten, denn wenn ich mir so das globale Meldewesen vorstelle, scheint es sehr nachvollziehbar, dass drei Millionen Tote mehr oder weniger nicht ohne weiteres auffallen. Sie verlören, und dabei wirds allmählich wirtschafts„wissenschaftlich“, dabei 1.7 Milliarden Lebenjahre an Krankheiten und ähnliches.

    Ich muss mich demnächst mal mehr damit beschäftigen. Schade, dass der November schon vorbei ist. Das wäre eine sehr jahreszeitgemäße Tätigkeit gewesen.

    [1]Auch einer meiner Lieblingskollegen tut das. Als wir uns mal drüber unterhalten haben, meinte er etwas wie: Ich dachte mir schon, dass du das komisch findest. Meine Antwort war: Nun, nicht per se, aber doch in einem Staat, der selbst von Kindern DNA-Profile einsammelt, um damit flächendeckend Ladendiebstahl aufzuklären.
    [2]Gut, das ist jetzt etwas provokant, zumal „bester“ ja immer eine Menge braucht, innerhalb derer verglichen wird, und über dieser eine Totalordnung, was für ziemlich viele praktisch relevante Mengen schon mal nicht (eindeutig) gilt. Hier: klar ist der Unterschied der Lebenserwartung für Leute mit und ohne amyotrophe Lateralsklerose noch größer als der zwischen armen und reichen Menschen, so dass „hat ALS” mit einigem Recht als „besserer“ Prädiktor bezeichnet werden könnte. Aber „ist arm“ erlaubt für weit mehr Menschen eine recht starke Aussage. Deshalb kann ich, ohne nur zu provozieren, mit mindestens gleichem Recht von „besser“ reden. Ist halt eine andere Ordnungsrelation. Oder eine andere Menge, in der exotische Prädiktoren gar nicht vorkommen.
  • Die überraschende Macht der Tradition

    Foto: Grabstein

    Nur, damit ich nicht falsch verstanden werde: Ich bin ein großer Fan von Argelander, so groß, dass ich zu seinem Grab in Bonn gepilgert bin.

    Als ich heute morgen bei heise online einen Artikel las, in dem die Entdeckung eines braunen Zwergs (oder meinethalben auch einen besonders großen Riesenplaneten) durch einen Amateurastronomen verkündet wurde, musste ich traurig lächeln, denn das Objekt, um das es ging, hieß dort – und, wie sich rausstellt, sogar in der Originalarbeit (doi:10.3847/1538-4357/ac2499; open access arXiv:2112.04678) – „BD+60 1417b“.

    Was ist daran traurig? Nun, das „BD“ darin bezieht sich auf die Bonner Durchmusterung, ein eingestandenermaßen epochales Werk. Nur eben eines mit dem Äquinoktium B1855.0, was aus dem Astronomesischen übersetzt „echt retro“ heißt. Genau: Die 1855 steht so in etwa für das bürgerliche Jahr 1855; wer genau nachrechnet, kommt auf den 31.12.1854, kurz vor zehn am Abend, aber legt mich jetzt bitte nicht auf die Zeitzone fest. Was Erdkoordinaten angeht, haben manche Leute damals noch mit der Längenzählung in Paris angefangen. „Äquinoktium B1855.0“ ist tatsächlich ein wenig mit sowas vergleichbar, denn es bezeicnet letztlich eine Art, den Himmel in Länge und Bereite aufzuteilen.

    Damit will ich nichts gegen die Arbeit von Friedrich Argelander – der hat das damals in der Hand gehabt – gesagt haben. Im Gegenteil: sie war unglaublich wertvoll, und es ist heute kaum glaublich, dass Menschen (statt Computer) überhaupt 325000 Sterne beobachten und die Beobachtungen reduzieren können. Aber der Kram ist halt Mitte des vorletzten Jahrhunderts beobachtet worden, und die abschließende Publikation war 1903.

    Dass Bezeichner aus Arbeiten vor der Publikation der speziellen Relativitätstheorie noch in einer Arbeit vorkommen, die mit Daten von einem Weltraumteleskop im mittleren Infraroten operiert, ist schon, na ja, zünftig, zumal eine schnelle Simbad-Anfrage reichlich weniger angestaubte Bezeichnungen geliefert hätte; vermutlich hätte ich das Ding aus persönlicher Verbundenheit PPM 18359 genannt, oder dann halt SAO 15880. Die wirklich aktuellen Gaia-Bezeichnungen hingegen („DR2 1579929906250111232“; ich habe gerade nachgesehen: die Nummer bleibt im DR3) – ach ja, die sind vielleicht wirklich nicht so gut für Menschen geeignet. Dabei sind sind die monströsen Ziffernfolgen nur 64 bit… eigentlich sollte es da eine menschenwürdigere Kodierung geben. Hm.

    Aber am Ende: es ist wieder die Macht der Tradition, die ich gerade für die Astronomie schon jüngst beklagt hatte, als es in Fußnote 1 um die in dem Bereich einfach nicht verschwinden wollenden sexagesimalen Koordinaten ging. Unter diesen Umständen würde ich mir vielleicht auch keine allzu große Mühe geben mit lesbaren Kodierungen von 64-bit-Zahlen.

  • Telecon-Gefühl: Das glaub ich jetzt nicht

    Nachdem ich hier schon zwei andere Patzer in Live-Übertragungen diskutiert habe, wird es klar Zeit für ein neues Tag: Live. Ich habe nämlich noch eine schöne und motivierende Reaktion auf technische Probleme in einer Live-Sendung [kommt es nur mir vor, als würde deren Rate zunehmen? Das wäre dann wohl Beleg für Digitalisierung…].

    Wieder sind es vor allem Erinnerungen an eigene Telecons, die mir Volkart Wildermuths Ausbruch in der Forschung aktuell-Sendung vom 19.11.2021 (Kudos an den DLF, dass sie die Panne nicht aus der Archiv-Sendung rausgeschnitten haben) so sympathisch machen:

    —Rechte beim Deutschlandfunk

    Der Seufzer bei Sekunde 27! Ich erkenne mich so wieder. Genau mein Geräusch, wenn der doofe Chromium (wer ist eigentlich auf die hirnrissige Idee gekommen, ausgerechnet in Webbrowsern Telecons zu halten?) wieder genau das Alsa-Audiodevice nicht findet, über das ich sprechen will.

    „Mann! Dann ruft mich an.“ Absolut ich. Bis in den Tonfall.

    „Das glaub ich jetzt nicht.“ Wie oft habe ich das schon gesagt speziell seit Corona, etwa, wenn der fiese closed-source zoom-Client (immerhin kein Web-Browser!) genau das xephyr-Fenster nicht zum Screenshare anbietet, in dem ich den Kram zeigen wollte (stattdessen aber alle Fenster von Dockapps, die er jetzt wirklich anhand ihrer Properties hätte rausfiltern können)? Das ganze Elend mistiger und unfixbarer proprietärer Software, der Horror von Javascript-Salat, zu deren Nutzung mich die Technikfeindlichkeit (im Sinne von: ich nehme halt das Bequemste und Vorgekochteste, was es nur gibt) meiner doch angeblich so digitalisierungslustigen Umwelt so nötigt: „Ach, Mann, das glaub ich jetzt nicht.“

    Abgesehen von der Panne fand ich in der Sendung übrigens speziell das das Segment über Flussblindheit wirklich hörenswert: Ich muss gestehen, dass ich diese komplett vermeidbare Dauerkatastrophe zwischenzeitlich verdrängt hatte. Noch so ein Ding, bei dem in hundert Jahren zurückblickende Menschen den Kopf schütteln werden: Wie konnten die eine so einfach behandelbare Krankheit so viele Opfer fordern lassen? Während sie, um nur ein besonders bizarres Beispiel zu nennen, gleichzeitig mit unfassbarem Aufwand High Frequency Trading gespielt haben?

« Seite 12 / 17 »

Letzte Ergänzungen