Gnarf. Die Parse-Funktion hat einen Fehler: Der letzte `run` wird nicht mehr an die Liste angehängt. Hier die Korrektur, ist sogar etwas einfacher geworden:
Code: Alles auswählen
def parse_runs(lines):
result = list()
run = None
for line in ifilter(None, imap(strip_comment, lines)):
if line.startswith('C='):
run = [line[2:]]
result.append(run)
else:
run.append(line)
return result
Zu meiner Verteidigung:
Die `strip_comment()`-Funktion ist nicht kompliziert. Da passieren letztendlich nur 3 Sachen nacheinander. Wenn das jetzt irgendwo mitten im Quelltext steht und man es im Zusammenhang verstehen muss, okay, aber so als einzelne Funktion sollte so etwas "erlaubt" sein. In einem "echten" Programm hätte ich noch einen Doctstring mit kurzer Beschreibung und einem Doctest mit '', ' # comment', ' spam ' und ' spam # comment #' hinzugefügt, und dann sollte es keine Verständnisprobleme mehr geben.
Ein einfaches ``line.startswith('#')`` reicht ja nicht, weil in der "Aufgabenstellung" steht, dass eigentlich auch Kommentare am Ende jeder Zeile möglich sein sollen. Und den Ausdruck um den Kommentar zu entfernen sollte man in eine eigene Funktion auslagern und damit nicht die Lesbarkeit Schleife belasten.
Beim Rest ist eigentlich nur `None` beim `ifilter()` etwas gewöhnungsbedürftig. Ansonsten sind `map()` und `filter()` IMHO ziemlich grundlegende Bausteine um Programme lesbarer zu gestalten, man braucht weniger explizite Schleifen. Ohne die beiden hat man mehr Quelltext in der Schleife und eine Einrücktiefe mehr:
Code: Alles auswählen
def parse_runs(lines):
result = list()
run = None
for line in lines:
line = strip_comment(line)
if line:
if line.startswith('C='):
run = [line[2:]]
result.append(run)
else:
run.append(line)
return result
Grundgedanke bei solchen Skripten ist bei mir immer `data driven programming`, also dass man den Datenstrom in den Mittelpunkt stellt und überlegt wie man mit den "Verbindungsbausteinen" `map`, `filter` und `reduce` zum gewünschten Ergebnis kommt. Ich schaue mir an was habe ich, was möchte ich und wie komme ich durch Transformation, Filtern und Zusammenfassen zum gewünschten Ergebnis. So kommt man in der Regel zu relativ kurzen, übersichtlichen Funktionen die eine klar definierte Aufgabe haben, z.B. ein Element des Datenstroms verändern, es auf etwas Testen oder mehrere aufeinanderfolgende Elemente zu jeweils einem neuen zusammenfassen.
Diese einzelnen Funktionen kann man einzeln Testen und dann mit den `itertools` zu einem Programm zusammenstecken.
Ich habe mich sogar etwas zurückgehalten. Die Kommentare hätte ich in eigenen Programmen vor der Parse-Funktion entfernt und aus der Parse-Funktion einen Generator gemacht.
@XtraNine: `imap()` und `ifilter()` sind die Gegenstücke zu `filter()` und `map()` und liefern Iteratoren statt Listen. Sparen also Speicherplatz.