28.04.2015

Überraschender Leserbrief zum Thema Impfen

Am Samstag war ein Leserbrief von mir in der WZ, obwohl ich gar keinen geschrieben hatte - dachte ich.

Und was war nun wirklich passiert?

Eigentlich hatte ich eine Email an die Redaktion geschrieben und mich darüber gewundert, warum ein ausgesprochener Impfgegner in einem Leserbrief fast eine halbe Seite lang seine eigenen schlimmen Erlebnisse mit vermuteten Impfschäden aufgrund einer Tetanusimpfung ausbreiten durfte. Der Leserbrief gipfelte darin, dass er sich seit seiner Frühpensionierung 8 Jahre lang selbst zum Impfexperten ausgebildet habe und jetzt von Impfungen abrate, weil die Impfschäden viel zu riskant seien. Er hat viele Zahlen aus "Studien" zitiert und die üblichen Arien der Impfgegner verwendet.

Eigentlich wollte ich wirklich einen Leserbrief mit Fakten schreiben. Dann dachte ich mir, es wird ja wohl hoffentlich jemand mit medizinischer Ausbildung schreiben und den Leserbrief widerlegen.

Leider ist das fast zwei Wochen lang nicht passiert, deshalb schrieb ich dann folgendes:

vor knapp zwei Wochen gab es einen in meinen Augen sehr fragwürdigen Leserbrief von K. J., in dem er sich massiv gegen das Impfen ausgesprochen hat, weil er selbst - angeblich - durch das Tetanus-Impfen geschädigt und zum Frührentner wurde.

Abgesehen davon, dass er nicht die Kenntnisse hat, um seinen Rundumschlag gegen das Impfen fachlich und kompetent zu untermauern, sorgt so ein Leserbrief zu Verunsicherung unter Eltern, die dann vielleicht ihre Kinder nicht impfen lassen, wenn sie eine solche Horrorgeschichte lesen und das Verhältnis von Impfrisiko zu Impfschadenrisiko selbst nicht bewerten können.

Selbst wenn ursächlich die Impfung die Ursache war, ist wissenschaftlich hervorragend erforscht, dass Impfen generell sinnvoll ist - Einzelfälle sind immer tragisch, das streite ich auch gar nicht ab, aber sie dürfen nicht ohne Prüfung Grundlage für Entscheidungen werden.

Ich selbst bin kein Mediziner, meine Frau ist Tierärztin, aber als Elternteil finde ich beunruhigend, wenn die WZ einem radikalen Impfgegner auf diese Weise ein Forum bietet und dem überhaupt nichts entgegensetzt.

Ich hätte gehofft, dass Sie als Reaktion darauf - z.B. mit einem Kinderarzt zusammen - einen redaktionellen Beitrag veröffentlichen, der das Impfen und die jeweiligen Risiken sachlich beschreibt und die Irrationalität der Impfgegner auf's Korn nimmt.

Ansonsten verweise ich auf die Diskussionen, die z.B. beim Blog von Kinderdoc (das sind 3 Links!) und auf der Facebookseite von hr1 toben.

Und eine schöne Zusammenstellung der Mythen, mit denen Impfgegner gern argumentieren. 
Überraschenderweise hat die Redaktion sich aber nicht selbst als Adressaten empfunden und meine Email kurzerhand als Leserbrief veröffentlicht. Und dummerweise habe ich meine mitgeschickten URLs nicht bei goo.gl abgekürzt, und die WZ hat drei davon wirklich in voller Länge als Fußnote gedruckt. Natürlich tippt so etwas niemand ab. Deshalb hier alles nochmal bequem zum Anklicken ;)

22.04.2015

OpenOffice-Dokumente mit perl-Skript bearbeiten

Offene Dateiformate sind eine tolle Sache!

Das merke ich immer wieder bei lustigen Problemen, wenn mir z.B. jemand ein Office-Dokument schickt und ich damit irgendetwas total langweiliges erledigen soll.

Es macht viel mehr Spaß, dafür ein Programm oder ein Skript zu schreiben und den Computer die Arbeit machen zu lassen, statt selbst dröge Arbeiten zu erledigen, die nur aus Wiederholungen von Tastendrücken und Mausbewegungen bestehen!

Letzte Woche hatte ich so einen Auftrag: ein Kollege schickte mir eine Excel-Datei mit mehreren Tabellenblättern und bat mich, daraus mehrere Tables einer Datenbank zu befüllen.

Mein erster Ansatz war, jedes Blatt als Textdatei (CSV) abzuspeichern und mit ein wenig Skripting die SQL-Befehle pro CSV-Datei zu generieren.

Der nächste Gedanke war einiges cooler und hat mir deshalb noch viel besser gefallen: ich speichere die Excel-Datei im OpenOffice-Format (ODF=OpenDocumentFormat) ab und lasse ein Skript die ganze Arbeit machen! Die Datei enthält um die 15 Tabellenblätter - allein vor dem Abspeichern von 15 CSV-Dateien in Handarbeit grauste es mir schon!

