Punktnummer in versch. Dateien kopieren und verändern...

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
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Guten Morgen liebes Forum!

Ich als Neu-Benutzer von Python habe da mal eine Frage:

Wir haben hier verschiedene Dateien (Isybau-Kanal-Dateien, *.k, *.lk und *.h-Dateien). Die haben auf einer bestimmten Position in Zeilen die Punktnummern stehen. Diese Punktnummer müsste erst kopiert und dann bei der ersten Stelle überschrieben werden mit einer anderen Punknummer, die man(n) dann eingeben müsste, am besten in einer Maske, wo man "neue Punktnummer" und "alte Punktnummer" (zum Suchen) eingeben kann und die Routine sucht und kopiert/ersetzt dann in allen 3 Dateien, dann halt nacheinander die Zeilen alle ab.

Diese Routine müsste dann halt in einer "Endlosschleife" immer wieder nach verrichteter Arbeit wieder andere alte Punktnummern suchen/kopieren und die neuen Punktnummern einsetzen, also Durchläufe, die dann bis zu 5000 Punkte im Rutsch verändert.

Daher müsste bei der "Eingabemaske" Pkt.-Nr. neu, Pkt.-Nr. alt, auch ein "Beenden"-Knopf dabei sein, wenn man fertig ist, und am besten auch eine Nachricht, wieviel mal die letzte Punktnummer gefunden, kopiert und ersetzt wurde...

Vielleicht gibt es sowas ja schon als "Grundgerüst", das ein findiger Programmierer schon bereits "erfunden" hat!?

Die gesuchten alten Punktnummern sind zwischen 2 und 9 Stellen lang, die neuen Punktnummern sind immer 9-stellig!

Bei den alten Punktnummern müssten also immer nach 9 Stellen gesucht werden und der Rest halt mit Leerzeichen gefüllt sein, wenn gesucht wird, wenn die Punktnummer-alt halt weniger wie 9 Stellen hat - zum korrekten Einfügen in der richtigen Position in den Dateien, wobei in den Dateien es unterschiedlich ist, an welcher Position in der Datei die Punktnummer gesucht/kopiert und ersetzt werden soll.

