iFortune

Ich habe mal wieder etwas programmiert, was euren Alltag weder leichter, noch schwerer, aber dafür eventuell etwas lustiger macht. So wie die Sex-Würfel. HAHA!
Gestern habe ich ein kleines Python-Programm programmiert, mit welchem man eine Fortune-Datei anlegen kann, die ihre Fortunes aus einem Twitter-Archiv zieht.

Zur Erklärung: Fortune ist ein Programm, welches einen Spruch ausgibt, wenn es im Terminal ausgeführt wird. Das sieht dann beispielsweise so aus:

fortune

Der zweite Spruch verdeutlicht, was das Programm eigentlich imitiert: Glückskekse, oder auch Fortune Cookies.
Der fünfte Spruch ließ mich kurz stutzen. Ich wähnte mich schon in der Riege illustrer Personen, deren Zitate in Fortunes gespeist werden, den gleichen Spruch hatte ich nämlich auch schon gemacht. Das war aber nicht der gleiche, sondern derselbe. Das war mein Spruch. Der Command „fortune“ wählt nämlich zufällig einen Spruch aus einer Hand voll Dateien aus, worunter sich mittlerweile die ratschlagfiona.dat befindet. Außerdem hätte mir auch auffallen können, dass das der einzige deutsche Spruch war. Ich werde mich vermutlich nie in der illustren Runde von Personen befinden, deren Zitate in fortunes standardmäßig eingespeist werden.

Wie konnte das nur passieren?
Ganz einfach. Jedoch: Ein sehr kluger Mensch riet mir dazu, mein Vorhaben in Einzelschritte zu zerlegen. Das ist sehr klug, weil das alle möglichen Autoren von Büchern, die ich über’s Programmieren gelesen habe, auch gesagt haben. Also erkläre ich mal in Einzelschritten, was ich tun wollte, musste und mittlerweile habe.

Was ich wollte: 
Ein Fortune, das mir statt Fefe-Aphorismen, Sci-Fi-Zitaten oder  Glückskeks-Philosophie etwas anderes, nämlich Tweets von @ratschlagfiona ausgibt. Dabei möchte ich natürlich ein Programm schreiben, das für andere nutzbar ist. Für den unwahrscheinlichen Fall, dass sie die Tweets von einem anderen Account gerne in ihrem Terminal hätten.

Was ich tun musste:

1. Twitter-Archiv von @ratschlagfiona herunterladen.

2. Die darin enthaltene csv-Datei muss bearbeitet bzw. bearbeitbar gemacht werden.

3. Die Tweets enthalten viel Metadatenkram den ich nicht will. Weg damit.

4. Die übriggebliebenen Tweets in eine neue Datei schreiben.

5. Die Tweets müssen jeweils in einer Zeile liegen und durch ein %-Zeichen getrennt sein.

6. Diese Datei muss in den Pool von Fortune-Dateien rein und genutzt werden.

Was ich habe

Die Tweets in der csv-Datei sehen so aus:

"342921659667345408","","","","","2013-06-07 08:31:09 +0000","web","Liebe ist immer noch die schönste Prokrastination! <3"
"337189811200860163","","","","","2013-05-22 12:54:50 +0000","web","Geld an sich hat keinen Wert. Wenn du weder Zeit noch Freude am Getauschten hast, solltest du vielleicht deinen Job kündigen."
"337189294022205440","","","","","2013-05-22 12:52:47 +0000","web","Pöbelnde, sexistische Autofahrer haben eh zuviele Rückspiegel!"

Was ich haben will
ist eine fortune-file und die ist so aufgebaut:

"Liebe ist immer noch die schönste Prokrastination! <3"
%
"Geld an sich hat keinen Wert. Wenn du weder Zeit noch Freude am Getauschten hast, solltest du vielleicht deinen Job kündigen."
%
"Pöbelnde, sexistische Autofahrer haben eh zuviele Rückspiegel!"

Was ich getan habe:

1. Mich eine Weile rumärgern und relativ unsystematisch nicht so wirklich etwas tun. Ich hatte eine Weile versucht, an der csv-Datei in calc rumzuhantieren, bis mir irgendwann dämmerte, dass das eine ziemlich bescheuerte Idee ist. Solche Aufgaben, wie Elemente einer Zeile abschneiden und dann etwas dazwischen schreiben klingen sehr stark danach, als würden sie mich davon abhalten, etwas wichtigeres zu tun und als sollte mein dummer, aber sehr treuer Computer das übernehmen.

2. Trotzdem viel zu viel Zeit damit verbringen.

3. Auch mal jemand anderes als Google nach Hilfe fragen.

