Daten lesen und schreiben

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.
Antworten
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Hallo,

ich bin ein absoluter Programmier-Anfänger und arbeite mich gerade in Python ein. Ich habe mit "A Byte of Python" angefangen und lese nun im python-manual. Ich muss die nächsten Monate einen komplexen Prozess automatisieren. Falls ihr Literaturtipps habt, immer her damit.

Ich habe nun also mit einem ersten Mini-Teilprozess begonnen und komme nicht weiter.
Ich muss eine Textdatei erzeugen. Diese besteht aus Text mit Werten und Listen mit Geometriedaten(die irgendwann mal automatisiert vorgegeben werden sollen).
Die Geometriedaten werden aus einer großen Textdatei ausgelesen und sollen Abschnittsweise in eine neue Textdatei eingefügt werden.
Ich dachte mir, dass ich kleine Schritte in Richtung Ziel mache und habe mir folgende Textdatei zu Übungszwecken erstellt:

test_in.ibl

Code: Alles auswählen

ibl-file
11        12        13
14        15        16
17        18        19
Ich habe mittels Tutorial und googlen folgenden Code gebastelt:

Code: Alles auswählen

general = '''GEOMETRY TURBO
TOLERANCE    1e-006
'''
channel = '''NI_BEGIN CHANNEL
DISCRETISATION    10
   NI_BEGIN zrcurve
   ZR polyline
'''
f = open('gt_t01.geomTurbo', 'w')
f.write(general)
f.write(channel)
f.close()

import csv
with open('test_in.ibl', 'r') as csvfile:
    reader = csv.reader(csvfile)
    next(reader)
    for rows in reader:
        print(rows)
        with open('gt_t01.geomTurbo', 'a') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerows(rows)

Als Ergebniss bekomme ich folgendes ausgeschrieben:
gt_t01.geomTurbo

Code: Alles auswählen

GEOMETRY TURBO
TOLERANCE    1e-006
NI_BEGIN CHANNEL
DISCRETISATION    10
   NI_BEGIN zrcurve
   ZR polyline
1,1, , , , , , , , ,1,2, , , , , , , , ,1,3
1,4, , , , , , , , ,1,5, , , , , , , , ,1,6
1,7, , , , , , , , ,1,8, , , , , , , , ,1,9,
Die Geometriedaten sollen in Spalten angeordnet sein. Die Abstände spielen momentan keine Rolle. Die Kommas müssen raus. Mit dem delimiter verschwinden diese zwar, aber die Zahlen bleiben getrennt.
Desweiteren sollen die Daten in eine neue Zeile geschrieben werden. Dies habe ich erreicht indem ich die ' ' ' in eine neue Zeile verschoben habe. Macht man das so?

Kann mir jemand helfen? Da ich noch eine Menge in der Richtung machen muss, freue ich mich auch über Hilfe zur Selbsthilfe.

Grüße,
Stephi
Zuletzt geändert von Anonymous am Mittwoch 31. Mai 2017, 10:40, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@stephi_1011: Die Eingabedatei ist keine CSV-Datei, also weder wenn man das C in CSV als „comma“ liest, noch allgemeiner wenn man es als „character“ liest. Die Zellen sind nicht durch *ein* Zeichen getrennt, das man dann beim `csv.reader()` als Begrenzungszeichen angeben könnte. Also ist das `csv`-Modul zum lesen dieser Daten nicht geeignet. Hier wäre es wohl am einfachsten die Zeilen selbst aufzuteilen.

Wenn die Ausgabedaten nicht durch *ein* spezielles Zeichen getrennt werden sollen, dann ist auch die Ausgabe nicht im CSV-Format. Wenn ich mir die Beschreibung so durchlese, dann kannst Du die Zeilen doch eigentlich direkt durchreichen, ohne sie zu teilen und dann wieder zusammen zu setzen.

Du solltest konsquenter ``with`` benutzen, die Ausgabedatei in dem Programm nur *einmal* öffnen (und schliesen (lassen (durch ``with``))).

