Konvertierer (Konvertiertung zwischen verschiedenen Dateiformaten)

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
Patryk Buczak
User
Beiträge: 9
Registriert: Mittwoch 26. August 2020, 13:16

Hallo zusammen,

die folgende Konvertierungsdatei soll erweitert werden, ich habe aber kein Plan wie ich das machen soll. Ich würde mich über eine kleine Hilfe freuen.

Python Programm zur Konvertierung zwischen verschiedenen Dateiformaten

import sys # benötigte Module importieren
import os
import csv
import json

while 1: # Endlosschleife
print( "CSV-JSON-Konvertierer") # Programmüberschrift
print( "---------------------")
print( "")
print( "(3) CSV -> JSON") # Menü und Benutzerauswahl
print( "(0) Ende")
befehl = int(input( "Auswahl: "))

if( befehl != 0 and befehl != 3): # Testen, ob ein bekannter Befehl eingegebn wurde
print( "Unbekannter Befehl: " + str(befehl))
continue

if befehl == 0: # Programm beenden
print( "Konvertierer beendet")
break

nameEingabeDatei = input( "Name Eingabedatei: ") # Name der Eingabedatei
nameAusgabeDatei = input( "Name Ausgabedatei: ") # Name der Ausgabedatei

if os.path.isfile(nameEingabeDatei) != True: # Testen, ob Eingabedatei existiert
print( "Eingabedatei: " + nameEingabeDatei + " nicht gefunden")
continue

if befehl == 3: # CSV -> JSON
print("Eingabedatei einlesen ...")
csvdatei = open( nameEingabeDatei, "r", encoding="utf-8") # CSV-Datei öffnen
reader = csv.DictReader( csvdatei, fieldnames = None)
print("In JSON-Format verwandeln ...") # Umwandeln
out = json.dumps( [ row for row in reader ], indent=4, ensure_ascii=False )
print ("JSON-Datei erstellen ...")
jsonDatei = open( nameAusgabeDatei,"w", encoding="utf-8" ) # JSON-Datei rausschreiben
jsonDatei.write( out)
jsonDatei.close()
print( "Konvertierung: CSV -> JSON")
print( "Ausgabedatei: " + nameAusgabeDatei + " erfolgreich erstellt.")

print ("")

sys.exit(0)

Und zwar
- das Programm soll anzeigen, wie viele Datensätze konvertiert wurden und wie lange es gebraucht hat
- der Benutzer soll in einem kleinen Menü wählen können was er gerne hätte
- das Programm soll die CSV Datei anzeigen können
- und man soll auch in JSON Dateien in CSV konvertieren können

Ist eine Schulaufgabe, und ich habe nur ein paar Tage zeit. Bitte keine unhöflichen Antworten, danke euch im Voraus!
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Kommentare gehören vor die Zeile, die sie betreffen. Deine Kommentare hüpfen bei mir irgendwo am rechten Rande meines Editors herum.
Die meisten Kommentare sind sinnlos. Dass Module importiert werden, sieht man am Input.
Und eine Zeile wo die Variable nameEingabeDatei definiert wird, den Kommentar "Name der Eingabedatei" zu haben, ist auch überflüssig.
Variablennamen werden generell klein geschrieben, also name_eingabedatei. Nach der öffnenden Klammer kommt kein Leerzeichen. Bei Funktionsaufrufen davor auch nicht.

In Python gibt es die Wahrheitswerte True und False. Die sollte man benutzen, wo es um Wahrheitswerte geht.
Mit `continue` sollte man sparsam umgehen. Hier wären Funktionen praktisch, um die langen if-Blöcke zu vermeiden.
Strings stückelt man nicht mit + zusammen, sondern nutzt Formatstrings.
Statt `a != True` benutzt man `not a`.

Dateien öffnet man innerhalb des with-Statements, damit sie auch garantiert wieder geschlossen werden.
Das sys.exit am Schluß ist unnötig.

Hier mal umstrukturiert und mit den Kommentaren, die einigermaßen nützlich sind:

Code: Alles auswählen

import sys
import os
import csv
import json