Soviel zu den Metadaten. Ich probierte noch ein paar Dinge aus und kam meinem Ziel durchaus auch näher aber nicht nah genug. Dann bot sich benthor an, mir zu helfen und wir vereinbarten einen Termin, den ich wieder absagte. Dann vereinbarten wir einen neuen Termin für Mittwoch um 8!UHR!MORGENS!

Das Treffen mit Leuten zum Programmierenlernen hat meiner Erfahrung nach den Vorteil, dass man unheimlich viel nebenher lernt. Zum Beispiel, dass bei Linux die Ordner in den Ordnern immer oben stehen. Außerdem lernte ich, dass meine Festplatte voll ist. Darüber hinaus erfuhr ich, dass die Köche bei der GPN ziemlich kranke Schweine sein müssen, wenn sie ernsthaft mit Ohai-Brause kochen!

Benthor zeigte mir ersteinmal ipython, eine interaktive Shell zur Python-Programmierung. Alle, die Python lernen, sollten sich schleunigst ipython installieren. Mit tab completion kannst du beispielsweise die möglichen Befehle zu dem von dir eingegebenen Teil anzeigen lassen:

str

Und wenn du hinter einen Befehl ein Fragezeichen setzt, bekommst du gleich eine Erklärung dazu, die verständlicher ist, als die pädagogische Katastrophe, die sich in meinen manuals abspielt.

file

Mit ipython war es relativ leicht, die notwendigen Befehle herauszusuchen und sie gleich live anzuwenden und auszuprobieren. Mit benthors Hilfe und Geduld und seinem Absehen von Fragen wie „Naaaaa? Was kommt da jetzt hin???“ brauchte ich auch nur zwei Stunden um die 15 Zeilen Code zu schreiben. Dazu sei aber gesagt, dass ich wirklich etliche Zwischenfragen gestellt habe, um auch wirklich alles und alles darüber hinaus zu verstehen. Danke nochmal für dein Verständnis, Geduld und lustige Gestikulation, benthor!

Hier das Ergebnis:

#1
#!/usr/bin/python
#2
lesdatei = open("tweets.csv", "r")
schreibdatei = open("ratschlagfiona", "w")
#3
liste = lesdatei.readlines()
#4
for element in liste[1:]:
    felder = element.split(",", 7)
    tweet = felder[7]
    fortune = tweet + "%\n"
    if fortune[1] != "@":
    schreibdatei.write(fortune)

Die ersten Zeilen sind recht schnell erklärt:

#1
Hinter der Raute und dem Ausrufezeichen steht eine Anweisung an das Betriebssystem, damit es weiß, welchen Interpreter es braucht. Das ist aber in zufallssex nochmal genauer erklärt.

#2
Dann wird die csv-Datei geöffnet. Das „r“ in der Klammer bedeutet, dass ich sie lesen möchte, das kann aber auch weggelassen werden, da es sich dabei um die Standardaktion handelt. Die Datei in welche ich reinschreiben will, wird ebenfalls geöffnet, bzw. erstellt, sofern sie noch nicht existiert. Beachte: Die Dateien müssen in demselben Verzeichnis liegen wie das Programm, ansonsten kann auch einfach der Pfad reingeschrieben werden.
Die Dateien „adressiere“ ich im Programm jetzt mit lesdatei bzw. schreibdatei.

#3
Dann wird mit dem Befehl readlines die lesdatei zu einer Liste gemacht, die ich jetzt „liste“ genannt habe.

#4
Darauf folgt eine heitere for-Schleife. Ich erkläre das mal in ganz kleinen Schritten, Zeile für Zeile:

for element in liste[1:]:

Ich gebe in der ersten Zeile der Schleife an, dass die einzelnen Elemente der Liste „elemente“ heißen und dass ich erst beim zweiten Element mit der for-Schleife anfangen will. Daher die „1“ in eckigen Klammern, da bei Null angefangen wird zu zählen. Das mache ich, weil in der ersten Zeile irgendein unnützer Kram steht, der nicht lustig ist.

 felder = element.split(",", 7)

In der zweiten Zeile splitte, also trenne ich die Elemente entlang der Kommata. Die sind nämlich die delimiters, die in der csv-Datei einige Meta-Daten und dann die Tweets voneinander trennen. Die voneinander getrennten Teile nenne ich „felder“. Ich höre beim 7. Feld auf, da dort der Tweet beginnt, der unter Umständen Kommata enthält, die nicht als delimiter verstanden werden sollen. Daher gebe ich den sogenannten „maxsplit“ an, in diesem Falle eine 7.

tweet = felder[7]

