@sportgangg: Das Problem liegt beim `open()`. Der Modus 'w' bedeutet „Öffne eine neue, leere Datei zum Schreiben”. Wenn eine mit dem gleichen Namen schon existiert(e), ist deren Inhalt so natürlich verloren. Du möchtest Daten an eine vorhandene Datei anhängen. Dafür ist der 'a'-Modus (wie „append”) vorgesehen. Oder Du öffnest die Datei einmal ausserhalb der Schleife zum schreiben.
Wenn Du mit CSV-Daten arbeiten willst, solltest Du Dir auch mal das `csv`-Modul aus der Standardbibliothek anschauen.
Sternchenimporte sollte man vermeiden, weil dann sehr schnell nicht mehr nachvollziehbar ist, wo welcher Name her kommt. Ausserdem scheint auch gar nichts aus `numpy` verwendet zu werden!?
Pfadnamen sollte man mit `os.path.join()` und nicht mit ``+`` zusammen setzen. In Deinem Fall wäre das `glob`-Modul sehr nützlich.
Dateien sollte man mit der ``with``-Anweisung öffnen. Dann braucht man sie nicht explizit schliessen, kann sich aber sicher sein, dass sie in jedem Fall wieder geschlossen werden, egal auf welche Weise der Code-Block verlassen wird.
Einbuchstabennamen sind ausser bei den üblichen Schleifenzählern für ganze Zahlen (`i`, `j`, `n`, `m`, …) oder wenn sie auf kompakte Ausdrücke wie „list comprehensions” oder Generatorausdrücke beschränkt sind, keine gute Idee. Namen sollten dem Leser vermitteln wofür ein Objekt im Quelltext steht. In der Regel bedeutet das auch, dass der Typ nicht in den Namen gehört (`row_string_list`), weil der sich eventuell im Laufe der Entwicklung ändern kann, und dann muss man entweder den Namen überall anpassen, oder man hat irreführende Namen im Quelltext stehen. `f` könnte man zum Beispiel `lines` nennen und `row_string_list` könnte man `parts` nennen oder `row` und das was Du `row` nennst dafür `line`.
Statt `count_row` manuell zu führen, sollte man die `enumerate()`-Funktion verwenden.
Du weist `length` an zwei Stellen einen Wert zu, der aber nirgends verwendet wird.
Muss man um die Startzeile zu finden, diese tatsächlich in ihre Bestandteile zerlegen? Würde ein ``line.startswith('Summary of CHF Data')`` nicht eindeutig sein?
Ausdrücke wie ``sequence[len(sequence) - n]`` sind unnötig kompliziert weil ein einfacher negativer Index das gleiche bewirkt.
Was soll der `str()`-Aufruf beim Schreiben von `Heat_Flux_B` bewirken?
Da die beiden extrahierten Zeilen gleich behandelt werden und sich die Namen nur durch einen Zusatz unterscheiden, sollte man hier vielleicht keine Einzelnamen verwenden, sondern eine Liste an die man die Werte der beiden Zeilen anhängt.
Und wenn die Zeilennummer grösser als die für den zweiten Wertesatz wird, könnte man die Schleife abbrechen, denn die Zeilen danach interessieren ja nicht weiter.
Deine Einrückung und die Leerzeichensetzung bei Zuweisungen weicht vom
PEP 8 -- Style Guide for Python Code ab. Insbesondere bei der Einrückung sollte man sich an die vier Leerzeichen pro Ebene halten, sonst wird es kompliziert Quelltext mit anderen auszutauschen. Wenn man es wie Du innerhalb des eigenen Quelltextes nicht *einheitlich* macht, kann es auch bei eigenem Quelltext problematisch werden Quelltext an andere Stellen zu verschieben oder in andere Skripte zu übernehmen.
Dann wären wir bei so etwas (ungetestet):
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv
import os
from glob import glob
def main():
folder_path = '/home/georg/Auswertungen/out/'
#
# Offsets of the two lines of interest relative to the start of
# the CHF data.
#
offset_a, offset_b = 81, 93
#
# Offsets of MDNBR, heat flux, axial location, rod, and subchannel
# within a row.
#
value_offsets = [-3, -4, -5, -2, -1]
with open('test.csv', 'w') as result_file:
writer = csv.writer(result_file, delimiter=';')
for path in glob(os.path.join(folder_path, '*.out')):
#
# Get start line of the last CHF data summery in the file.
#
with open(path, 'r') as lines:
chf_data_offset = None
for i, line in enumerate(lines):
if line.startswith('Summary of CHF Data'):
chf_data_offset = i
assert chf_data_offset is not None, 'No CHF data found.'
#
# Extract the two rows and write them into the result CSV file.
#
with open(path, 'r') as lines:
offsets = [
chf_data_offset + offset_a, chf_data_offset + offset_b
]
result = list()
for i, line in enumerate(lines):
if i in offsets:
row = line.split()
result.append([row[n] for n in value_offsets])
elif i > offsets[-1]:
break
assert len(result) == 2, 'Premature end of file'
writer.writerows(result)
if __name__ == '__main__':
main()
Das ist von der Länge und Komplexität für meinen Geschmack schon hart an der Grenze für eine einzige Funktion. Ich würde hier wohl schon mindestens die Verarbeitung einer Einzeldatei in eine eigene Funktion auslagern.
Von der Effizienz her wäre es übrigens ungünstig wenn es nur einen einzigen 'Summary of CHF Data' pro `*.out`-Datei gäbe, denn dann müsste man in der ersten Schleife gar nicht die komplette Datei durchsuchen, sondern könnte nach dem ersten Fund abbrechen. Man müsste nicht mal die Datei zweimal öffnen, sondern könnte nach dem Fund der Startzeile die entsprechende Anzahl von Folgezeilen überlesen, bis man jeweils bei den Interessanten angekommen ist. In dem Fall könnte das so oder so ähnlich aussehen (ungetestet — insbesondere die Offset-Werte könnten hier um eine Zeile daneben liegen):
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv
import os
from glob import glob
from itertools import dropwhile, islice
from operator import itemgetter
def main():
folder_path = '/home/georg/Auswertungen/out/'
#
# Offsets of the two lines of interest relative to the start of
# the CHF data.
#
offset_a, offset_b = 81, 93
#
# Gets MDNBR, heat flux, axial location, rod, and subchannel
# from a row.
#
get_values = itemgetter([-3, -4, -5, -2, -1])
with open('test.csv', 'w') as result_file:
writer = csv.writer(result_file, delimiter=';')
for path in glob(os.path.join(folder_path, '*.out')):
with open(path, 'r') as lines:
chf_lines = dropwhile(
lambda line: not line.startswith('Summary of CHF Data'),
lines
)
writer.writerows(
[
get_values(islice(chf_lines, n, n + 1).next().split())
for n in [offset_a, offset_b - offset_a]
]
)
if __name__ == '__main__':
main()