def convert_csv_json(name_eingabedatei, name_ausgabedatei):
    print("Eingabedatei einlesen ...")                                          
    with open(name_eingabedatei, encoding="utf-8") as csvdatei:
        reader = csv.DictReader(csvdatei)
        print("In JSON-Format verwandeln ...")
        rows = list(reader)
    print("JSON-Datei erstellen ...")
    with open(name_ausgabedatei, "w", encoding="utf-8") as json_datei:
        json.dump(rows, json_datei, indent=4, ensure_ascii=False)
    print("Konvertierung: CSV -> JSON")
    print("Ausgabedatei:  {name_ausgabedatei} erfolgreich erstellt.")


def convert(befehl):
    name_eingabedatei = input("Name Eingabedatei: ")
    name_ausgabedatei = input("Name Ausgabedatei: ")

    # Testen, ob Eingabedatei existiert
    if not os.path.isfile(name_eingabedatei):
        print("Eingabedatei: {name_eingabedatei} nicht gefunden")
        return
       
    if befehl == 3:
        convert_csv_json(name_eingabedatei, name_ausgabedatei)


def main():
    while True:
        print("CSV-JSON-Konvertierer")
        print("---------------------")
        print("")
        # Menü und Benutzerauswahl
        print("(3) CSV -> JSON")
        print("(0) Ende")
        befehl = int(input("Auswahl: "))

        if befehl == 0:
            # Programm beenden
            break
        elif befehl == 3:
            convert(befehl)    
        else:
            print("Unbekannter Befehl: {befehl}")
        print("")                                                                 
    print("Konvertierer beendet")

if __name__ == '__main__':
    main()
Wo kommst Du mit den Aufgaben konkret nicht weiter? Zum Zeit messen gibt es das time-Modul. Ein Menü hast Du schon, der umgekehrte Konvertierer ist ja analog zu dem bereits existierenden, und Anzeigen macht man mit print.
Patryk Buczak
User
Beiträge: 9
Registriert: Mittwoch 26. August 2020, 13:16

Zum Zeit messen habe ich im Internet folgendes gefunden, ich weiß aber leider nicht wie ich das in den Code einsetzen soll, damit das Ganze Sinn macht:

from time import perf_counter
>>> def longrunning_function():
... for i in range(1, 11):
... time.sleep(i / i ** 2)
...
>>> start = perf_counter()
>>> longrunning_function()
>>> end = perf_counter()
>>> execution_time = (end - start)
>>> execution_time
8.201258441999926

Und die Kommentare habe ich für mich selber geschrieben da ich noch ein Anfänger bin und nicht so viel Erfahrung mit Python habe. Mit den Kommentaren ist es einfach einfacher für mich. Danke für die schnelle Antwort
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

perf_counter gibt eine Zeit zurück, mit der man Zeitdifferenzen messen kann. Also ein Zeitpunkt am Start der Funktion, dessen Zeit man messen will und einen am Ende.
Patryk Buczak
User
Beiträge: 9
Registriert: Mittwoch 26. August 2020, 13:16

hat mir nicht weitergeholfen, ich weiß immer noch nicht wie der ganze Code mit der Funktion perf_counter aussehen soll
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich weiß nicht, wo ich da helfen kann. Du hast ein Beispiel gepostet, das die Benutzung von perf_counter zeigt, mehr gibt es dazu eigentlich nicht zu erklären. Wo kommst Du denn konkret nicht weiter? Was hast Du versucht?
JannisS
User
Beiträge: 8
Registriert: Donnerstag 8. Oktober 2020, 10:30

Ich habe die selbe Aufgabe in der Schule und bin auch absoluter Anfänger was programmieren betrifft. Ich habe das mit dem Modul time gemacht :

if befehl == 3:
startTime = time.time()
print("Eingabedatei einlesen ...")
csvdatei = open( nameEingabeDatei, "r", encoding="utf-8")
reader = csv.DictReader( csvdatei, fieldnames = None)
print("In JSON-Format verwandeln ...")
out = json.dumps( [ row for row in reader ], indent=4, ensure_ascii=False )
print ("JSON-Datei erstellen ...")
jsonDatei = open( nameAusgabeDatei,"w", encoding="utf-8" )
jsonDatei.write( out)
jsonDatei.close()
print( "Konvertierung: CSV -> JSON")
endTime = time.time ()
total_time = endTime - startTime

