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
shIxx
User
Beiträge: 22
Registriert: Sonntag 13. Oktober 2019, 16:11

hallo liebe Leute,
ich lerne gerade das Programmieren also ein totaler Anfänger.
Nun ich wollte üben wie man ganz einfach was abspeichert und liest aber ich verstehe den Error in meinem Code nicht.

Code: Alles auswählen

# Einfaches abspeichern von Daten
import json

user_input = {}

with open('daten.txt', 'r+') as f:
    try:
        inhalt = f.readlines()
        print(inhalt)
    except:
        Print('Datenbank ist leer')

with open('db.txt', 'a') as f:
    name = input('Name ')
    age = input('Alter ')
    birth_day = input('Geburtstag ')
    user_input = {'Kundenstamm': {'Name': name, 'Alter': str(age), 'Geburtstag': birth_day},
    json.dump(user_input, f, indent=4, separators=4 (',', ':'), sort_keys=True)
Der Error lautet

Code: Alles auswählen

SyntaxError: unexpected EOF while parsing
Kann man das überhaut so machen mit dem Dictionary ?
Ihr könnt mir bestimmt helfen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dir fehlt mindestens mal ne schließende Klammer beim dict. Und die Zeile mit json.dump enthält den nächsten Fehler.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@shIxx: Keine nackten ``except``\s ohne konkrete Ausnahmen die dort behandelt werden sollen. Wenn Du eine Ausnahme nicht sinnvoll behandeln kannst, dann lass es einfach ganz bleiben statt wertvolle Informationen zur Fehlersuche durch nichtssagende `print()`-Ausgaben zu verstecken. Zumal die Aussage dort zumindest fragwürdig ist, denn bei einer leeren Datei liefert `readlines()` einfach eine leere Liste und löst keine Ausnahme aus.

Bei beiden Dateien ist der Modus falsch. "+" macht bei Textdateien so gut wie nie Sinn. Und "a" hängt Daten an eine Datei an, das geht bei einer JSON-Datei aber nicht, die muss *einen* JSON-Wert enthalten, sonst kann man die nicht wieder parsen. JSON-Lines könnte eventuell Sinn machen wenn es möglich sein soll einzelne Datensätze hinzuzufügen ohne die Datei vorher komplett einlesen und anschliessend neu speichern zu müssen.

Beim öffnen von Textdateien sollte man immer eine konkrete Kodierung angeben. Bei JSON sollte das UTF-8 sein.

Die erste Zuweisung des leeren Wörterbuchs an `user_input` ist sinnlos weil dieser Wert nirgends verwendet wird. Die Struktur ist nicht so sinnvoll. Unter dem Schlüssel "Kundenstamm" würde man nicht nur *einen* Datensatz erwarten, sondern, naja eben den gesamten Kundenstamm.

Alter und Geburtsdatum zu speichern ist redundant, weil man das Alter aus dem Geburtsdatum berechnen kann. Und man sollte in einem Kundenstamm auch deswegen nicht das Alter speichern, weil sich das im Gegensatz zum Geburtsdatum mit der Zeit ändert.

`age` ist bereits eine Zeichenkette, da braucht man kein `str()` drauf anzuwenden. Wobei das etwas fragwürdig ist, denn eigentlich *ist* das Alter ja eine Zahl. Man sollte das also eher tatsächlich in eine Zahl umwandeln.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
shIxx
User
Beiträge: 22
Registriert: Sonntag 13. Oktober 2019, 16:11

Danke, ja das mit der Klammer hab ich gleich nachdem ich das gepostet habe auch gemerkt.

Wenn es die txt Datei nicht gibt meckert er auch. Ich dachte das + beim 'r+' bedeutet das er die Datei dann erstellen soll wenn sie noch nicht vorhanden ist.
Wann ist es eigentlich besser zu schreiben with open(...) as f oder f = open(...) ?

Wow, Ok so viel falsches in so wenig Code,.. ich bin etwas irritiert aber danke für diese ausführlich info.
__deets__ hat geschrieben: Sonntag 13. Oktober 2019, 16:26 Beim öffnen von Textdateien sollte man immer eine konkrete Kodierung angeben. Bei JSON sollte das UTF-8 sein.
Was genau meinst du damit? Sollte ich einfach mal nach Kodierung googeln?
__deets__ hat geschrieben: Sonntag 13. Oktober 2019, 16:26 Die erste Zuweisung des leeren Wörterbuchs an `user_input` ist sinnlos weil dieser Wert nirgends verwendet wird.
Dann erzeugt er doch eine Liste und ich möchte ein dict. Naja ich verstehe das Dictionary erlich gesagt nicht ganz. Wann macht es Sinn es zu nutzen? Ich dachte das es in diesem Fall sinn macht weil das Keyword halt der "Kunde" ist und dem dann Atribute wie Name, Alter usw. zugewiesen werden. Ich gebe zu der Schlüssel "Kundenstamm" war sehr falsch gewählt.
__deets__ hat geschrieben: Sonntag 13. Oktober 2019, 16:26 Alter und Geburtsdatum zu speichern ist redundant, weil man das Alter aus dem Geburtsdatum berechnen kann. Und man sollte in einem Kundenstamm auch deswegen nicht das Alter speichern, weil sich das im Gegensatz zum Geburtsdatum mit der Zeit ändert
Vollkommen richtig. Das war einfach so zum üben
__deets__ hat geschrieben: Sonntag 13. Oktober 2019, 16:26 `age` ist bereits eine Zeichenkette, da braucht man kein `str()` drauf anzuwenden. Wobei das etwas fragwürdig ist, denn eigentlich *ist* das Alter ja eine Zahl. Man sollte das also eher tatsächlich in eine Zahl umwandeln.
Wie behandelt json es dann ? Sprich in der txt Datei ist es dann wieder ein String. Glaube ich sehe das alles zu einfach denn schließlich ist es auf der Festplatte irgendwas aus Nullen und Einsen.
Ich studiere nicht Informatik sondern möchte es für mich selbst neben bei lernen. Deshalb fehlen mir da bestimmt einige Grundlagen.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@shIxx: Warum dachtest Du das "+" das bedeutet? Kann man auch einfach ausprobieren:

Code: Alles auswählen

In [48]: f = open("gibtsnich.xxl", "r+")                                          
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-48-bf83ef210cec> in <module>
----> 1 f = open("gibtsnich.xxl", "r+")

FileNotFoundError: [Errno 2] No such file or directory: 'gibtsnich.xxl'
Man sollte immer ``with`` verwenden wenn das geht. Andernfalls müsste man mehr Zeilen mit ``try``/``finally`` schreiben um das gleiche zu erreichen.

`open()` hat ein `endoding`-Argument. Und JSON an sich ist zwar nur auf ASCII definiert, aber JSON-Lines legt UTF-8 nahe und wenn sich JSON-Dokumente in freier Wildbahn nicht auf ASCII beschränken, sind sie in 99,9% der Fälle UTF-8 kodiert.

Die erste Zuweisung an `user_input` hat in dem Programm letztlich überhaupt gar keinen Effekt. Was sollte da warum zu einer Liste werden wenn die Zeile nicht vorhanden ist?

Wörterbücher machen immer dann Sinn wenn man Schlüssel auf Werte abbilden möchte. Also zum Beispiel um einen Kunden zu beschreiben der aus verschiedenen Eigenschaften besteht.

Falls "Kundenstamm" eigentlich "Kunde" heissen soll, stellt sich die Frage wofür das äussere Wörterbuch gut sein soll? Wenn es nur ein Kunde sein kann braucht man es nicht. Wenn es verschiedene Typen gibt, dann wäre das eher ein Schlüssel "Typ" mit dem Wert "Kunde" im inneren Wörterbuch.

JSON hat Zahlen als Datentyp. JSON hat eine ziemlich kompakte Spezifikation: https://json.org und in der Dokumentation zum JSON-Modul steht wie Datentypen zwischen JSON und Python abgebildet werden. In einer Textdatei serialisiert ist dann letztlich natürlich alles Text, aber wenn man die Daten wieder deserialisiert werden wieder die entsprechenden Python-Datentypen daraus:

Code: Alles auswählen

In [52]: json.dumps([42, "4711"])                                               
Out[52]: '[42, "4711"]'
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
shIxx
User
Beiträge: 22
Registriert: Sonntag 13. Oktober 2019, 16:11

Wahrscheinlich ist hier das JSON nicht gut anzuwenden aber ich wollte einfach das dictionary nach "," und ":" trennen und formatieren können, damit es dann in der txt Datei irgendwie leserlich dargestellt wird.
Kunden:

Name: Alex Musterman
Geburtstag: 01.07.1987

Name: Lisa D.
Geburtstag:26.05.1994
.......

Edit: das sieht man hier nicht aber das wäre noch eingerückt. Also "Kunden" dann eingerückt irgendwelche Daten dazu und dann zu Beispiel "Lieferanten" und wieder eingerückt irgendwelche anderen Daten.
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@shIxx: Dann brauchst Du da eine Liste mit Kunden oder doch wieder ein Wörterbuch mit einem Schlüssel wie "Kundenstamm" der dann auf eine Liste mit Kunden abbildet.

Code: Alles auswählen

In [54]: print(json.dumps([{"Name": "Alex Mustermann", "Geburtsdatum": "1987-07- 01",}, {"Name": "Lisa D.", "Geburtsdatum": "1994-05-26"}], indent=4))
[
    {
        "Name": "Alex Mustermann",
        "Geburtsdatum": "1987-07-01"
    },
    {
        "Name": "Lisa D.",
        "Geburtsdatum": "1994-05-26"
    }
]
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
shIxx
User
Beiträge: 22
Registriert: Sonntag 13. Oktober 2019, 16:11

Danke für deine Hilfe aber ich glaube ich geh erstmal ein paar Schritte zurück und versuche das ganz einfach mit Listen und .write().
Um die Formatierung kann man sich ja dann noch immer kümmern.

Ist das richtig, das man grundsätzlich wie folgt vorgeht?

Code: Alles auswählen

alter_inhalt = read(dateiname) 		# Datei auslesen und zwischenspeichern 
neue_daten = user_input()		# Daten manipulieren oder neue Daten generieren
write(alter_inhalt, neue_daten) 	# zusammen führen von alten und neuem Daten und Datei überschreiben
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du glaubst nur du gehst einen Schritt zurück. Stimmt nicht, ist nur ein Umweg. Denn man kann Datenstrukturen halt nicht einfach speichern und laden. Dazu bedarf es konkrete Dateiformate. Wenn du JSON (oder andere wie pickle oder shelve, aber die sind nicht anzuraten aus diversen Gründen) nicht nimmst, musst du dir also erstmal ein Format ausdenken, umsetzten und erst DANN kannst du weitermachen. Sind also diverse Schritte. Eben ein Umweg.
Antworten