Das siebte Feld der einzelnen Zeilen ist für mich interessant, denn darin steht der eigentliche Tweet. Ich belege die Variable „tweet“ mit dem, was im siebten Feld steht. (Nicht vergessen, es handelt sich dabei eigentlich um das 8. aber wir fangen bei Null an zu zählen!)

fortune = tweet + "%\n"

Jetzt füge ich jedem einzelnen tweet noch ein % hinzu und eine \n (newline), denn das ist für das Format einer fortune-Datei notwendig. Mit dem Ergebnis wird die Variable „fortune“ belegt.

 if fortune[1] != "@":
 schreibdatei.write(fortune)

Jetzt möchte ich noch verhindern, dass @-Replys in die fortune-Datei übernommen werden, da die ohne Kontext nicht besonders viel Sinn ergeben. Ich habe in der csv-Datei gesehen, dass die @-Zeichen an zweiter Stelle nach den Anführungszeichen kommen, also prüfe ich, ob im zweiten Element [1] der fortunes ein @ steht. Wenn das zweite Element ungleich (!=) @ ist, wird das fortune endlich in die Datei geschrieben. Wenn die Bedingung nicht stimmt, weil es sich um eine Reply handelt, wird der Schritt übersprungen und die Schleife von vorne begonnen.

Damit das nicht falsch verstanden wird: Ich schreibe, dass die Schritte hier mit allen Elementen der Liste durchgeführt werden, aber die for-Schleife grast natürlich jede Zeile einzeln ab, bis sie am Ende der Datei angelangt ist.

Fertig!

Naja!

Noch nicht ganz!

Was ich noch machen muss:

Jetzt habe ich im günstigsten Falle eine neue Datei beschrieben namens ratschlagfiona. Die muss natürlich noch in das richtige Verzeichnis geworfen werden. In diesem Fall unter /usr/share/games/fortunes – dann wird sie noch zu einer Binärdatei umgewandelt. Dafür gehe ich in das Verzeichnis mit cd und wende dann den befehl strfile an. Das sieht dann so aus:

root@lorem:/home/fiona# cd /usr/share/games/fortunes/
root@lorem:/usr/share/games/fortunes# strfile ratschlagfiona
"ratschlagfiona.dat" created
There were 192 strings
Longest string: 287 bytes
Shortest string: 12 bytes

Ich hoffe, das wurde einigermaßen verständlich erklärt. Aber ein paar Fragen bleiben vielleicht noch. Witzig ist natürlich, dass ihr gar nicht das Twitter-Archiv von ratschlagfiona habt. Ich könnte aber die von mir äh manipulierte ratschlagfiona.dat irgendwo zur Verfügung stellen.

Was ich noch machen müsste irgendwann mal…

Das Programm muss auf jeden Fall noch ein wenig ausgebessert werden. Schöner wäre es, wenn das Programm Tweets direkt vom Online-Account einspeist, allerdings bin ich etwas skeptisch gegenüber Twitter-APIs. Besser wäre es auch, wenn ich die Dateien, mit denen ich arbeiten will, nicht in den Code schreibe, sondern per Einlesen, z.B. mit raw_input oder Ähnlichem beziehe.

Was also damit getan werden kann, ist eine fortune-Datei mit Tweets von einem Twitter-Archiv, zu welchem Ihr Zugang habt, bestücken. Vielleicht habt ihr ja auch so einen Besserwisser-Account wie @ratschlagfiona und wollt die csv-Datei und eure Tweets mit eurer Umwelt teilen.
Was auch ginge, wäre eine csv-Datei selber anlegen und durch dieses Programm jagen, wobei das Programm dann vermutlich auf die Hälfte gekürzt werden könnte oder verändert werden müsste.

Eine sinnvolle Erweiterung oder Änderung des Programms, bzw. ein sinnvolles anderes Programm wäre also eines, das auch die Verwendung von Tweets von anderen erlaubt. Mir fällt da gerade nur der Account vom Dalai Lama ein, wobei der ja schon ganz schön 90er ist.

Puh. Gar nicht so einfach, Programme für jemand anderes als sich selbst zu schreiben. Aber ich kann ja auch auf github schauen, ob nicht jemand Bock…

Apropos Bockbier!
Ich bin heute Abend zu Gast im Podcast „Wir müssen reden“ mit Michael Seemann und Max Winde und erzähle dort bestimmt auch etwas über Fortune, Fortran und Fiona. Schaut doch im Chat vorbei, schaltet ein, schreibt in die Kommentare, wenn euch etwas einfällt, was ich bis heute Abend recherchieren und ansprechen oder wenn ich eure Verwandten grüßen soll.

%d Bloggern gefällt das: