Seite 2 von 4

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 14:09
von Xfd7887a
Habe das ganze so geändert:

Code: Alles auswählen

try:
    with open("aufgaben.txt") as aufgaben_datei:
        AUFGABEN = load(aufgaben_datei)
except:
    with open("aufgaben.txt", "w") as aufgaben_datei:
        dump(dict(), aufgaben_datei)
        AUFGABEN = load(aufgaben_datei)
Wird nun die Datei automatisch geschlossen?

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 14:14
von Hyperion
Das ist eine komische Logik... ich musste da erst genau hinsehen, um zu begreifen, dass Du die Datei "leer" anlegst, wenn diese nicht geöffnet werden konnte.

Lesen und Schreiben würde ich komplett trennen, also eine Funktion ``dump`` und eine ``load`` oder so ähnlich.

Wenn Die Datei (noch) nicht existiert, dann gib einfach ein *leeres* Dictionary zurück :-)

Das ist imho das sinnvollere Vorgehen!

Und fange niemals *alle* Exceptions ab, sondern nur die, auf die Du reagieren willst. In Deinem Falle also eine ``FileNotFoundError``-Exception.

Ansonsten: Ja, so werden die Dateien automatisch geschlossen.

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 14:22
von Xfd7887a
Danke :D

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 15:32
von cofi
Hyperion hat geschrieben:Und fange niemals *alle* Exceptions ab, sondern nur die, auf die Du reagieren willst. In Deinem Falle also eine ``FileNotFoundError``-Exception.
Genau das. Spiel mal durch was passiert, wenn du keine Spreibrechte fuer die Datei "aufgaben.txt" hast :)

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 19:09
von Xfd7887a
Ich habe gerade versucht mein Programm zu "verbessern". Leider habe ich rumgemurkst, jetzt werden Änderungen einfach nicht gespeichert. Hier das Script: https://github.com/toxinman/stuff/blob/master/todo.py Ich weiß nicht, was ich geändert habe.

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 19:18
von EyDu
Ich gebe mal einen Tipp ab: Du beendest das Programm über die "programm_beenden"-Funktion. Diese ruft dann allerdings die exit-Funktion auf, welche das Programm direkt beendet. Dadurch wird das Speichern nicht mehr ausgeführt. Bei solchen Problemen hilft es oft, wenn du ein paar print-Statements in dein Programm einbaust. Dann siehst du recht schnell ob du irgendwo im Code ankommst oder nicht.

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 19:30
von pillmuncher
cofi hat geschrieben:[...] keine Spreibrechte fuer die Datei [...]
Muss es nicht Speibrechte[*] heißen?

[*]Von Bairisch: speiben (schbaim): spucken, erbrechen.

Re: Aufgabenverwaltung

Verfasst: Freitag 27. Juni 2014, 22:03
von cofi
@pillmuncher: Dann ist immer noch ein "b" zu viel 8)
Nein, das ist ein reichlich verungluecktes "Schreibrechte" :roll:

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 09:09
von Xfd7887a
Ich habe versucht, die Schleife explizit zu verlassen, aber die Datei wird immer noch nicht gespeichert :K

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 10:17
von BlackJack
@Xfd7887a: Wie stellst Du das denn fest? Hast Du nach Programmende tatsächlich mal in die Datei geschaut, oder denkst Du das nur weil nach einem erneuten Programmstart keine Daten in `AUFGABEN` sind?

Hier sieht man schön warum nackte ``except``\s ohne konkrete Ausnahmen keine gute Idee sind. Du rennst wegen einem Programmierfehler immer in das ``except`` in Zeile 103 und merkst das nicht, weil dort eben nicht nur die Ausnahmensituationen behandelt werden die Du erwartest, sondern auch mindestens eine die bei einem korrekten Programm gar nicht vorkommen dürfte. Und der Fehler sorgt auch dafür das die Datei bei jedem Programmstart geleert wird.

Die Schreibweise von `AUFGABEN` ist für eine Datenstruktur die während des Programmlaufs verändert werden soll übrigens falsch. Ausschliesslich Grossbuchstaben werden per Konvention nur für konstante Werte verwendet.

Es wäre übrigens praktischer wenn Du beim Verlinken Deines Quelltextes nicht immer wieder das Master-Tag verwenden würdest, sondern einen Link auf die konkrete Revision die gemeint ist. Denn sonst kann man nach Änderungen an Master die Antworten hier nicht mehr wirklich nachvollziehen, sondern muss sich erst anhand des Beitragsdatums die richtige Revision auf Github heraus suchen.

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 10:52
von Xfd7887a
Ich glaube, ich habe nicht verstanden, was du meinst. Meine Änderung:

Code: Alles auswählen

 with open("aufgaben.txt", "w") as aufgaben_datei:
      try:
 -        AUFGABEN = load(aufgaben_datei)
 -    except:
 -        AUFGABEN = dict()
 +        aufgaben = load(aufgaben_datei)
 +    except IOError:
 +        aufgaben = dict()
