Seite 1 von 1

Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 11:19
von frostkrieger
Hallo zusammen,
ich bin Neuling im Programmieren möchte mir aber bevor ich mein Informatikstudium beginne
etwas Vorwissen verschaffen. Ich mache aktuell einen Kurs bei Udemy und stoße regelmäßig
an Probleme da die Themen dann doch nicht so ausführlich beschrieben werden und auch
nicht jeder Einzelfall besprochen werden kann.

Nun komme ich mal zu meinem Problem:
Also ich habe eine CSV Datei mit Daten, diese Daten habe ich mit einer
for Schleife in Listen eingelesen und nach den Daten gefiltert die ich haben möchte

Eine Liste hat folgenden Inhalt:

['Name', 'Vorname', 'Ausgeschieden']

Die Ausgabe gibt mir dann alle Listen mit diesem Inhalt aus.
Nun möchte ich diese Listen wieder in eine neue CSV Datei schreiben.
Aber hier verzweifel ich ein bisschen. Ich bekomme einfach keinerlei Einträge in die CSV
Datei geschrieben. Die Ausgabe mit Print gibt mir aber die richtige Ausgabe.

Hier mein Code:

Code: Alles auswählen

import csv

with open('users_exit_bubihr.csv', newline='', encoding='cp1252') as E, open('ausgeschieden.csv', 'w', newline='') as A:
    bubihrreader = csv.reader(E, delimiter=';', quotechar='"')
    ausgabe = csv.writer(A, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    
    for row in E:
        splitted = str(row.strip()).split(";")
        
        ausgeschieden = splitted[2]
        vorname = splitted[0]
        name = splitted[1]
        
        count = 0
        if ausgeschieden != "NULL":
            new_list = [vorname, name, ausgeschieden]
            for ele in new_list:
                new_list[count]=ele[1:-1]
                count += 1
                A.writelines(ele for ele in new_list)
            print(new_list)

Re: Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 11:41
von __blackjack__
@frostkrieger: Du machst da komische Dinge an den Reader und Writer Objekten vorbei. Die verwendest Du überhaupt gar nicht. `row` ist deswegen auch ein falscher Name denn der enthält keine Zeile der 2D-Daten aus der CSV-Datei sondern eine Zeile aus der Textdatei. Du musst da einfach nur über das Reader-Objekt iterieren. Nach definition von `bubihrreader` und `ausgabe` sollten `E` und `A` überhaupt nicht mehr in Deinem Code auftauchen.

Die Namensgebung könnte insgesamt besser sein. Namen sollen dem Leser vermitteln was der Wert dahinter im Programm bedeutet. `E` und `A` tun das sicher überhaupt nicht und ausserdem sind sie wie Konstanten gross geschrieben. `input_file` und `output_file` wären passende Namen.

`ausgabe` ist auch nicht gut. Das ist ja keine Ausgabe sondern ein Objekt über das etwas ausgegeben wird. Oder einfach ein `writer`. Beim `bubihrreader` fehlt das ”Leerzeichen”: `bubihr_reader`,

Der `str()`-Aufruf ist unsinnig. Was denkst Du denn was der bewirkt?

`splitted` braucht man nicht, denn dafür ist ja das Reader-Objekt zuständig. Die Indexzugriffe auf die Einzelbestandteile eines Eingabedatensatzes kann man kompakter und verständlicher über eine Zuweisung an mehrere Namen lösen. Angenommen man verwendet den CSV-Reader um über die Datensätze zu iterieren und `row` enthält einen geparsten Datensatz, einfach: ``vorname, name, ausgeschieden = row``. Andererseits, wenn da nur nach der Ausgeschieden-Spalte gefiltert werden soll ist das alles superumständlich. Alles im ``if``-Zweig ist sowieso völliger Murks, total gefährlich, unnötig, und unpythonisch. Man muss doch nur *ein* Element von `row` prüfen ob es "NULL" ist oder nicht, und falls nicht den gelesenen Datensatz wieder schreiben. Ohne den irgendwie neu anzulegen oder gar irgendwie zu verändern.

Alles ausser `delimiter` ist bei den CSV-Reader/-Writer-Objekten übrigends der jeweilige Standardwert und muss nicht angegeben werden.

Re: Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 11:59
von frostkrieger
Hallo Blackjack,
vielen Dank für deine Anmerkungen, ich glaube ich schreibe dass dann noch mal neu mit deinen Anregungen. An der Stelle danke für die konstruktive Kritik.

Was meinst du mit "str()`-Aufruf", an welcher Stelle?
Was iterieren bedeutet muss ich dann noch mal nachlesen.
Ich werde erst noch mal mit deinen Hinweisen das Programm neu schreiben und mich dann bestimmt noch mal melden :D

Re: Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 13:07
von __blackjack__
@frostkrieger: In dem gezeigten Quelltext ist nur ein einziger Aufruf von `str()` und genau den meine ich dann natürlich. 😉

Re: Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 21:50
von frostkrieger
ähhh ja hab ich auch dann gefunden xD
Das war noch aus einem Test, du hast vollkommen recht das es vollkommen sinnfrei ist :)