print( "Ausgabedatei: " + nameAusgabeDatei + " erfolgreich erstellt.")
print( "Das Script hat für die Ausführung {0} Zeit gebraucht.".format(time.time()- startTime))

so klappt es. Was ich aber bei einer anderen Antwort nicht verstehen kann ist, die Befehle mit dem " def ", " def convert ", " rows = list(reader) ", " encoding utf=8 ", " if not os.path.isfile(name_eingabedatei): " und das Letzte " if __name__ == '__main__':
main() ". Das mit dem letzten der Code beendet wird ist mir klar, aber ich will verstehn, was genau dort gemacht wird und was die einzelnen Wörter alle bedeuten, damit ich z.B. bei einer neuen Aufgabe mein Wissen anwenden kann und auch verstehen kann was genau dort passiert. DANKE
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

`def` definiert eine Funktion, weil man mit Funktionen komplexere Dinge schreiben kann, man hat eine Strukturierung und vor allem kann man Funktionen mehrfach mit unterschiedlichen Parametern verwenden.
`list(reader)` ist die direktere Form von `[row for row in reader]`: packe die Elemente des Iterators reader in eine Liste. Das ist viel einfacher zu lesen, als den Listcomrehensionausdruck.
Um eine Python-Datei als Modul nutzen zu können, darf nichts auf oberster Ebene stehen, außer (Funktions-)Definitionen. Daher braucht man eine main-Funktion. Die muß aber auch irgendwie aufgerufen werden, und das macht man mit den beiden letzten Zeilen (das if unterscheidet zwischen dann zwischen Programmaufruf und Modulimport).

Bei Deinem Code gilt auch, dass man Variablennamen generell komplett klein schreibt: start_time. Dateien öffnet man am besten innerhalb eines with-Statments, damit sie auch sicher wieder geschlossen werden. csvdatei wird bei Dir z.B. nicht wieder geschlossen.
Bei csv-Dateien muß man open mit dem Argument newline="" aufrufen.
JannisS
User
Beiträge: 8
Registriert: Donnerstag 8. Oktober 2020, 10:30

okay, danke schon mal. Das mit dem def Befehl habe ich jetzt alles verstehen können, aber wenn ich ihr Script ausprobiere und die CSV Datei eingeben will kommt immer die Fehlermeldung, dass die Datei nicht gefunden wurde. Ich habe ecxra nochmal mehrere CSV Dateien erstellt und das mit allen probiert aber es funktioniert nicht, auch wenn ich keinen Unterschied zu meinem Script sehe. & kann ich dieselben Befehle benutzen wenn ich von JSON zu CSV konvertieren möchte oder muss ich da andere Sachen beachten ? Danke im voraus. Zu dem Counter modul also um zählen zu können wie viele Dateien konvertiert wurden kann ich im Internet auch nichts finden. Bitte um Hilfe dankeschön!
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Es gibt kein "Counter-Modul". Das wäre auch etwas zuviel des guten, für 2 Zeilen Code.
Du musst dir selbst eine Variable definieren und dann immer wenn du zählen willst, den Wert um 1 erhöhen.
Wenn dich das ins Schleudern bringt, dann empfehle ich dir, dich mit den Grundlagen vertraut zu machen. Ein guter Einstieg ist das Tutorial in der Python-Dokumentation.

Mit der nicht gefundenen Datei: da musst du zeigen, wie du versuchst die zu öffnen und wo sie auf dem System ist.
JannisS
User
Beiträge: 8
Registriert: Donnerstag 8. Oktober 2020, 10:30

import sys
import os
import csv
import json
import time

def convert_csv_json(name_eingabedatei, name_ausgabedatei):
startTime = time.time()
print("Eingabedatei einlesen ...")
with open(name_eingabedatei, encoding="utf-8") as csvdatei:
reader = csv.DictReader(csvdatei)
print("In JSON-Format verwandeln ...")
rows = list(reader)
print("JSON-Datei erstellen ...")
with open(name_ausgabedatei, "w", encoding="utf-8") as json_datei:
json.dump(rows, json_datei, indent=4, ensure_ascii=False)
print("Konvertierung: CSV -> JSON")
endTime = time.time()
total_time = endTime - startTime
print("Ausgabedatei: {name_ausgabedatei} erfolgreich in {total_time} Sekunden erstellt.")