Hinzu kommt, dass mein Arbeitgeber OpenOffice als Standardwerkzeug und Standardformat festgelegt hat und es somit vollkommen natürlich ist, mit dem OpenDocument-Format zu arbeiten. Erwähnte ich schon, dass mein Arbeitsplatz mit Linux ausgestattet ist?

Ein ODF-Dokument ist eigentlich ganz einfach aufgebaut: es ist im Wesentlichen eine zip-Datei und der Inhalt ist immer in der Datei content.xml zu finden. Alles andere ist Beiwerk (Stylesheets, Bilder, ...), das ich für meinen Zweck ignorieren kann.

Natürlich verwende ich perl zum Programmieren meiner Umwandlungsskripte, und natürlich gibt es ein Modul für jeden Zweck. Für die Verbindung zu OpenOffice gibt es sogar mehrere, und ich habe mir OpenOffice::OODoc ausgesucht. Mir ist nämlich in der Beschreibung aufgefallen, dass es eine ganz bestimmte Funktion gibt, die haargenau das erledigt, was ich mir als Lösungsweg überlegt hatte: den Tabelleninhalt als CSV-Text auszuliefern.

Damit war mein perl-Skript plötzlich fertig, kaum dass ich 20 Zeilen geschrieben hatte, wobei das meiste davon sogar ein fast fertiges Beispiel aus der man-page war! Ich musste nur ein wenig die Daten massieren, als ich mit einem Testskript anfing und die ersten Daten probeweise auf dem Bildschirm ausgeben ließ.

Das folgende Skript erledigt nun den ersten Teil meiner Aufgabe: es zerlegt ein OpenOffice-Spreadsheet in mehrere CSV-Dateien, eine pro Tabellenblatt.
Als Ziel schwebt mir vor, dass die temporären CSV-Dateien gar nicht mehr gebraucht werden und ich direkt den SQL-Code erzeuge, aber ich denke, die Umwandlung von .ods in .csv kann man immer mal brauchen.

Einzige Bedingung: der Name des Tabellenblatts sollte sinnvoll gesetzt sein, weil daraus nämlich der Name der CSV-Datei gebildet wird.  Wenn man das nicht macht, heißen die Dateien einfach "Sheet1.csv", "Sheet2.csv" usw.

#!/usr/bin/perl -w
use OpenOffice::OODoc;
sub out {
  my ($table,$data)=@_;
  my $f=$table->{'att'}->{'table:name'}.".csv";
  return unless (open(OUT,">",$f));
  print STDERR "# $f\n";
  print OUT $data;
  close(OUT);
}
my $file=shift||"file.ods";
my $doc = odfText(file => $file);
foreach my $table ($doc->getTableList()) {
  $doc->normalizeSheet($table);
  my $data = $doc->getTableText($table);
  $data=~s!(<<|>>)!!msgo;
  $data=~s!^[\s;]*$!!msgo;
  $data=~s!;$!!msgo;
  chomp($data);
  out($table,$data);
}
Die Ausgabe-Funktion bildet den Dateinamen aus dem Attribut table:name des Blatts. Die eigentliche Umwandlung findet in der Methode getTableText statt: hier wird ein gesamtes Tabellenblatt mit einstellbaren Trennzeichen für Spalten und Zeilen in CSV-Text zurückgeliefert. Manche Blattnamen werden von "<<" und ">>" eingerahmt, was ich natürlich in Dateinamen nicht brauchen kann, deshalb werden die Daten noch etwas gesäubert. Welche Blattnamen es gibt, kann man mit getTableList erfragen.

Natürlich kann man auch andere Methoden einsetzen, um einzelne Zeilen, Spalten oder Zellen zu adressieren, und man kann mit diesem perl-Modul auch Daten ändern und die Änderungen abspeichern. Ein geniales Modul! Wie gesagt, die bequemste Funktion war für mich die Umwandlung in CSV mit einem einzigen Aufruf.

[Update: OpenOffice optimiert die Tabellenstruktur in der internen Verwaltung (content.xml), wenn mehrere Zellen denselben Inhalt haben; deshalb muss man vor der Benutzung der Methode getTableText das XML wieder "entzerren". Dazu setze ich vor das Auslesen der Tabelle die Methode normalizeSheet ein. ]

Und zack!, schon ist der erste Teil der Aufgabe erledigt - das Auslesen einer ODF-Datei.

Den zweiten Teil - die Umwandlung von Text in SQL - gibt es bei der nächsten Märchenstunde.

Und jetzt am Schluss verrate ich noch ein Geheimnis: ich erzähle, wie man dieses Modul in sein eigenes perl integriert (Punkte zwischen [...] optional).
  1. Modul herunterladen
  2. Auspacken
  3. In das Directory wechseln
  4. perl Makefile.PL
  5. make
  6. [make test]
  7. make install
oder noch viel bequemer mit dem CPAN-Modul:
  1. perl -MCPAN -e 'install OpenOffice::OODoc'
[Update 20150521: Umbruch im perl-Skript repariert]
[Update 20180810: dito]