Firefox Bug?
Wow, ich habe geschlagene eineinhalb Stunden damit verschwendet, dass die Funktion document.evaluate nicht das Hauptdokument untersucht hat, sondern nur die Frames mit Ads. Vielleicht kommt es daher, dass ich beim include http://*.snopes.com* eingegeben habe und wegen des überflüssigen Punkt nach dem ersten Stern die Hauptseite (die von http://snopes.com geladen wird) nicht geladen wurde...
Ich benutze jetzt http://snopes.com* und http://ww.snopes.com* als includes. Dann funktioniert es. Meistens.
/edit: Ich weiß jetzt, dass
var spoiler = document.evaluate( '//noindex', article_text, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
Probleme macht. Ich vermute, "article_text" (eine Node, die den Artikeltext umspannt) verbiegt im Argument eine Referenz, die nicht wieder zurückgebogen wird.
Korrekturen.de Quiz
Einige Webseiten, über die ich so stolpere, könnte man prima zu einem Quiz umbauen. So zum Beispiel www.korrekturen.de oder Snopes.com. Anstatt dass mir gleich angezeigt wird, welche Schreibweise die richtige ist bzw. ob das Gerücht stimmt, könnte man diese Information hinter einem Klick verbergen. Eine erweiterte Version des Programms könnte dann eine Schaltfläche haben, auf der man anklickt, was man vermutet und die dementsprechend Punkte vergibt.
Klingt nach einer Aufgabe für Greasemonkey! Dabei kann ich das DOM-Model von Firefox ein bisschen üben, um dann irgendwann mal eine Thunderbird-Erweiterung in Angriff zu nehmen...
Ich werde mal mit Snopes.com üben, denn ich glaube, da ist es ein bisschen einfacher...
Lösung Teil 3: Mediziner nachschlagen
Das Skript muss man per
chmod +x
ausführbar machen und laufen lassen. (Dateipfad im Skript anpassen!)
Jetzt kommt ein bisschen Handarbeit:
Es bleiben 10 Menschen übrig, von denen nur zwei amerikanische
Vollzeit-Mediziner sind. Nur einer von den beiden hat eine medizinische
Entdeckung aus dem Bereich Physiologie gemacht, die ihm auch zu einem
deutschen Wikipedia-Artikel gereicht. Sein Nachname muss die Lösung
sein!
Mal sehen, was der Rest Familie heraus bekommt...
Lösung Teil 2: Namen untersuchen
Jetzt kommt ein kleines python-Programm, dass den Rest erledigt. Ich häng es einfach mal an und hoffe, dass die Kommentare ausreichen, es zu verstehen:
(Ich würde es gerne als herunterladbare Datei posten, aber Wordpress lässt mich nicht!)
#!/usr/bin/env python
#A short script that reads a raw list of physicians and
#prints out the ones that have their last name with all
#their characters in aphabetical ascending order, i.e.
#John Ace
import string
f = open("/home/martin/physician_list.txt","r")
lines = f.readlines()
#We'll examine the file line by line
for line in lines:
#Step One: Remove all garbage like whitespaces and newlines in each line
clean_one = string.strip(line)
#Step Two: Remove all additional info in each line that may be added in
#parantheses (i.e.: John Doe (physician))
#string.find() returns -1 when nothing is found!
garbage_start_index = string.find(clean_one, "(")
if garbage_start_index < 0:
garbage_start_index = len(clean_one)
clean_two = clean_one[:garbage_start_index]
#We will get a bit more white spaces, let's remove these again and make
#everything lowercase
clean_three = string.strip(string.lower(clean_two))
#Now lets get the last word in each string - assuming it's the last name
#Let's hope that the -1 for unsuccessful rfind doesn't mess things up.
#NOTE: OF COURSE IT DOES, STOOPID!
last_name_start_index = string.rfind(clean_three, " ")
if last_name_start_index < 0:
last_name_start_index = 0
clean_four = clean_three[last_name_start_index:]
clean_four = string.strip(clean_four)
#Now the final loop that checks for alphabetical order
#We use the ASCII file table for that - the ord() function gives us the
#ASCII index. The ASCII-table is alphabetical by default (although it starts
#somewhere 90-ish).
#What about umlauts?
#Names containing umlauts cannot be alphabetical, because umlauts are not part
#of the alphabet!
#When python reads the lines, it converts Umlauts to something like xc3xa4
#Luckily, this means that all names containing umlauts will be discarded
#automatically, since comes before x in the ASCII table!
#How does the algorithm work?
#The idea is to examine the word letter by letter and when coming to letter
#that is lower in the alphabet than the previous, we flip the match=1 to
#match=0.
#The first letter has to be an 'a' at least!
last_character = ord('a')
match = 1
for i in range(len(clean_four)):
#Just in case ord() gives any errors, we use try: except: - but I don't
#think it's really necessary.
try:
current_character = ord(clean_four[i])
if current_character < last_character:
match = 0
last_character = current_character
except:
match = 0
#Anything that still has match==1 must be alphabetical, so we'll display it.
#I use repr('string') for output, because I want to check if there are any
#weird control characters left in the string.
if match == 1:
print repr(clean_one)
Lösung Teil 1: Liste runterladen und aufräumen
Zuerst holen wir uns eine Liste aller amerikanischen "Physicians" (in denen die Physiologen enthalten sind) von Wikipedia. Das geht am einfachsten mit der Konsole (Ubuntu 08.10). Nach einigen Versuchen sieht der Befehl dazu am Ende so aus:
wget -qO- http://en.wikipedia.org/wiki/List_of_physicians | grep "<li>" | awk -F'title=' '{print $2}' | awk -F'"' '{print $2}' > physician_list.txt
Was der Befehl bedeutet:
Zuallererst wird mit
wget -qO- http://en.wikipedia.org/wiki/List_of_physicians
die Liste von Wikipedia heruntergeladen. Die Option -q lässt wget ohne
störende Statusmeldungen laufen, die Option -O- (großes "o" und dann
ein Minus) lässt wget den Output auf die Konsole umleiten, anstatt ihn
in einer Datei zu speichern
Die Schreibweise -qO- ist Kurzform von -q -O- , was erlaubt ist, weil
hier alle Optionen nur aus aus einem Buchstaben bestehen.
Jetzt wird das komplette HTML-Dokument über die berühmten Physiologen in die Konsole ausgegeben. Wenn man sich das Dokument näher anschaut, kann man erkennen, dass die Namen immer in einer Zeile mit <li>-Tags stehen, und zwar immer nach einem "title=". Das benutzen wir, um möglichst nur die Namen heraus zu fischen:
Den Pipe-Operator | benutzt man dazu, um den Output des vorgerigen Befehls an den nächsten Befehlt weiter zu geben. Das funktioiniert aber nur für den Output, der auf der Konsole ausgegeben wird. Daher muss man bei wget die Optionen -qO- angeben!
grep "<li>"
durchsucht die mit dem |-Operator übergebene Liste nach der Zeichenkette <li> und gibt nur die Zeilen weiter, die diese Zeichenkette enthalten.
Jetzt kommt ein kleines Programm:
awk -F'title=' '{print $2}'
awk ist eine eigene Skriptsprache, die zum durchstöbern von Tabellen
benutzt werden kann. Man kann awk über die Konsole benutzen, indem man
awk -Optionen '{programm}' benutzt. Das Programm muss in geschweiften
Klammern stehen, um als solches erkannt zu werden, und in Hochkommatas,
damit die Konsole nicht versucht, innerhalb des Programmes $2 etc.
aufzulösen.
Die Optione -F'title=' sagt, dass in der mit dem |-Operator
übergebenen "Tabelle" die Zeichenkette "title=" als Trennelement
zwischen Spalten angesehen werden soll. Das "Programm" print $2 führt
dazu, dass die zweite Spalte auf der Konsole ausgegeben wird.
Alle Physicians, die schon einen eigenen Wikipedia-Eintrag haben (hoffen wir mal, dass unserer darunter fällt), stehen in Zeilen, die mit " beginnen. Hinter dem Namen steht wieder ein ". Perfekt für einen weiteren awk-Befehl!
awk -F'"' '{print $2}'
Jetzt bleiben noch 352 Zeilen übrig, die mit
> physician_list.txt
in einer Datei gespeichert werden. Da steht zwar noch Unsinn drin, aber den fischen wir nachher raus.
Osterrätsel der F.A.S.
Das Osterwochenende wird traditionell mit der Lösung des Osterrätsels aus der Frankfurter Allgemeinen Sonntagszeitung verbracht. In diesem Jahr sind die Fragen arg medizinisch (was meinem Bruder einen unfairen Vorteil verschafft), so dass ich eine Lösung durch's Hintertürchen versuche.
Eigentlich muss man 16 knifflige Fragen lösen, um am Ende aus einem Buchstabenpool ein endgültiges Lösungswort zu erhalten. Über dieses Lösungswort wissen wir, dass es der Nachname eines amerikanischen Physiologen ist, wobei die Buchstaben des Nachnamen in alphabetischer Reihenfolge sein müssen (z.B. "John Ace").
Das lässt sich doch mit python finden!
Schritt 4: Lesen, lesen, lesen...
Die Sache mit dem Heimserver soll später mal so aussehen: Per DynDNS.org (oder irgendwann mal einem Skript auf einem kleinen, gemieteten Server) kann ich von überall aus sehen, welche IP mein Heimrechner hat. Naja, nicht ganz, mich interessiert erst einmal die IP des Routers, hinter dem er sitzt. Über den will ich dann an meinen Heimrechner kommen. Und das ist kompliziert, denn Port Forwarding ist für mich die allerschlechteste Lösung... (schließlich ist mein "Heimrechner" ab und zu auch woanders und ich möchte nicht jedes Mal den lokalen Netzwerkadministrator anhauen, ob er mal für mich sein System umkonfiguriert!)
Es gibt da ein Protkoll namens UPnP, das das Port-Forwarding quasi automatisch macht. Aber nicht jeder Router unterstützt dieses Protokoll. Da bleiben zwei Möglichkeiten: Abwarten und auf IPv6 warten oder versuchen, ein Skript zu schreiben, das mit Hilfe eines kleinen, externen Servers an die richtige IP-Adresse zum richtigen Zeitpunkt auf gut Glück ein "ACK" raussendet... ähh, vielleicht sollte ich mal ein Diagramm dazu malen.
Naja, ob das mindestens theoretisch geht, muss ich zu allererst nachlesen.…
/edit: Genau so hatte ich mir das vorgestellt!
Tweaks
Das Lüfter-Problem konnte ich mit einem BIOS-Update lösen. Dummerweise kann man das BIOS nur über DOS oder Windows aktualisieren. Glücklicherweise gibt es unetbootin und freeDOS!
Der Ubuntu Netbook Remix ist auch schon installiert - genau so wie die Codecs für DivX und mp3. Es fehlt nur noch ein SNES-Emulator und ich bin für jede Zugfahrt gerüstet!
Ach ja, eigentlich sollte es ja ein Heimserver werden...