def convert(befehl):
name_eingabedatei = input("Name Eingabedatei: ")
name_ausgabedatei = input("Name Ausgabedatei: ")

# Testen, ob Eingabedatei existiert
if not os.path.isfile(name_eingabedatei):
print("Eingabedatei: {name_eingabedatei} nicht gefunden")
return

if befehl == 3:
convert_csv_json(name_eingabedatei, name_ausgabedatei)


def main():
while True:
print("CSV-JSON-Konvertierer")
print("---------------------")
print("")
# Menü und Benutzerauswahl
print("(3) CSV -> JSON")
print("(0) Ende")
befehl = int(input("Auswahl: "))

if befehl == 0:
# Programm beenden
break
elif befehl == 3:
convert(befehl)
else:
print("Unbekannter Befehl: {befehl}")
print("")
print("Konvertierer beendet")

if __name__ == '__main__':
main()


Das ist jetzt mein Script. Warum das mit der Zeit nicht funktioniert kann ich mir echt nicht erklären.
print("Ausgabedatei: {name_ausgabedatei} erfolgreich in {total_time} Sekunden erstellt.")

Wieso steht in der Anwendung dann nicht der Name der erstellten Datei und nicht die gebrauchte Zeit zur Erstellung der JSON Datei, sondern immernoch {name_ausgabedatei} & {total_time}. Ich verstehe es echt nicht.

Zu dem erstellen einer Variblen und immer +1 nehmen wenn ich zählen möchte bin ich noch nicht gekommen, weil ich das hier einfach nicht verstehe. Danke (wie gesagt absoluter Neuling)
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Das soll ein Formatstring sein, da fehlt also ein f:

Code: Alles auswählen

        print(f"Ausgabedatei:  {name_ausgabedatei} erfolgreich in {total_time} Sekunden erstellt.")
Rücke immer nur so viel in einem with-Block ein, wie wirklich nötig ist. Variablennamen schreibt man immer komplett klein!

Code: Alles auswählen

def convert_csv_json(name_eingabedatei, name_ausgabedatei):
    start_time = time.time()
    print("Eingabedatei einlesen ...")                                          
    with open(name_eingabedatei, encoding="utf-8") as csvdatei:
        reader = csv.DictReader(csvdatei)
        print("In JSON-Format verwandeln ...")
        rows = list(reader)
    print("JSON-Datei erstellen ...")
    with open(name_ausgabedatei, "w", encoding="utf-8") as json_datei:
        json.dump(rows, json_datei, indent=4, ensure_ascii=False)
    print("Konvertierung: CSV -> JSON")
    end_time = time.time() 
    total_time = end_time - start_time 
    print(f"Ausgabedatei:  {name_ausgabedatei} erfolgreich in {total_time} Sekunden erstellt.")
JannisS
User
Beiträge: 8
Registriert: Donnerstag 8. Oktober 2020, 10:30

Wenn ich jetzt nochmal eine definition einführen will, wo ich von json zu csv konvertieren will. Wie kann ich diese def Sachen unterscheiden ? Gibt es da sowas wie if, elif else ? Danke im voraus
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Offensichtlich mußt Du Dein Menü um einen weiteren Punkt erweitern und bei diesem `befehl` dann die richtige Funktion aufrufen.
JannisS
User
Beiträge: 8
Registriert: Donnerstag 8. Oktober 2020, 10:30

import sys
import os
import csv
import json
import time


def convert_csv_json(name_eingabedatei, name_ausgabedatei):
start_time = time.time()
Zahl=0
print("Eingabedatei einlesen ...")
with open(name_eingabedatei, encoding="utf-8") as csvdatei:
reader = csv.DictReader(csvdatei)
print("In JSON-Format verwandeln ...")
rows = list(reader)
print("JSON-Datei erstellen ...")
with open(name_ausgabedatei, "w", encoding="utf-8") as json_datei:
json.dump(rows, json_datei, indent=4, ensure_ascii=False)
print("Konvertierung: CSV -> JSON")
end_time = time.time()
Zahl=+1
print("Es wurden insgesamt {0} Daten konvertiert.".format(Zahl))
print("Die Konvertierung hat {0} Sekunden gedauert.".format(time.time() - start_time))
print(f"Ausgabedatei: {name_ausgabedatei} wurde erfolgreich erstellt.")