Re: Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 23:12
von frostkrieger
So ich hab mich deinen Hinweisen mal angenommen und festgestellt, dass ich zumindest bis zur Ausgabe deutlich effizienter bin.
Allerdings bekomme ich es immer noch nicht hin dass er die "neuen" Daten in die CSV schreibt.

Hier der Code, ich hoffe er ist jetzt schöner :)

Code: Alles auswählen

import csv
with open('users_exit_bubihr.csv', newline='', encoding='cp1252') as input_file, open('ausgeschieden.csv', 'w', newline='') as output_file:
    bubihr_reader = csv.reader(input_file, delimiter=';')
    bubihr_writer = csv.writer(output_file, delimiter=',')

    for row in bubihr_reader:
        if row[2] != "NULL":
            print(row)
Ich hab es nach dem IF in der Zeile versucht mit bubihr_writer.writerow(row)
Allerdings schreibt er immer noch nichts in die csv. :/

Hier noch mal ein Update:

Code: Alles auswählen

import csv
with open('users_exit_bubihr.csv') as input_file, open('ausgeschieden.csv', 'w+') as output_file:
    bubihr_reader = csv.reader(input_file, delimiter=';')
    bubihr_writer = csv.writer(output_file, delimiter=';')

    for row in bubihr_reader:
        if row[2] != "NULL":
            with output_file:
                writer = csv.writer(output_file)
                writer.writerow(row)
            print(row)
Fehler: ValueError: I/O operation on closed file.
Ich hab die Datei doch oben geöffnet ?
Muss ich das explizit noch mal machen ?

Re: Daten in CSV schreiben

Verfasst: Samstag 20. Juni 2020, 23:33
von Sirius3
Was hast Du denn genau versucht? Funktionierenden Code zu zeigen, und dann nur zu schreiben, dass irgendein anderer Code nicht funktioniert, ist nicht sehr hilfreich.

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 01:48
von __blackjack__
@frostkrieger: Was machst Du denn im ``if``-Zweig schon wieder mit der Ausgabedatei? Und warum willst Du da jedes mal wieder einen neuen CSV-Writer erzeugen? Du hast doch bereits einen. Den musst Du nur verwenden. Nix anderes. Einfach den vorhandenen verwenden um direkt einfach den Datensatz zu schreiben.

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 09:20
von frostkrieger
@sirius3

Naja der Code funktioniert halt nicht so wie er es soll und ich schrieb ja auch extra dass es ein Update ist, da ich zwischenzeitlich auch wieter rumprobiert habe.

@blackjack

Naja aber wie bekomme ich denn sonst die Datensätze die ich haben möchte ?

Die Datei ist halt ein Datenbankexport
Da stehen Vorname, Nachname, Exit drin.
Ich möchte in diesem Fall nur die Benutzer haben die im Exit Feld ein Datum stehen haben.

Ich habe festgestellt dass auch was mit meiner Datei nicht stimmte, weswegen er nichts in die Datei reingeschrieben hat.

Nun erhalte ich die gewünschten Daten und er schreibt sie auch in die CSV Datei. Allerdings besteht immer noch die Frage wie ich das ohne IF Schleife bewerkstelligen soll?

HIer jetzt der funktionierende Code:

Code: Alles auswählen