Beim öffnen von Textdateien in Python 3.x würde ich immer eine konkrete Kodierung explizit angeben. Und wenn man nur ASCII erwartet, sollte man auch das kenntlich machen, um vor Überraschungen sicher zu sein, wenn da doch einmal etwas anderes in den Dateien vorkommt.

Der Name `rows` ist falsch! Da werden keine Zeile*n*, mehrzahl, dran gebunden, sondern immer genau *eine* Zeile. Das ist auch der Grund für die Ausgabe in der Datei. Die `writerows()`-Methode erwartet nämlich eine Sequenz die Zeilen beschreibt, erhält aber eine Sequenz die nur eine Zeile beschreibt. Und jedes Element dieser Sequenz wird wiederum als Sequenz aufgefasst, welche die einzelnen Zellen enthält. `rows` enthält *eine* Zeile als Zeichenketten, also wird jede dieser Zeichenketten als kompletter Datensatz aufgefasst, dessen einzelnen Elemente durch das Trennzeichen abgegrenzt geschrieben werden. Und die einzelnen Elemente einer Zeichenkette sind die einzelnen Zeichen. Und genau das sieht man im Ergebnis.

Importe gehören an den Modulanfang, damit man dort schnell sieht wovon das Modul abhängt.
BlackJack

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3

GENERAL = '''GEOMETRY TURBO
TOLERANCE    1e-006
'''

CHANNEL = '''NI_BEGIN CHANNEL
DISCRETISATION    10
  NI_BEGIN zrcurve
  ZR polyline
'''


def main():
    with open('test_in.ibl', 'r', encoding='ascii') as ibl_file:
        next(ibl_file)  # Skip header line.
        with open('gt_t01.geomTurbo', 'w', encoding='ascii') as geom_turbo_file:
            geom_turbo_file.write(GENERAL)
            geom_turbo_file.write(CHANNEL)
            geom_turbo_file.writelines(ibl_file)


if __name__ == '__main__':
    main()
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Vielen Dank für deine Hilfe, BlackJack. Das sieht gut aus. Damit arbeite ich erstmal weiter :)

Ich kann die Daten aus meinem ibl-file nicht direkt weitergeben. Ich muss noch die Reihenfolge der Spalten ändern, aus manchen Bereichen die Werte von unten nach oben auslesen, Zeilen abzählen,... Möglicherweise muss ich das ibl-file separat bearbeiten(mit einem python-script). So weit bin ich aber noch lange nicht :roll: Ich arbeite mich langsam vor :wink:
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Hallo,

ich habe jetzt ein(oder eigentlich einige^^) Probleme mit dem bearbeiten meines ibl-files.

Hier ein Ausschnitt aus dem originalen ibl-file:

Code: Alles auswählen

begin section ! TE2
  begin curve
         132.371         46.0155         33.5768
         147.886         50.7319         36.7593
         163.404         55.4531         39.9493
         178.927         60.1782         43.1446
         194.454         64.9063         46.3437

begin section ! Hub
  begin curve
         139.500        0.000000        -110.000
         140.054        0.000000        -99.0020
         140.631        0.000000        -88.0140
         141.241        0.000000        -77.0415
         141.885        0.000000        -66.0842
         142.550        0.000000        -55.1371
Ich habe mir ein einfaches Testfile erstellt:
test_in.ibl

Code: Alles auswählen

1.0	2.0	3.0
4.0	5.0	6.0
Ich will nun die Reihenfolge der Spalten ändern und (später nur für einige Abschnitte aus meinem originalen ibl-file) von unten nach oben ausgeben lassen. Da ich mich wie gesagt langsam vorarbeite, betrachte ich die Schritte derzeit noch separat.

Mein Code

Code: Alles auswählen

import numpy as np
import os


path = r'U:\07_Python\03_Test'


def main():
    ibl_file1 = np.loadtxt(os.path.join(path, 'test_in.ibl'), dtype=float)
    ibl_file1[:, [0, 1]] = ibl_file1[:, [1, 0]]
    print(ibl_file1)

    np.savetxt(os.path.join(path, 'test_out.ibl'), ibl_file1, '%3.1f')

