Seite 1 von 1
Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 08:33
von jim_beam
Hallo Zusammen, ich bin blutiger Phyton Anfänger und hoffe ich könnt mir helfen.
Ich versuche Daten aus einer semikolon separierten .csv an die Stelle der Platzhalter in einer .txt zu schreiben. Solange ich in meiner .csv nur einen Splatenkopf habe funktioniert das Skript. Sobald ich aber in Spalte B (hier "vlan") einen weiteren Wert hinzufüge bricht das Skript mit folgenden Fehler ab:
Code: Alles auswählen
PS C:\Program Files\WPy64-31110\scripts> python test.py
Traceback (most recent call last):
File "C:\Program Files\WPy64-31110\scripts\test.py", line 27, in <module>
generate_router_config(csv_data, router_template_file, router_config_output_file)
File "C:\Program Files\WPy64-31110\scripts\test.py", line 18, in generate_router_config
config_entry = config_template.format(**entry)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'routername'
Hier mein skript:
Code: Alles auswählen
import csv
def read_csv_data(file_path):
data = []
with open(file_path, 'r') as csv_file:
csv_reader = csv.DictReader(csv_file, delimiter=';')
for row in csv_reader:
data.append(row)
return data
def generate_router_config(csv_data, template_file, output_file):
with open(template_file, 'r') as template:
config_template = template.read()
with open(output_file, 'w') as output:
for entry in csv_data:
print(entry) # Ausgabe der entry-Daten zur Überprüfung
config_entry = config_template.format(**entry)
output.write(config_entry)
if __name__ == "__main__":
csv_file_path = r"C:\Program Files\WPy64-31110\scripts\test.csv"
csv_data = read_csv_data(csv_file_path)
router_template_file = r"C:\Program Files\WPy64-31110\scripts\test_vorlage.txt"
router_config_output_file = "router_konfiguration.txt"
csv_data = read_csv_data(csv_file_path)
generate_router_config(csv_data, router_template_file, router_config_output_file)
Die .csv wurde mit Excel365 erstellt und als Typ "CSV Trennzeichen-getrennt" gespeichert. Die Zellen habe ich alle als Text formatiert.
Inhalt der .csv:
Inhalt der meiner test_vorlage.txt:
Hat jemand einen Tip für mich?
Vielen Dank im Vorraus!
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 08:54
von Sirius3
Eingerückt wird immer mit 4 Leerzeichen pro Ebene; da Deine Einrückungen kaputt sind, kann man nicht sagen, welches Programm Du wirklich ausgeführt hast.
csv-Dateien sollte man immer mit newline="" öffnen.
Code: Alles auswählen
def read_csv_data(file_path):
with open(file_path, 'r', newline='') as csv_file:
return list(csv.DictReader(csv_file, delimiter=';'))
Wie ist die Ausgabe von `entry`? Ist da wirklich der Schlüssel routername drin?
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 09:24
von jim_beam
Ok danke, ich habe die Einrücken korrigiert und öffne die .csv mit newline.
Leider kommt keine Ausgabe von `entry`. Es erscheint lediglich der o.g. Fehler
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 09:44
von __deets__
Was heisst es kommt keine Ausgabe von entry? Die kommt ja nicht von alleine, die musst du da schon reinschreiben. Bitte zeig den konkreten Code, den du verwendest (nach der Aenderung). Umschreibungen, was da jetzt veraendert wurde, helfen nicht.
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 10:27
von jim_beam
Hier mein angepasstest Script:
Code: Alles auswählen
import csv
def read_csv_data(file_path):
with open(file_path, 'r', newline='') as csv_file:
return list(csv.DictReader(csv_file, delimiter=';'))
def generate_router_config(csv_data, template_file, output_file):
with open(template_file, 'r') as template:
config_template = template.read()
with open(output_file, 'w') as output:
for entry in csv_data:
print(entry) # Ausgabe der entry-Daten zur Überprüfung
config_entry = config_template.format(**entry)
output.write(config_entry)
if __name__ == "__main__":
csv_file_path = r"C:\Program Files\WPy64-31110\scripts\test.csv"
csv_data = read_csv_data(csv_file_path)
router_template_file = r"C:\Program Files\WPy64-31110\scripts\test_vorlage.txt"
router_config_output_file = "router_konfiguration.txt"
csv_data = read_csv_data(csv_file_path)
generate_router_config(csv_data, router_template_file, router_config_output_file)
Die Fehlermeldung beim Ausführen lautet weiterhin:
Code: Alles auswählen
PS C:\Program Files\WPy64-31110\scripts> python test.py
Traceback (most recent call last):
File "C:\Program Files\WPy64-31110\scripts\test.py", line 27, in <module>
generate_router_config(csv_data, router_template_file, router_config_output_file)
File "C:\Program Files\WPy64-31110\scripts\test.py", line 18, in generate_router_config
config_entry = config_template.format(**entry)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'routername'
Die Ausgabe von entry müsste doch beim Befehl absenden mit ausgegeben werden oder verstehe ich das falsch?
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 10:33
von __deets__
Ja, das print-statement sollte ausgefuehrt werden. Aber das ist natuerlich immer noch nicht die Datei, die du wirklich ausfuehrst. Denn wenn ich die in eine Datei kopiere, und mir die Zeile 18 anschaue, dann ist das
Code: Alles auswählen
router_template_file = r"C:\Program Files\WPy64-31110\scripts\test_vorlage.txt"
und nicht die Zeile, die da bei dir steht. Da ist also noch irgendetwas faul, von dem wir noch nichts wissen.
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 10:36
von __blackjack__
@jim_beam: Zeig doch erst einmal den tatsächlich ausgeführten Quelltext. Der im Beitrag kann so nicht gelaufen sein, der hat einen offensichtlichen Syntaxfehler. Und der Traceback sagt was von Zeile 27, bei Quelltext der nur 23 Zeilen lang ist. Das passt nicht zusammen.
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 10:57
von __blackjack__
@jim_beam: Allgemeine Anmerkungen zum Quelltext: Das Hauptprogramm sollte in einer Funktion stecken. Im Moment werden da auf Modulebene Namen definiert, die dann in Funktionen auch noch mal als lokale Namen verwendet werden. Hoffentlich — denn bei so etwas ist die Gefahr gross, dass man irgendwann mal in Funktionen einen Namen ausserhalb der Funktion verwendet ohne das zu merken und sich wundert warum der nicht den Wert hat, den man erwartet.
Wenn man Quelltext für andere zum Testen veröffentlich sind irgendwo im Programm verstreute absolte Pfade auf einem Windowssystem nicht hilfreich. Und das gilt eigentlich auch schon für eigene Tests. Der Basispfad, den alle gemeinsam haben sollte man auch nicht mehrfach schreiben, sondern als Konstante definieren.
Beim öffnen von Textdateien sollte man immer die Kodierung angeben die der Text hat, sonst ”rät” Python das anhand der Umgebung, das muss aber für konkrete Dateien gar nicht stimmen.
Es werden Werte `*_file` genannt die gar keine Dateien sind sondern Datei*namen*. Bei einer Datei erwartet man ein Objekt mit `read()`- und/oder `write()`- und `close()`-Methoden, keine Zeichenkette (oder ein `Path`-Objekt).
`csv_data` mag in der Hauptfunktion noch gehen, aber in `generate_router_config()` ist es völlig egal wo die Daten mal herkamen, aus einer CSV- oder JSON-Datei oder aus einer Datenbank, oder direkt im Quelltext als Datenstruktur ist für die Arbeit dieser Funktion völlig egal.
Man muss auch nicht jeden kleinen Zwischenwert an einen Namen binden. Das kann die Lesbarkeit verschlechtern.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import csv
from pathlib import Path
BASE_PATH = Path(R"C:\Program Files\WPy64-31110\scripts")
def read_csv_data(file_path):
with open(file_path, "r", newline="", encoding="utf-8") as csv_file:
return list(csv.DictReader(csv_file, delimiter=";"))
def generate_router_config(entries, template_file_path, output_file_path):
config_template = template_file_path.read_text(encoding="utf-8")
with open(output_file_path, "w", encoding="utf-8") as file:
file.writelines(map(config_template.format_map, entries))
def main():
entries = read_csv_data(BASE_PATH / "test.csv")
generate_router_config(
entries,
BASE_PATH / "test_vorlage.txt",
Path("router_konfiguration.txt"),
)
if __name__ == "__main__":
main()
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 11:54
von jim_beam
Vielen Dank für die Anmerkungen.
Das Problem lag in Notepad++! Alle Änderungen die ich da an der test.py vorgenommen habe, wurde wohl nicht in die datei in meinem python pfad geschrieben. Mir ist auch nicht aufgefallen, dass die Fehlermeldung auf eine Zeile verweißt, die eigentlich garnicht existiert.
Nun funktioniert es!

Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 13:34
von jim_beam
Nach weiterer Überlegung ist es sehr unpraktisch, dass das Script sofort abbricht, sobald im Tabellenkopf der csv ein Wert steht welcher in der vorlage.txt nicht zu finden ist.
Kann man das script evtl. so anpassen, dass Variablen die nicht in der vorlage.txt stehen aber in der csv stehen einfach ignoriert werden?
Re: Daten aus .csv in .txt vorlage
Verfasst: Dienstag 8. August 2023, 14:14
von Sirius3
Da bricht nichts ab, Werte, die nicht gebraucht werden, werden einfach ignoriert:
Code: Alles auswählen
"{da}".format_map({"da": 17, "nicht_da": 29}) # -> '17'