def convert_json_csv(name_ausgabedatei, name_ausgabedatei): #hier bei dem " def " wird mir die Fehlermeldung angezeigt
start_time=time.time()
Zahl=0
print("Eingabedatei einlesen ...")
with open(name_eingabedatei, encoding="utf-8") as jsondatei:
reader = json.Dictreader(jsondatei)
print("In CSV umwandeln ...")
rows = list(reader)
print=("CSV Datei wird erstellt ...")
with open(name_ausgabedatei, "w", encodding="utf-8") as csv_datei:
csv.dumps(rows, csv_datei, indent=4, ensure_ascii=False)
print("Konvertierung: JSON -> CSV")
end_time = time.time()
Zahl=+1
print("Es wurden insgesamt {0} Daten konvertiert.".format(Zahl))
print("Die Konvertierung hat {0} Sekunden gedauert.".format(time.time() - start_time))
print(f"Ausgabedatei: {name_ausgabedatei} wurde erfolgreich erstellt.")




def convert(befehl):
name_eingabedatei = input("Name Eingabedatei: ")
name_ausgabedatei = input("Name Ausgabedatei: ")

# Testen, ob Eingabedatei existiert
if not os.path.isfile(name_eingabedatei):
print("Eingabedatei: {name_eingabedatei} nicht gefunden")
return

if befehl == 3:
convert_csv_json(name_eingabedatei, name_ausgabedatei)

if befehl == 2:
convert_json_csv(name_eingabedatei, name_ausgabedatei)



def main():
while True:
print("CSV-JSON-Konvertierer")
print("---------------------")
print("")
# Menü und Benutzerauswahl
print("(3) CSV -> JSON")
print("(0) Ende")
befehl = int(input("Auswahl: "))

if befehl == 0:
# Programm beenden
break
elif befehl == 3:
convert(befehl)
else:
print("Unbekannter Befehl: {befehl}")
print("")
print("Konvertierer beendet")

if __name__ == '__main__':
main()
Sirius3
User
Beiträge: 18273
Registriert: Sonntag 21. Oktober 2012, 17:20

Kommt da jetzt auch eine Frage?

Du hast in den beiden Funktionen convert_csv_json und convert_json_csv 6 identische Zeilen, die nichts mit der Konvertierung direkt zu tun haben. Die sollten also woanders stehen und dort nur einmal. Wenn man beim Programmieren Code kopiert und nur leicht ändert, dann ist das ein Alarmsignal, dass man etwas falsch strukturiert hat. Die Hälfte der Zeilen kann so auch gar nicht innerhalb der Funktion stehen bleiben, weil das nur fehlerhafte Ergebnisse liefert.
JannisS
User
Beiträge: 8
Registriert: Donnerstag 8. Oktober 2020, 10:30

Vergessen zu schreiben: ich habe unten beim def main halt noch den befehl elif befehl ==2:
convert(befehl)
Patryk Buczak
User
Beiträge: 9
Registriert: Mittwoch 26. August 2020, 13:16

Habe noch eine Frage zu dem Thema...
Wieso wird die def main() am Ende des Codes geschrieben und nicht ganz am Anfang?
Macht es nicht mehr Sinn eine Hauptfunktion ganz am Anfang zu packen und danach die "Unterfunktionen" die zu def main() gehören?
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Patryk Buczak: Warum sollte das mehr Sinn machen? Ich ordne fast immer so, dass nichts verwendet wird das nicht vorher schon definiert wurde. Kann man auch anders herum machen oder völlig durcheinander, aber innerhalb von Funktionen/Methoden wird lokal die Reihenfolge erst definieren, dann verwenden ja erzwungen. Also würde ich sagen das diese Reihenfolge mehr Sinn macht um konsistent zu bleiben. Und der Aufruf der `main()` muss am Ende passieren, denn sonst wären die anderen Sachen ja nicht definiert.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten