Problem beim Bearbeiten und Abspeichern einer Liste

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
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

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!
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!
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Könntest du dich bitte etwas genauer ausdrücken, weil so hilft das einem Anfänger wie mir überhaupt nicht weiter.

Trotzdem Danke!
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

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() 
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

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]
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

Ich habe jetzt herausgefunden, dass der aus irgendeinem Grund immer in Zeile 22 sprint und den Try-Block nie benutzt. Warum?
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.
Nirven
User
Beiträge: 130
Registriert: Mittwoch 10. Mai 2006, 08:18
Wohnort: Bremerhaven

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.
basti33
User
Beiträge: 56
Registriert: Donnerstag 24. August 2006, 15:05

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
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

'w' löscht den Inhalt. Du suchst glaube ich 'r+' oder 'a', weiss nicht mehr, welches
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".
Antworten