Seite 1 von 1

Problem beim Bearbeiten und Abspeichern einer Liste

Verfasst: Freitag 15. September 2006, 17:50
von basti33
Hallo,

ich habe ein Problem mit diesem Programm.

Code: Alles auswählen

#!/usr/bin/python
# -*-coding: utf-8 -*-

# Version 0.1

import random
import cPickle

class Vokabeln:
    def __init__(self, Vokabeldatei):
        self.Vokabeldatei = Vokabeldatei
    
    def neueVokabeln(self):
        try:
            f=file(self.Vokabeldatei, 'w')
            e=cPickle.Unpickler(f)
            z=e.load()
            neu=z.append([raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')])
            p=cPickle.Pickler(neu)
            p.dump()
            f.close
        except IOError:
            f=file(self.Vokabeldatei, 'w')
            p=cPickle.Pickler(f)
            p.dump([[raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')]])
            f.close
        
    def frageVokabeln(self):
        f=open(self.Vokabeldatei, 'r')
        up=cPickle.Unpickler(f)
        vokabeln=up.load()         
        print vokabeln
        laenge=len(vokabeln)
        a=random.randrange(0, laenge)
        print vokabeln[a][0]
        if raw_input('Antwort: ') == vokabeln[a][1]:
            print 'Richtig'
        else:
            print 'Falsch\nRichtig wäre ',vokabeln[a][1],'!'
        f.close()
        
print '''Das ist ein kleines Vokabelabfrageprogramm\n
Man benutzt es, indem man "Frage" eintippt.
Wenn man neue Vokabeln anlegen möchte, tippt man "neu"'''

weiter=True
while weiter:
    vok=Vokabeln('/home/basti/Eigene_Dateien/vok.data')
    antwort=raw_input('Was möchten Sie tun? ')
    if antwort == 'neu':
        vok.neueVokabeln()
        continue
    elif antwort == 'Frage':
        vok.frageVokabeln()
    else:
        print "Das gibt's nicht"
Es soll ein Programm zum Vokabelabfragen werden, hat jedoch einen Fehler.
Wenn ich eine neue Vokabel hinzufüge, wird diese mit ihrer Übersetzung gespeichert und lässt sich auch korrekt abfragen. Wenn ich jetzt eine neue Vokabel hinzufüge, dann überschreibt diese jedoch die erste usw.. Ich vermute, dass der Fehler irgenwo zwischen Zeile 13 und 26 liegt.

Ich bedanke mich für jede Hilfe!

Verfasst: Freitag 15. September 2006, 18:55
von BlackJack
Gib doch mal mit `print repr(obj)` einige der Objekte im Verlauf des Programms aus, um zu sehen ob sie wirklich den Wert enthalten, den sie sollten. Bei `neu` wirst Du zum Beispiel eine interessante Entdeckung machen.

Und Du schliesst die Datei nicht immer. Zu einem Methodenaufruf gehören Klammern!

Verfasst: Freitag 15. September 2006, 19:01
von basti33
Könntest du dich bitte etwas genauer ausdrücken, weil so hilft das einem Anfänger wie mir überhaupt nicht weiter.

Trotzdem Danke!

Verfasst: Freitag 15. September 2006, 19:13
von DatenMetzgerX

Code: Alles auswählen

            z=e.load()
            neu=z.append([raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')])
            p=cPickle.Pickler(neu)
Neu beinhaltet nachher nicht die neue Liste!

Du musst dies so machen...

Code: Alles auswählen

            z=e.load()
            z.append([raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')])
            p=cPickle.Pickler(z)
nicht

Code: Alles auswählen

f.close 
sondern...

Code: Alles auswählen

f.close() 

Verfasst: Freitag 15. September 2006, 19:18
von basti33

Code: Alles auswählen

#!/usr/bin/python
# -*-coding: utf-8 -*-

# Version 0.1

import random
import cPickle

class Vokabeln:
    def __init__(self, Vokabeldatei):
        self.Vokabeldatei = Vokabeldatei
    
    def neueVokabeln(self):
        try:
            f=file(self.Vokabeldatei, 'w')
            e=cPickle.Unpickler(f)
            z=e.load()
            z.append([raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')])
            p=cPickle.Pickler(z)
            p.dump()
            f.close()
        except IOError:
            f=file(self.Vokabeldatei, 'w')
            p=cPickle.Pickler(f)
            p.dump([[raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')]])
            f.close()
        
    def frageVokabeln(self):
        f=open(self.Vokabeldatei, 'r')
        up=cPickle.Unpickler(f)
        vokabeln=up.load()         
        print vokabeln
        laenge=len(vokabeln)
        a=random.randrange(0, laenge)
        print vokabeln[a][0]
        if raw_input('Antwort: ') == vokabeln[a][1]:
            print 'Richtig'
        else:
            print 'Falsch\nRichtig wäre ',vokabeln[a][1],'!'
        f.close()
        
print '''Das ist ein kleines Vokabelabfrageprogramm\n
Man benutzt es, indem man "Frage" eintippt.
Wenn man neue Vokabeln anlegen möchte, tippt man "neu"'''

weiter=True
while weiter:
    vok=Vokabeln('/home/basti/Eigene_Dateien/vok.data')
    antwort=raw_input('Was möchten Sie tun? ')
    if antwort == 'neu':
        vok.neueVokabeln()
    elif antwort == 'Frage':
        vok.frageVokabeln()
    else:
        print "Das gibt's nicht"
Damit keine Missverständnisse entstehen habe ich den Code hier erneut gepostet.

DatenMetzgerX, danke für den Tip, aber irgendwie funktioniert es immer noch nicht.[/code]

Verfasst: Freitag 15. September 2006, 19:36
von basti33
Ich habe jetzt herausgefunden, dass der aus irgendeinem Grund immer in Zeile 22 sprint und den Try-Block nie benutzt. Warum?

Verfasst: Freitag 15. September 2006, 20:36
von BlackJack
Er "benutzt" den `try`-Block. Da tritt aber ein `IOError` auf. Schau Dir mal an was `Pickler` als Argument bei der Initialisierung haben wollen und was Du stattdessen übergibst.

Und einem Anfänger sollte der Tip, dass er ``print`` benutzen soll um sich zu überzeugen was die Objekte zu einem bestimmten Zeitpunkt für einen Wert haben, durchaus helfen.

Verfasst: Freitag 15. September 2006, 20:39
von Nirven
Ich vermute mal, weil es in dem try-Block eine exception gibt.

füg mal

Code: Alles auswählen

print 'Try'
in Zeile 15 ein. Dann siehst du, dass er da reingeht.

Verfasst: Freitag 15. September 2006, 22:13
von basti33
Hallo,

ich habe das Ganze jetzt so gelöst

Code: Alles auswählen

def neueVokabeln(self):
        try:
            f=file(self.Vokabeldatei, 'r')
            up=Unpickler(f)
            l=up.load()
            l.append([raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')])
            f=file(self.Vokabeldatei, 'w')
            p=Pickler(f)
            p.dump(l)
            f.close()
        except EOFError:
            f=file(self.Vokabeldatei, 'w')
            p=Pickler(f)
            p.dump([[raw_input('Schreibe hier die neue Vokabel: '), raw_input('Schreibe hier ihre Übersetzung: ')]])
            f.close()
Ich hoffe mal, dass das eine einigermaßen elegante Lösung ist :?.

Danke für die Hilfe. :D

Verfasst: Samstag 16. September 2006, 09:42
von Joghurt
'w' löscht den Inhalt. Du suchst glaube ich 'r+' oder 'a', weiss nicht mehr, welches

Verfasst: Samstag 16. September 2006, 11:25
von BlackJack
Nein er sucht schon 'w' bzw. hat es gefunden. Bei 'a' würde jedesmal eine neue "gepicklete" Liste mit zusätzlichen Elementen an die schon vorhandenen Daten angehängt werden werden, die Daten würden also mehrfach in der Datei stehen. Und das auslesen würde dann natürlich auch nicht mehr funktionieren weil immer nur die erste "gepicklete" Liste eingelesen würde.

Zur Frage der Eleganz, naja. Es wäre vielleicht besser wenn die Daten beim erstellen des Objekts einmal geladen würden und die Klasse eine explizite `save()` Methode bekäme, anstatt bei jedem Zugriff auf eine Vokabel die die Datei "anzufassen".