if __name__ == '__main__':
    main()

Als Ausgabe bekomme ich:

Code: Alles auswählen

[[ 2.  1.  3.]
 [ 5.  4.  6.]]
In mein test_out.ibl schreibt er aber:

Code: Alles auswählen

2.0	1.0	3.05.0	4.0	6.0
Meine Spalten sollen erhalten bleiben. Was habe ich falsch gemacht?
Die Orientierung der Zeilen habe ich mit 'np.flipud' geändert. Dort besteht das gleiche Problem.

Desweiteren arbeite ich daran mir die Werte abschnittsweise auszugeben. Ich muss mein ibl-file "durchsuchen". Ich muss zB. zu "begin section ! Hub" gehen, die folgende Zeile überspringen, die Reihenfolge der Spalten ändern, die Orientierung der Zeilen ändern und dann in die passende Stelle im geomTurbo-file schreiben. Das ganze muss ich mit ca 15 verschiedenen Abschnitten durchführen. Die Abschnitte haben immer drei Spalten mit Werten, aber sind unterschiedlich lang.
Ich versuche das gerade mit dem re-Modul zu lösen. Bin ich damit wohl auf dem richtigen Weg?
Zuletzt geändert von Anonymous am Dienstag 6. Juni 2017, 11:26, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@stephi_1011: kann es sein, dass Du versuchst, die Dateien per Windows-Notepad Dir anzuschauen, was Zeilenumbruchszeichen (\n) einfach ignoriert?
re-Modul ist unnötig kompliziert, da Du ja nur auf "begin xxx" prüfen mußt. Am besten schreibst Du eine Funktion, die Blöcke liefert, da reicht es ja, Zeilenweise zu arbeiten.
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Danke, Sirius3. Ja. Als ich vorhin meine Frage geschrieben habe, kam es mir schon seltsam vor, dass meine Ergebnisdaten hier korrekt dargestellt wurden. Darauf, dass es an meinem Editor liegen könnte bin ich aber nicht gekommen :oops:

Auch wenn ich beim Editor Zeilenumbrüche aktiviere, funktioniert es nicht. Was mache ich da am besten? Auf Notepadd++ umsteigen?
__deets__
User
Beiträge: 14533
Registriert: Mittwoch 14. Oktober 2015, 14:29

Genau. Notepad ist ziemlicher Mist.
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Also ich komme einfach nicht weiter. Wäre schön, wenn mir jemand ein Tipp geben könnte.

Ich muss eine Zeile suchen und die Werte ab der nächsten Zeile bis zur nächsten Leerzeile lesen und in eine neue Textdatei schreiben.
test_find.ibl:

Code: Alles auswählen

test for find:

begin # hub
1	2	3
4	5	6

begin # shroud
7	8	9
10	11	12

Ich versuche das in diesen Code reinzukriegen:

Code: Alles auswählen

import os


def main():
    path = r'U:\07_Python\03_Test'

    with open(os.path.join(path, 'test_find.ibl'), 'r') as in_file:
        line = in_file.read()
        search = 'begin # shroud'
        if search in line:
            print('vorhanden')
            print(line)
            with open(os.path.join(path, 'test_find_out.ibl'), 'w') as out_file:
                out_file.write(line)

        else:
            print('nicht vorhanden')


if __name__ == '__main__':
    main()
Aus Ausgabe bekomme ich

Code: Alles auswählen

vorhanden
test for find:

begin # hub
1       2       3
4       5       6

begin # shroud
7       8       9
10      11      12
Ich wollte die Datei eigentlich mit readlines() zeilenweise lesen, aber da findet er die Zeile nicht.

Was ich im Kopf habe ist, dass ich die gewünschte Zeile suche, 'search' eine Zeilennummer = 0 zuweisen ---> bis Leerzeile zählen und das dann in ausschreibe.
Ich habe einiges dazu gelesen, aber ich tue mich total schwer das auf mein Problem anzuwenden :K
BlackJack

@stephi_1011: `line` ist der falsche Name, denn Du liest da die *gesamte Datei* ein und nicht eine Zeile.

Man würde hier eher beide Dateien öffnen und dann die Eingabedatei zeilenweise lesen und sich ein Flag merken ob die aktuelle Zeile geschrieben werden soll oder nicht. Das setzt man wenn man das erste mal über die Startzeile gestolpert ist und man bricht ab wenn bei gesetztem Flag eine Leerzeile gefunden wird. Oder man löscht das Flag wieder, je nach dem ob das ganze mehrmals in einer Datei vorkommt.

Grundsätzlich frage ich mich aber ob Du da nicht zu viel auf unstrukturierten Textzeilen operierst und ob es nicht besser wäre das ganze beim einlesen in eine passende Datenstruktur zu überführen, dann die nötigen Veränderungen daran vornehmen und/oder es in eine Datenstruktur für das Ergebnis zu überführen, und die dann am Ende wieder formatiert in eine Datei zu schreiben.
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Danke BlackJack. Ich versuche erstmal zu verstehen was du geschrieben hast.

Ich melde mich wieder :wink:
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Hallo,

ich habe leider immer noch nicht richtig verstanden, was du mir geraten hast, BlackJack.

Ich habe jetzt zwei Skripte, die ich nacheinander ausführe. Im ersten habe ich mir eine "Suchfunktion" im ibl-file gebastelt und erstelle mir für die passenden Abschnitte neue ibl-Dateien und bearbeite diese. Im zweiten wird das geomTurbo-file erstellt. Dort lade ich dann an den passenden Stellen meine vorher korrekt formatierten ibl-Dateien ein. Es funktioniert :)

So, jetzt mein Problem:
Mein Script ist ziemlich lang, aber die meisten Schritte wiederholen sich einfach nur. Das ist ein Auszug aus meinem ersten Script:

Code: Alles auswählen


import os
import numpy as np

path = r'U:\\07_Python\03_Vorbereitung\


def main():

    with open(os.path.join(path, 'Test.ibl'), 'r') as in_file:
        row = in_file.readlines()

# ****suction*****************************************************************
# ***** Layer 1 
        searchtext = 'begin section ! Side1 #0'
        for i, line in enumerate(row):
            if searchtext in line:
                with open(os.path.join(path, 'Test_row1_s1_del.ibl'), 'w') as out_file:
                    out_file.writelines(row[i+2:i+45])
        
# ***** Layer 2
        searchtext = 'begin section ! Side1 #1'
        for i, line in enumerate(row):
            if searchtext in line:
                with open(os.path.join(path, 'Test_row1_s2_del.ibl'), 'w') as out_file:
                    out_file.writelines(row[i+2:i+45])
....
Ich meine, dass ich mal gesehen oder gelesen habe, dass man das auch verkürzt schreiben kann. Ich will also für einen "Layer" den Code schreiben und er soll das für alle Layer ausführen. Variabel sind dort die Zahl hinter # und der Name des out-files(die Zahl hinter dem _s).

Desweiteren muss ich die ganzen erstellten ibl-files nachher mit meinem zweiten Script öffnen und in das geomTurbo-file schreiben. Dabei bekomme ich eine Fehlermeldung, weil es zu viele zu öffnende Dateien sind. Das Problem wäre auch hier bestimmt zu lösen, wenn eine "allgemeine Form" hätte und er alle Dateien mit der Struktur öffnen würde oder??
Außerdem sollen alle Dateine mit "_del" später gelöscht werden.

Hier ein Auszug aus meinem zweiten Script:

Code: Alles auswählen

import os

path = r'U:\\07_Python\03_Vorbereitung\

Text_row1 = '''Hier steht 
ein
Text
'''
Text2_row2 = '''   Hier
 steht ein
anderer text
'''


