quink hat geschrieben:
ValueError: need more than 0 values to unpack
und markiert mir diese Zeile als Fehler:
Code: Alles auswählen
englisches_wort, deutsches_word = zeile.strip().split()
Ich komm nicht dahinter wo der Fehler steckt :K
Dieser Fehler kann so nicht auftreten, wenn die Datei wirklich leer ist. Er kann nur auftreten, wenn in der Datei Zeichen stehen. Bist Du sicher, dass da keine Whitespaces enthalten sind?
Zudem solltest Du uns immer den *kompletten* Fehler hier posten, also die vollständige Fehlerausgabe des Interpreters.
Dein Parser - also das, was in `buch_einlesen` passiert - ist wenig "robust". Du gehst davon aus, dass in jeder Zeile genau zwei Wörter stehen, die durch Whitespaces getrennt sind. Sobald da nur ein Wort oder auch mehrere drin stehen, kracht es.
Ich simuliere das mal in einer Shell:
Code: Alles auswählen
In [8]: a, b = "hello hallo".split()
In [9]: a, b = "hello hallo foo".split()
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/home/nelson/src/Python/forum/<ipython-input-9-b6c7c598eafe> in <module>()
----> 1 a, b = "hello hallo foo".split()
ValueError: too many values to unpack (expected 2)
In [10]: a, b = " ".split()
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
/home/nelson/src/Python/forum/<ipython-input-10-b27890d4aff3> in <module>()
----> 1 a, b = " ".split()
ValueError: need more than 0 values to unpack
In [8] klappt das Parsen, in [9] habe ich zu viele Werte für die beiden Namen und in [10] zu wenige. So etwas kann man leicht in einer Shell ausprobieren! (hier IPython, also nicht durch den [zahl]-prompt verwirren lassen, sonst steht da ">>>")
quink hat geschrieben:
So viel ich verstehe will er ein englisches Wort UND ein deutsches Wort haben, aber in der Datei is ja nix drin.. Und nu?? Wie muß das Programm verändert werden das er wenn nix drin steht weitermacht?
Sofern wirklich *nichts* in der Datei steht, musst Du nichts ändern, da dann die Schleife erst gar nicht durchlaufen wird.
quink hat geschrieben:
Ach so, wenn ich was in die Datei reinschreibe, zb:
Haus, house
meckert er auch
Auch hier gilt: Wir brauchen die *exakte* Fehlermeldung. Eigentlich sollte das nicht passieren... insofern muss es sich um einen anderen Fehler oder eine andere Stelle im Code handeln!
quink hat geschrieben:
Und noch etwas, bei mir wird in der Frage-Textbox keine deutsche Sonderzeichen angezeigt, wie kann man das machen das er deutsche Sonderzeichen anzeigt?
Was ist die "Frage-Textbox"? Meinst Du die Shell? Generell sind das immer Encoding-Probleme. Lies Dir dazu mal die Links in meiner Signatur durch.
Btw: Die Namen sind der Hammer... `deutsches_wor
d`
Generell solltest Du imho *alles* wegwerfen und bei null anfangen. Ich versuche das mal zu begründen:
Du fängst inhaltlich an der falschen Stelle an. Was interessiert Dich denn die Datei und das Format, in der Du die Vokabeln speicherst? Persistenz ist ja gut und schön, sollte aber imho nicht zu Beginn der Entwicklung stehen! (Zumindest nicht bei solch einfachen Projekten) Du solltest Dich erst einmal auf das Wesentliche, also das Testen von Vokabeln, ggf. die Bewertung eines Tests usw. bemühen. Beispielvokablen kann man sich doch zunächst locker *statisch* im Programm hinterlegen:
Code: Alles auswählen
VOCABULARIES = {
"hello": "Hallo",
"world": "Welt",
...
}
Damit kann man erst einmal alles zur Genüge testen.
"Testen" ist ein weiteres wichtiges Stichwort in diesem Zusammenhang. Wieso hast Du bereits 30, 40 Zeilen Code, wenn Du an einer zentralen Stelle einen Fehler hast? Vermutlich hast Du `buch_abspeichern` noch gar nicht laufen lassen? Du musst Code immer so schreiben, dass Du Funktionen *separat* von anderen testen kannst. Ich stelle mir irgend wie vor, dass Du dieses Programm einfach so runter geschrieben hast. So darfst Du *nie* vorgehen.
Generell solltest auf globale Variablen verzichten! Schreibe Deine Funktionen so, dass sie die notwendigen Daten als Parameter übergeben bekommen müssen. Also bei `wort_eingeben` z.B. das Dictionary mit den Vokabeln, beim Laden den Dateinamen usw. Wenn diese Funktionen Daten generieren, dann sollten sie diese per `return` an die aufrufende Funktion zurückgeben. Das käme z.B. beim Laden zum Tragen.
Du hast eine ungewollte Rekursion in Deinem Programm! Du rufst aus den Funktionen andere Funktionen auf, ohne jemals zurück zu springen. Aus `buch_einlesen` springst Du in `wort_eingeben` in `buch_abspeichern` und von dort in `wort_eingaben` und so geht das weiter, bis der Stack voll ist. Dann gibt es einen Fehler...
Du kannst das mal selber austesten:
Code: Alles auswählen
In [14]: def foo():
....: bar()
....:
In [15]: def bar():
....: foo()
....:
Wenn Du nun eine der beiden Funktionen aufrufst, wirst Du nach einiger Zeit diese Meldung erhalten:
Schreibe Dein Programm so um, dass Du aus einem Menü heraus auswählen kannst, welche Aktion Du als nächstes vornehmen willst. Wenn Du Wörter in das Wörterbuch hinzufügen willst, dann musst Du diese ja nicht sofort speichern. Das kannst Du ja auch später erledigen, sprich, sobald Du die entsprechende Option ausgewählt hast. Willst Du das dennoch sofort erledigen, so kehre aus der "Speichern"-Funktion einfach zurück. Das geht ja einfach so, *ohne* dass Du irgend etwas tun musst
Du solltest Deine Funktionen so benennen, dass sie die Logik auch widerspiegeln. `wort_eingeben` macht ja viel mehr als das, was der Name ausdrückt. Es fügt ein neues Pärchen dem Dictionary hinzu und speichert das veränderte Wörterbuch ab. Das würde niemand erwarten, der nur den Namen "wort_eingeben" liest. Namen sind sehr sehr wichtig! (Und leider schwierig passend zu wählen

)
Achte auch bitte auf die Formatierung Deines Codes. Lies Dir dazu mal PEP8 durch. Das schreibt vier Spaces als Einrückungsebene vor. Bei Dir schwankt das irgend wie zwischen fünf und zwei...
Bei Dateipfaden solltest Du auch immer Raw-Strings verwenden, da es sonst zu ungewollten Escape-Sequenzen kommen kann:
(Beachte das "r" vor dem String-Literal!)
Als letztes: Wenn Du Python 2.x verwendest, dann lass die Klammern beim `print` weg! `print` ist in Python 2.7 ein Statement - also "tarne" es nicht als Funktion. Wo kommt das eigentlich her? Man liest das in letzter Zeit immer mehr... sollte das Tutorial aus dem "Freien Magazin" doch so beliebt sein?
Als letztes gebe ich Dir noch einen Tipp: Benutze das `csv`-Modul, um Dein Wörterbuch in eine Datei zu schreiben, oder es aus dieser zu laden. Dann musst Du Dich nicht um das Parsen selber kümmern. Noch einfacher wäre es in diesem Falle sogar mit dem `json`-Modul. Damit kämst Du auf jeweils *eine* Zeile fürs Speichern und Laden (ohne die Zeile zum Öffnen der Datei).
Ach ja, das Dateihandling ist bei Dir auch Grütze. Erkläre mir doch mal, was diese beiden Zeilen machen:
Code: Alles auswählen
buch = open(vokabeln_dateiname)
with open(vokabeln_dateiname) as buch:
Und wenn Du das nicht kannst, lies es eben noch mal in Deinem Tutorial nach. (Kleiner Tipp: Eine Zeile davon ist mindestens überflüssig

)
So, ich hoffe das hat Dich nicht demotiviert, sondern hilft Dir, Dich weiter zu verbessern! In diesem Sinne habe ich es geschrieben - also nicht in den falschen Hals bekommen. Lernen kannst Du nur durch (konstruktive) Kritik