Bei der K-Datei steht der Name bei Spalte 5-14, der Name-2(alter Name) bei 15-24. (Zuerst müsste der Name bei "Name-2" reinkopiert werden in der gleichen Zeile, dann erst der neue Name bei "Name" den jetzigen (alten) Name überschreiben, danach aber noch weiter in der Datei gesucht werden.
Diese Prozedur befindet sich nur in der 1. Hälfte der K-Datei, wobei diese Prozedur auf die Zeile mit Anfang "KS" beschränkt wäre:

Textdateiauszug K-Datei:

KS 131101550 325907.1765546945.4800 360.4420 0
KS 231101550 0.63 0.00R 1.00 1.00N 0.00 0.00 0.00 353.8600 2
KS 331101550 0N NN0
KS 131101551 325955.8945546949.0770 356.9190 0
KS 231101551 0.63 0.00R 1.00 1.00N 0.00 0.00 0.00 353.4600 2
KS 331101551 0N NN0

Die Bezeichnung "KS 1" ist der "Record 1", "KS 2" "Record 2" und "KS 3" der Record 3". Bei diesem Beispiel ist die Nummer-alt nur 8-stellig, der Name-2 ist nicht ausgefüllt. Die Zeilen müssten zum Schluss z.b. so aussehen:

KS 1715652010 31101550 325907.1765546945.4800 360.4420 0
KS 2715652010 0.63 0.00R 1.00 1.00N 0.00 0.00 0.00 353.8600 2
KS 3715652010 0N NN0
KS 1715652012 31101551 325955.8945546949.0770 356.9190 0
KS 2715652012 0.63 0.00R 1.00 1.00N 0.00 0.00 0.00 353.4600 2
KS 3715652012 0N NN0

Das wäre das Endergebnis bei der "Schachtdaten", in der zweiten Hälfte der Datei fängt das Steuerkürzel mit "KH 1", "KH 2" und "KH 3" an und ist ähnlich aufgebaut:

KH 131101550 31101550 31101551 353.860 353.46000 0 300 300 48.85
KH 231101550 0KS 0 B Schloßstraße (MB) 000
KH 331101550 0.000 0.000 0.0002 0.0 0.0 0.0 0.0 0.0 0.0 0.0
KH 131101551 31101551 31101560 353.460 352.39000 0 300 300 31.04
KH 231101551 0KS 0 B Schloßstraße (MB) 000
KH 331101551 0.000 0.000 0.0002 0.0 0.0 0.0 0.0 0.0 0.0 0.0

So sieht das dann bei dem "Haltungsblock" aus!

Demnach müsste die alte Nummer beim Record 1 (KH 1) auch wie bei "KS 1" kopiert und ersetzt werden und bei Record 2 und 3 halt auch wieder vorne die Nummer ersetzt werden wie beim Schachtblock:

KH 1715652010 31101550 715652010 715652012 353.860 353.46000 0 300 300 48.85
KH 2715652010 0KS 0 B Schloßstraße (MB) 000
KH 3715652010 0.000 0.000 0.0002 0.0 0.0 0.0 0.0 0.0 0.0 0.0
KH 1715652012 715652012 31101551 31101560 353.460 352.39000 0 300 300 31.04
KH 2715652012 0KS 0 B Schloßstraße (MB) 000
KH 3715652012 0.000 0.000 0.0002 0.0 0.0 0.0 0.0 0.0 0.0 0.0

Bei dem KH 1 Block steht bei Spalte 25-34 der Von-Schacht, also der gleiche neue Name wie vorne, bei Spalte 35-44 der Bis-Schacht.
Diese zwei Punktnamen wären mit den normalen "Suchen-und Ersetzen" zu finden und zu setzen!

Der Name 2 könnte vorab schon in der Access-DB gesetzt werden, sodaß man sich nicht darum kümmern müsste, allerdings müsste dieser ja dann nicht gesucht und ersetzt werden. Der müsste dann beim Block 1 (KS 1) und Block 2 (KH 1) so stehen bleiben! :D

Da dieses Prozedere für 2-10000 Punkte durchlaufen müsste, hatte ich mir gedacht, dass ich wenigstens das Suche-Kopieren-Ersetzen mittels Routine vielleicht ersparen könnte. (wobei das "Kopieren" dann rausfallen würde, wenn ich den Name 2 schon in ACCESS kopiere!

Ich wäre für jeglicher Art von Kommentar, Beleidigungen, Ratschläge, Hinweise zur Vorgehensweise, Tipps und Vorschläge dankbar! :? :D

Das wäre jetzt im Endeffekt erst die 1. Datei - die K-Datei, bei den anderen 2 Dateien ist es ähnlich - auch mit Records!

Vielen Dank für Ihre Aufmerksamkeit!

SG,
Arwed Fränken
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@zimmernagel: wenn Du ein Problem lösen willst, dann teile es erst einmal in Teilprobleme, und diese wieder in Unterteile, bis die einzelnen Teile trivial zu lösen sind.

Hier also:
1. Ermitteln der Zuordnung alt -> neu
2. Ändern der Zuordnung

Punkt 1 habe ich noch nicht so ganz verstanden: wer will denn 10000 Zahlen von Hand eingeben?

Punkt 2 ist ein Standardproblem, das man in folgende Teile teilen kann:
2.1. Lesen der Datei in eine passende Datenstruktur
2.2. Ändern der Daten
2.3. Schreiben der Datei

Punkt 2.2 ist trivial, soetwas sieht auch immer gleich aus:

Code: Alles auswählen

def replace_numbers(records, old2new_numbers):
    return [record._replace(number=old2new_numbers.get(record.number, record.number))
        for record in records]
wobei ich jetzt davon ausgegangen bin, dass der Dateiinhalt in eine Liste von NamedTuple-Objekten geparst wurde.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Hi Sirius3!

Wow, ich versteh' fast nur Bahnhof.. ;-)

Das ist eine gute Idee, ich will wohl eine eierlegende Wollmilchsau... - in einem Rutsch...

Die 10000 Punkte - ob ich jetzt vorher eine Liste mache, oder diese halt eintippe, ich muss nebenbei in einem AutoCAD-Plan schauen und mir eine neue Punktnummer überlegen..., daher die "händische Eingabe"...

Zu 2.1 - Die Datenstruktur der Dateien muss auf jeden Fall so bleiben, sie sollen ja nur geringfügig "aktualisiert" werden.

Zu 2.2 - Da kommt der Bahnhof wieder in's Spiel...

Wenn ich jetzt nur Alt gegen Neu tausche..., ich würde erstmal 1 Datei aufmachen, durchlaufen lassen, dann die 2. Datei, durchlaufen lassen, usw...

Ich werde mal am WE mir das genauer anschauen, müsste erstmal mit TKINTER klar kommen für die Eingabe der beiden Nummern und die Übergabe zu der Routine, sowie das direkte aktualisieren der aktuellen eingelesenen Zeile... (ich wollte das zeilenweise lesen/aktualisieren...!?)

Dateiinhalt in eine Liste von .... geparst wurde? Muss ich googlen, was das überhaupt heisst. Die Rohdaten hast du oben bei mir gesehen!? Das sind strukturierte Dateien die in bestimmten Spalten in einer Spalte die zu ändernden Namen stehen haben.

Vielen Dank schonmal!
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@zimmernagel: Du hast keine Datei mit Spalten und auch keine Textdatei, sondern eine Datei, die ein bestimmtes Format hat. Dass Du keine Spalten hast, siehst Du ja schon daran, dass die Nummer mal 9 und mal 7 Stellen hat.

Parsen bedeutet, den Text der Datei in eine Form zu bringen, mit der man dann weiterarbeiten kann. Weil Du nur mit einem Teil der Information, die in der Datei steht, arbeiten willst, reicht es auch nur diesen Teil abzubilden. Ich sehe gerade, Du willst irgendeinen Namen2 einfügen, was die Sache mit dem Parsen dann doch etwas komplizierter macht.

Am besten suchst Du mal, ob es nicht schon einen Parser für diese Art Daten in Python gibt. Falls nicht, solltest Du die Dokumentation des Datenformats genau lesen, damit Du nicht irgendeinen Fall übersiehst und im Zweifel nur Datenmüll produzierst. Gerade als Anfänger ist es nicht einfach, einen funktionierenden, fehlertoleranten Parser zu schreiben. Ganz wichtig ist hierbei das Testen an möglichst vielen Dateien. Erst wenn Parser und Schreiber fehlerfrei funktionieren kannst Du Dich an den nächsten Schritt machen, das Ändern der Daten. Hast Du auch das gut getestet kannst Du Dir überlegen, wie die Eingabe der Nummern am besten erfolgt. Die Eingabe würde ich im Übrigen nicht über eine GUI machen, sondern als einfache Tabelle, in der in der ersten Spalte die alten und in der zweiten die neuen Nummern stehen.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Danke schonmal für den Tipp. Ich sehe, für's nächste hab ich wohl erstmal genug Hausaufgaben, die ich mir abarbeiten werde... :-)
Antworten