def main():
    with open(os.path.join(path, 'Test_row1_s1_del.ibl'), 'r', encoding='ascii') as row1_s1:
        with open(os.path.join(path, 'Test_row1_s2_del.ibl'), 'r', encoding='ascii') as row1_s2:
            with open(os.path.join(path, 'Test_row1_s3_del.ibl'), 'r', encoding='ascii') as row1_s3:
                with open(os.path.join(path, 'gt_Test.geomTurbo'), 'w', encoding='ascii') as geom_turbo_file:
                    geom_turbo_file.writelines(row1_s1)
                    geom_turbo_file.write(Text_row1)
                    geom_turbo_file.writelines(row1_s2)
                    geom_turbo_file.write(Text_row1)
                    geom_turbo_file.writelines(row1_s3)
                    geom_turbo_file.write(Text_row2)


if __name__ == '__main__':
    main()

Ich habe schon gesucht, aber ich weiß nicht mal, wie das heißt, was ich da machen will^^
Meine fragen also: Geht das was ich da machen will? Wie nennt sich das? Oder lieber ganz anders machen?
BlackJack

@stephi_1011: Codewiederholungen vermeidet man mit Schleifen und/oder Funktionen. Wenn Du immer nahezu den gleichen Code hast, dann schreib eine Funktion die diesen Code einmal enthält und die Unterschiede als Argumente übergeben bekommt.

Der Name `row` für alle Zeilen einer Datei ist irreführend. Eine Liste mit Zeilen könnte man `lines` nennen. `row` für eine einzelne Zeile ist auch eher ungebräuchlich. Das ist eher eine Zeile in einer Tabelle, also beispielsweise ein Name für eine Liste mit Werten.

Konstantennamen werden per Konvention komplett in Grossbuchstaben geschrieben.

Da Du die Datei komplett in den Speicher liest ist in dem Code zu viel unter das ``with`` für die Eingabedatei eingerückt. Denn nach dem einlesen braucht man die Datei ja schon nicht mehr.

Die Abschnittsstartzeilen sind eindeutig, also kann man die Suchschleife nach dem man die Datei geschrieben hat, abbrechen, denn danach kommt der gleiche Abschnitt ja nicht noch einmal.

Zischenergebnis (ungetestet):

Code: Alles auswählen

def main():
 
    with open(os.path.join(PATH, 'Test.ibl'), 'r') as in_file:
        lines = list(in_file)
 
    searchtext = 'begin section ! Side1 #0'
    for i, line in enumerate(lines):
        if searchtext in line:
            with open(os.path.join(PATH, 'Test_lines1_s1_del.ibl'), 'w') as out_file:
                out_file.writelines(lines[i+2:i+45])
            break
   
    searchtext = 'begin section ! Side1 #1'
    for i, line in enumerate(lines):
        if searchtext in line:
            with open(os.path.join(PATH, 'Test_lines1_s2_del.ibl'), 'w') as out_file:
                out_file.writelines(lines[i+2:i+45])
            break
Und jetzt nehmen wir uns eine der beiden Kopien als Funktion heraus und ersetzen dann beide durch einen Aufruf der Funktion:

Code: Alles auswählen

def save_section(lines, start_line, filename):
    for i, line in enumerate(lines):
        if line.strip() == start_line:
            with open(filename, 'w') as out_file:
                out_file.writelines(lines[i+2:i+45])
            break


def main():
 
    with open(os.path.join(PATH, 'Test.ibl'), 'r') as in_file:
        lines = list(in_file)

    save_section(
        lines,
        'begin section ! Side1 #0',
        os.path.join(PATH, 'Test_lines1_s1_del.ibl')
    )
    save_section(
        lines,
        'begin section ! Side1 #1',
        os.path.join(PATH, 'Test_lines1_s2_del.ibl')
    )
Die beiden Aufrufe sind auch fast gleich. Da kann man die Unterschiede über eine Schleife heraus ziehen (ungetestet):

Code: Alles auswählen

def main():
 
    with open(os.path.join(PATH, 'Test.ibl'), 'r') as in_file:
        lines = list(in_file)

    for i in xrange(2):
        save_section(
            lines,
            'begin section ! Side1 #{0}'.format(i),
            os.path.join(PATH, 'Test_lines1_s{0}_del.ibl'.format(i + 1))
        )