Leider funktioniert es immer noch nicht, obwohl ich doch eigentlich nur abfange, wenn die Datei leer ist.
Hier sieht man schön warum nackte ``except``\s ohne konkrete Ausnahmen keine gute Idee sind. Du rennst wegen einem Programmierfehler immer in das ``except``
Welcher Fehler ist das?
Es wäre übrigens praktischer wenn Du beim Verlinken Deines Quelltextes nicht immer wieder das Master-Tag verwenden würdest, sondern einen Link auf die konkrete Revision die gemeint ist.
Wie geht das?

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 10:56
von EyDu
Xfd7887a hat geschrieben:Welcher Fehler ist das?
Nimm das except mal raus ;-)

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 11:02
von BlackJack
@Xfd7887a: Die Änderung behandelt jetzt alles was ein `IOError` ist, das ist mehr als nur das die Datei nicht existiert. Der Fall das die Datei nicht existiert, kann nebenbei gesagt innerhalb des ``try``/``except`` überhaupt gar nicht auftreten weil Du dort bereits ein geöffnetes Dateiobjekt vor dem betreten hast. Dann *muss* die Datei existieren, denn wie könnte man sonst so ein Objekt haben!?

Gib der Ausnahme in dem ``except`` noch einen Namen und gib das Ausnahmeobjekt dann doch einfach mal mit ``print`` aus, dann siehst Du ja was die Nachricht von dem Objekt sagt.

Zum verlinken: Du könntest zum Beispiel über die History gehen und da beim gewünschten Commit-Stand auf „Browse code →” klicken um zum Stand der Datei zu dem konkreten Commit zu kommen. So bin ich auf den Link in meinem letzten Beitrag gekommen.

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 11:33
von Xfd7887a
Ok, danke. Werde mich damit auseinandersetzen :D

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 12:09
von Xfd7887a
Die Ausgabe ist:

Code: Alles auswählen

File not open for reading
Das verstehe ich nicht, ich habe die Datei doch geöffnet.
Der Fall das die Datei nicht existiert, kann nebenbei gesagt innerhalb des ``try``/``except`` überhaupt gar nicht auftreten weil Du dort bereits ein geöffnetes Dateiobjekt vor dem betreten hast.
Ja, die Datei ist immer da. Mir geht's im Moment darum, ob sie gefüllt oder leer ist.

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 12:16
von BlackJack
@Xfd7887a: Da steht nicht die Datei wäre nicht geöffnet sondern sie ist nicht *zum lesen* geöffnet. Man kann aus einer Datei die man zum schreiben öffnet, nicht lesen. Und wenn man eine zum schreiben öffnet, wird sie geleert — das heisst was Du ganz am Anfang machst, ist die Daten zu löschen die Du eigentlich einlesen möchtest.

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 12:44
von Xfd7887a
Danke :D
Habe das jetzt so:

Code: Alles auswählen

def datei_laden():
    datei = open("aufgaben.txt")
    aufgaben = pickle.load(datei)
    return aufgaben


def in_datei_schreiben(daten):
    datei = open("aufgaben.txt", "w")
    pickle.dump(daten, datei)
    datei.close()
und so:

Code: Alles auswählen

try:
    aufgaben = datei_laden()
except IOError:
    in_datei_schreiben(dict())
    aufgaben = datei_laden()
gelöst. Sicherlich ist das ziemlich umständlich, aber es funktioniert :D

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 12:57
von BlackJack
@Xfd7887a: Da wird beim Laden die Datei wieder nicht geschlossen. Warum verwendest Du in den beiden Funktionen nicht die ``with``-Anweisung?

Und warum jetzt `pickle` statt `json`?

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 13:03
von Xfd7887a
Stimmt, das habe ich übersehen:

Code: Alles auswählen

def datei_laden():
    with open("aufgaben.txt") as datei:
        aufgaben = pickle.load(datei)
    return aufgaben


def in_datei_schreiben(daten):
    with open("aufgaben.txt", "w") as datei:
        pickle.dump(daten, datei)
Weil das die bevorzugte Variante für Python zu sein scheint. Aber eigentlich ist das Format ja egal.

Re: Aufgabenverwaltung

Verfasst: Samstag 28. Juni 2014, 13:28
von mutetella
Xfd7887a hat geschrieben:Weil das die bevorzugte Variante für Python zu sein scheint.
Wäre ja mal interessant, was "die bevorzugte" Variante wirklich ist, aber Pickle IMHO nicht.
Xfd7887a hat geschrieben:Aber eigentlich ist das Format ja egal.
Also pickle hat für mich zwei entscheidende Nachteile: Zum einen sind pickle-Dateien nicht menschenlesbar, zum anderen darf sich, wenn Du pickle zum Speichern von Klassenexemplaren verwendest, an deren Struktur nichts ändern. Ok, letzteres betrifft Dich nicht, wollte ich aber erwähnt haben.

mutetella