Programm fertig, aber Schleife einbauen klappt nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Chris82
User
Beiträge: 21
Registriert: Sonntag 13. Juli 2008, 17:06

Ich hab den Fehler gefunden.
An einigen Stellen kommt einige Zeilen nach dem EOT ein weiteres EOT vor, also im Datenmüll, weil dazwischen kein neuer Header mehr ist.
An dieser Stelle bricht das Skript immer ab. Mir war das bisher nur noch nicht aufgefallen, weil das bei ca. 9000 Bildern die sich in einer Datei befinden, nur bei ein paar Prozent vorkommt.
Das sollte eigentlich nicht so sein und ist natürlich extrem ungünstig!
Muss ich mal überlegen, was ich da machen kann.
Chris82
User
Beiträge: 21
Registriert: Sonntag 13. Juli 2008, 17:06

So jetzt hab ich's endlich.
Gestern hatte ich meine Daten mit einem Notepad++ Makro bearbeitet und den Header immer an den Zeilenanfang gesetzt.
Dadurch muss ich EOT nicht mehr zwangsläufig verwenden.
Der Header beginnt immer mit "PF" und dann folgt ein Datum. "PF" kommt zwar ansonsten auch in der Datei vor, aber niemals am Zeilenanfang. Das hab ich eben nochmal schnell überflogen und dann getestet und es wurden alle Bilder mit richtigem Dateinamen neu abgespeichert.

Code: Alles auswählen

infile = open("C:/Test/testfile", "rb")                

while True:
    erstezeile = infile.readline()
    if not erstezeile: break #dateiende erreicht

    if erstezeile.startswith('PF'):
        outfile = open(erstezeile[0:17], "wb")
        outfile.write(erstezeile)
        for i in range(1, 225):
            outfile.write(infile.readline())
        outfile.close()

infile.close()
Vielen Dank für die Tipps und Hilfe. Hoffe mein Datenformat ändert sich jetzt nicht mehr.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

'More pythonic' wäre:

Code: Alles auswählen

for erstezeile in infile:
MfG
HWK
BlackJack

@HWK: Da muss man in diesem Fall aber aufpassen. Wenn man direkt über `infile` iteriert wird immer ein Stück im Voraus gelesen, dass heisst, das ``infile.readline()`` innerhalb der Schleife liest dann die falschen Zeilen.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Woran liegt das? Ich dachte: 'for line in filestream' liest immer genau eine Zeile. readline() liest dann die nächste Zeile und beim nächsten Schleifendurchlauf folgt die darauffolgende Zeile. Ich habe das auch schon in Scripts ohne Probleme verwendet. Als Beispiel zum Ausprobieren:

Code: Alles auswählen

import random, StringIO
f = StringIO.StringIO('\n'.join(str(x + 1) for x in range(20)))
for line in f:
    print line,
    for _ in range(random.randrange(4)):
        temp = f.readline()
        if temp:
            print '#', temp,
Bei allen Testläufen war bei mir die Kontinuität erhalten.
MfG
HWK
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Dann nimm mal eine "richtige" Datei. Gibt hier unter 2.5 einen ValueError ("Mixing iteration and read methods would lose data") und steht so auch in der Dokumentation:
In order to make a for loop the most efficient way of looping over the lines of a file (a very common operation), the next() method uses a hidden read-ahead buffer. As a consequence of using a read-ahead buffer, combining next() with other file methods (like readline()) does not work right. However, using seek() to reposition the file to an absolute position will flush the read-ahead buffer.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Ich hab's auch mit 'ner richtigen Datei probiert. War dann aber wohl Zufall, dass es unter 2.4 funktioniert hat. Wieder was gelernt.
MfG
HWK
Antworten