Der Code ist allerdings nicht besonders robust was die Eingabedateien angeht. Ich habe mir mal ein paar IBL-Dateien im Netz angeschaut und die 'begin'-Zeilen müssen nicht klein geschrieben sein. 'Begin Section ! Something' wäre beispielsweise auch möglich. Und ich habe auch Dateien gefunden bei denen 'Open Archlength' in der ersten Zeile stand, und solche bei denen die beiden Worte auf zwei Zeilen verteilt waren. Ich würde also nicht unbedingt darauf bauen das zum Beispiel zwischen 'begin section' und 'begin curve' keine Leerzeile stehen darf, womit das ``i+2`` dann falsch wäre. Ausserdem kann in einem Abschnitt mehr als eine 'curve' stehen und das jede 'curve' genau 43 Zeilen umfasst, dürfte auch ein extremer Sonderfall sein.

Die Vorgehensweise an sich ist auch ineffizient, die Zeilen für jeden Abschnitt immer wieder von vorne zu durchsuchen. Man könnte auch die Datei *einmal* durchsuchen und jedes mal wenn man einen (passenden) Abschnitt gefunden hat, den in eine Datei schreiben.

Ich frage mich auch ob diese Dateien tatsächlich gebraucht werden, und wenn ob es dann wirklich lauter Einzeldateien sein müssen, oder ob es nicht wirklich besser ist die IBL-Datei in eine passende Datenstruktur einzulesen. Wenn ich das nach den Beispielen im Netz richtig sehe, bestehen die aus Abschnitten und diese Abschnitte können 'curve's enthalten, die aus Zeilen mit Koordinaten bestehen. Abschnitte und 'curve's werden mit 'begin section ! bezeichner' und 'begin curve ! bezeichner' eingeleitet, wobei die Gross-/Kleinschreibung der 'begin'-Teile variieren kann und das 'begin' muss *nicht* am Zeilenanfang stehen!

Man könnte so eine Datei also beispielsweise in eine Liste mit Abschnitten parsen, die ihrerseits eine Liste mit 'curve's enthalten, die eine 2D-Liste mit den Koordinaten enthalten. Oder, da Abschnitte und 'curve's Bezeichner besitzen, Wörterbücher statt Listen. Je nach dem wie auf die Daten zugegriffen werden muss und ob beispielsweise ein Speichern als JSON geplant ist und dabei die Reihenfolgen der Werte eine Rolle spielen.
stephi_1011
User
Beiträge: 8
Registriert: Mittwoch 31. Mai 2017, 08:58

Danke, für deine Antwort. Ich werde versuchen das mit einzuarbeiten.

Ich bekomme die ibl-Datei aus einem anderen Programm ausgegeben. Ich habe schon einige ibl-Dateien gesehen und die waren vom Aufbau her gleich.
Dass die curve bei i+2 beginnt, ist sehr wahrscheinlich. Dass sie bei i+43 endet, ist tatsächlich Zufall. Da ich mich, wie gesagt langsam vorarbeite, habe ich das erstmal so angenommen. Ich arbeite aber dran, dass das, sowie die Zahl der Layer variabel wird. Am Ende sollen am Anfang meines Prozesses alle möglichen Variablen in einem Dokument eingegeben werden und der Prozess soll durchlaufen werden. Ziel ist, diese Variablen zu verändern und anschließend zu vergleichen. Der Prozess ist komplex. Ich habe dafür noch drei Monate Zeit.
Ich wollte erstmal einen Prozess basteln der läuft und wenn dann (hoffentlich!) noch noch Zeit ist, verbessern.

Ich habe ja noch keine Programmiererfahrung. Deshalb weiß ich auch noch nicht, was so alles möglich ist. Ich sehe gerade nur, dass es so halbwegs funktioniert. Es "müssen" also keine Einzeldateien sein, aber anders habe ich es noch nicht hinbekommen. Ob der Prozess hier eine Sekunde länger braucht, ist für mich nicht interessant. Da die Einzeldateien anschließend gelöscht werden sollen, spielt das doch auch für den Speicher keine Rolle. Also eine Gegenfrage: Was ist der Nachteil mit Einzeldateien?
Ich weiß leider nicht, was du mit "in eine passende Datenstruktur einzulesen" meinst. Ich bekomme die Datei so exportiert aus einem CAD-Programm. Dort kann ich nichts ändern.