import csv
with open('users_exit_bubihr.csv') as input_file, open('ausgeschieden.csv', 'w+') as output_file:
    bubihr_reader = csv.reader(input_file, delimiter=';')
    bubihr_writer = csv.writer(output_file, delimiter=',')

    for row in bubihr_reader:
        if row[2] != "NULL":
            writer = csv.writer(output_file)
            writer.writerow(row)

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 09:50
von Sirius3
Mein Beitrag und Dein Update haben sich zeitlich überschnitten.

Um __blackjack__ zu zitieren: warum willst Du in der Schleife jedes mal wieder einen neuen CSV-Writer erzeugen? Du hast doch bereits einen.

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 10:05
von frostkrieger
Weil ich jede Zeile in der input_file in die neue output_file schreiben möchte und dabei die Einträge die in der Spalte Exit nicht "Null" sind in die output_file geschrieben werden sollen.
In dem Udemykurs den ich mir anschaue wird gesagt, dass wenn ich dies Zeile für Zeile tun möchte mit einer for Schleife vorgehen soll.

Für mein Verständnis, du/ihr zielt doch auf diese for Schleife ab? Bei jedem neuen Durchgang erzeuge ich einen neuen csv.writer? Wenn ich das nicht machen soll benötige ich ggf. einen Hinweis wie man es machen soll. In den ganzen Beispielen in dem Kurs wurde das immer so gemacht.

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 10:11
von Sirius3
Wir haben nichts gegen die for-Schleife und auch nichts gegen das if, sondern gegen die Zeile, in der Du einen `writer` erzeugst`, obwohl Du doch schon einen `bubihr_writer` hast, den Du aber gar nicht benutzt.

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 10:19
von frostkrieger
AHHHHHHHHHHHHHH jetzt verstehe ich :D

Ich denke ich habs dann :

Code: Alles auswählen

import csv
with open('users_exit_bubihr.csv') as input_file, open('ausgeschieden.csv', 'w+') as output_file:
    bubihr_reader = csv.reader(input_file, delimiter=';')

    for row in bubihr_reader:
        if row[2] != "NULL":
            bubihr_writer = csv.writer(output_file)
            bubihr_writer.writerow(row)
Ok also zu meinem Ursprungscode ist das natürlich ein himmelweiter unterschied.
Wenn Ihr jetzt zufrieden seid bin ich auch zufrieden da es tut was es soll :D

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 10:29
von Sirius3
NEEEEEIIIIIN.

Code: Alles auswählen

import csv
with open('users_exit_bubihr.csv', newline='', encoding='cp1252') as input_file, open('ausgeschieden.csv', 'w', newline='', encoding='cp1252') as output_file:
    bubihr_reader = csv.reader(input_file, delimiter=';')
    bubihr_writer = csv.writer(output_file, delimiter=',')

    for row in bubihr_reader:
        if row[2] != "NULL":
            bubihr_writer.writerow(row)
CSV-Dateien brauchen immer die Option newline="", und der Filemodus w+ macht bei Textdateien keinen Sinn. Woher kommt der jetzt?
Man sollte immer ein Encoding angeben, wobei cp1252 heutzutage eigentlich nicht mehr verwendet werden sollte, weil nur utf8 alle Zeichen darstellen kann.

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 10:46
von frostkrieger
Hi,
habs berichtigt, danke für deine Hinweise!

Code: Alles auswählen

import csv
with open('users_exit_bubihr.csv', newline="", encoding="utf-8") as input_file, open('ausgeschieden.csv', 'w', newline="", encoding="utf-8") as output_file:
    bubihr_reader = csv.reader(input_file, delimiter=';')

    for row in bubihr_reader:
        if row[2] != "NULL":
            bubihr_writer = csv.writer(output_file)
            bubihr_writer.writerow(row)

Re: Daten in CSV schreiben

Verfasst: Sonntag 21. Juni 2020, 11:03
von Sirius3
Wenn Deine Eingabedaten cp1252 kodiert waren, kannst Du das nicht einfach ersetzen. Ich schrieb nur, wenn Du die Möglichkeit hast, das umzustellen, dann mach das.
ABER WARUM ERZEUGST DU IMMER WIEDER IN JEDEM SCHLEIFENDURCHGANG EINEN NEUEN CSV-WRITER? Das haben wir jetzt sieben mal geschrieben und ich habe jetzt sogar den Code auf dem Silbertablett serviert, aber trotzdem ist es wieder falsch.