In dem ersten von mir vorhin geposteten Script geht's ja noch weiter. Ich muss aus meinem ibl-file für mein geomTurbo-file pro Layer zwei Kurvenzüge basteln. Dafür habe ich mit numpy gearbeitet. Ich muss an einige, vorher gesucht und gespeicherte Abschnitte, noch Werte aus dem ibl-file vorne und hinten anhängen. Die Dateien überschreibe ich einfach.
(Das ist ein weiterer Auszug aus meinem Script.)

Code: Alles auswählen

import os
import numpy as np

path = r'U:\\07_Python\03_Vorbereitung


def main():
    arr = np.loadtxt(os.path.join(path, 'Test_row1_s1_del.ibl'), dtype=float)
    arr1 = np.loadtxt(os.path.join(path, 'Test_row1_1LE_del.ibl'), dtype=float)
    arr2 = np.loadtxt(os.path.join(path, 'Test_row1_1TE_del.ibl'), dtype=float)
    arr = np.flipud(arr)  # ---> +x
    arr1 = np.flipud(arr1)  # ---> +x
    arr2 = np.flipud(arr2)  # ---> +x
    arr = np.insert(arr, [0], arr1[9:19], axis=0)
    arr = np.append(arr, arr2[0:10], axis=0)
    arr[:, [0, 1]] = arr[:, [1, 0]]
    np.savetxt(os.path.join(path, 'Test_row1_s1_del.ibl'), arr, '%8.6f', delimiter="\t")

if __name__ == '__main__':
    main()
Nochmal vielen Dank für deine Hilfe :)
BlackJack

@stephi_1011: Der Nachteil von Einzeldateien ist neben dem Aufwand den das für den Rechner macht, auch das es mehr Aufwand beim Programmieren und Verstehen des Programms bedeutet. Und das dann auch noch über mehrere Programme hinweg mit kryptischen temporären Dateinamen ist ziemlich unübersichtliches und unverständliches Stückwerk. Das ist für aussenstehende schwer zu verstehen, und auch für Dich selbst wenn Du in einem Jahr da mal wieder drauf schaust.

Mit in eine passende Datenstruktur einlesen meine ich die Daten im Programm und in den Überlegungen nicht mehr als reinen, nahezu unstrukturierten Text zu behandeln, denn das sind sie ja nicht. Die Daten haben eine ziemlich klare, und auch gar nicht mal so komplizierte Struktur, die man im eigenen Programm auf Datenstrukturen abbilden kann. Zahlen, Listen, Wörterbücher, Mengen, Numpy-Arrays, Datentypen aus dem `collections`-Modul, eigene Klassen, sind alles Bausteine für eigene, sinnvolle Datenstukturen. Du gehst eher nach dem Motto alles ist irgendwie Text, den wandelt man vielleicht mal kurz in eine Liste von Zeilen oder ein Numpy-Array, mach damit kurz etwas, und wandelt es dann wieder in Text. Nur um im nächsten Skript den Text dann wieder in eine Liste oder ein Numpy-Array zu wandeln, etwas damit zu machen, und das Zwischenergebnis wieder in Text umzuwandeln. Und dann geht das ganze wieder von vorne los. Dabei enstehen dann auch noch viele Dateien, wo man aufpassen muss das die unnötigen wieder gelöscht werden, nicht zu viel gelöscht wird, und das man nicht auch mal irgendwo einen Fehler macht, und alte oder falsche Dateien weiterverarbeitet.

Normal wäre es die IBL-Datei in eine Datenstruktur einzulesen, also einmal von der Textform in eine zur Bearbeitung passende Sammlung von Objekten zu wandeln. Aus dieser Datenstruktur dann eine Datenstruktur zu erstellen die alle Daten für die Zieldatei enthält, und diese Datenstruktur dann erst wieder in einen Text zu wandeln und zu speichern.
Antworten