Seite 1 von 1

frage zu pickle

Verfasst: Sonntag 17. Dezember 2006, 12:34
von cyp++
hallo,

ich habe ein kleines problem mit dem modul "pickle" undzwar will es nicht richtig funktionieren bzw nicht richtig laden, ob es richtig speichert weiß ich auch nicht so recht, da ich ja auch nichts laden kann. Es geht eigentlich nur um die ersten beiden funktionen "saveVoc()" und "loadDict()" der Rest funktioniert einwandfrei, wenn ihr natürlich noch Verbesserungsvorschläge habt, immer her damit! :D Hier erstmal mein Code:

Code: Alles auswählen

import pickle

def saveVoc():
    f = file('dict.dmp', 'w')
    pickle.dump(dict,f)
    f.close()

def loadDict():
    f = file('dict.dmp', 'r')
    pickle.load(f)
    f.close()

def writeVocIntoDict():
    word = raw_input('\nEnter the word: ')
    transword = raw_input('\nEnter the translation: ')
    dict[word] = transword
    # translated word as key
    dict[transword] = word
    saveVoc()


def menu():
    print '1) Add vocabulary'
    print '2) Translate a word'
    sel = int(raw_input ('\nWhat do you want? '))
    if sel >= 1 and sel < 3:
        if sel == 1:
            writeVocIntoDict()
        elif sel == 2:
            word = raw_input('Enter the word: ')
            if word in dict:
                print dict[word]
            else:
                print 'vocabulary not known'
    else:
        print 'Error! Only numbers from 1 to 2 are allowed!'

    menu()


dict = {}

print '\nDictionary 1.000.000 by read error\n**********************************'
loadDict()
menu()
mfg

Re: frage zu pickle

Verfasst: Sonntag 17. Dezember 2006, 12:47
von birkenfeld
cyp++ hat geschrieben:

Code: Alles auswählen

i
def loadDict():
    f = file('dict.dmp', 'r')
    pickle.load(f)
    f.close()
Ja, das lädt von "f", aber wohin? Du wirfst den Rückgabewert von pickle.load() einfach weg. loadDict gibt None zurück.

Verfasst: Sonntag 17. Dezember 2006, 13:06
von cyp++
ok, habe jetzt folgendes:

Code: Alles auswählen

def loadDict():
    f = file('dict.dmp', 'r')
    load = pickle.load(f)
    f.close()
und nu? wie ruf das ich nu auf? normal wie ich es vorher auch getan habe oder muss ich noch irgendwas ändern? und muss ich bei saveVoc() auch ändern? weil da habe ich ja auch nur

Code: Alles auswählen

pickle.dump(dict,f)
ohne irgendeine zuweisung?

Verfasst: Sonntag 17. Dezember 2006, 13:35
von BlackJack
cyp++ hat geschrieben:ok, habe jetzt folgendes:

Code: Alles auswählen

def loadDict():
    f = file('dict.dmp', 'r')
    load = pickle.load(f)
    f.close()
und nu? wie ruf das ich nu auf? normal wie ich es vorher auch getan habe oder muss ich noch irgendwas ändern?
Du wirfst die Daten immer noch weg. Das Dictionary wird jetzt geladen, an den Namen `load` gebunden, und der verschwindet am Ende der Funktion wieder und damit auch die geladenen Daten.

Code: Alles auswählen

def loadDict():
    f = file('dict.dmp', 'rb')
    result = pickle.load(f)
    f.close()
    return result
Beim schreiben solltest Du die Datei auch im Binärmodus öffnen und bitte benutze 1. keine globalen Variablen und 2. nicht den Namen `dict`, der überschreibt nämlich die eingebaute `dict()`-Funktion.

Werte sollten Funktionen möglichst nur über Argumente betreten und über Rückgabewerte verlassen. Sonst werden Programme sehr schnell unübersichtlich und Funktionen lassen sich nicht isoliert testen oder benutzen.

Re: frage zu pickle

Verfasst: Sonntag 17. Dezember 2006, 14:01
von BlackJack
cyp++ hat geschrieben:[...], wenn ihr natürlich noch Verbesserungsvorschläge habt, immer her damit!
Na dann, Du hast es ja so gewollt. :-)

Die Funktionsnamen halten sich nicht an die Konvention kleinbuchstaben_und_unterstriche.

Pickle-Dateien müssen als Binärdateien geöffnet werden, sonst sind sie nicht auf andere Plattformen übertragbar.

Das selbe Dictionary auch für "reverse lookup" zu benutzen, bringt spätestens Probleme wenn ein Wort in beiden Sprachen vorkommt, aber unterschiedliche Übersetzungen hat.

Bereichsabfragen kann man in Python auch ohne ``and`` ausdrücken: ``if 1 <= sel <= 2:``.

Eine einfache Endlosschleife durch Rekursion auszudrücken (`menu()`), ist in Python keine so gute Idee weil dabei irgendwann der Stack überläuft.

Verfasst: Sonntag 17. Dezember 2006, 14:27
von cyp++

Code: Alles auswählen

import pickle

def saveVoc():
    f = file('dict.dmp', 'w')
    save = pickle.dump(dict_,f)
    f.close()

def loadDict():
    f = file('dict.dmp', 'rb')
    result = pickle.load(f)
    f.close()
    return result

def writeVocIntoDict():
    word = raw_input('\nEnter the word: ')
    transword = raw_input('\nEnter the translation: ')
    dict_[word] = transword
    # translated word as key
    dict_[transword] = word
    saveVoc()


def menu():
    print '1) Add vocabulary'
    print '2) Translate a word'
    sel = int(raw_input ('\nWhat do you want? '))
    if 1 <= sel <= 2:
        if sel == 1:
            writeVocIntoDict()
        elif sel == 2:
            word = raw_input('Enter the word: ')
            if word in dict_:
                print dict_[word]
            else:
                print 'vocabulary not known'
    else:
        print 'Error! Only numbers from 1 to 2 are allowed!'

    menu()


dict_ = {}

print '\nDictionary 1.000.000 by read error\n**********************************'
loadDict()
menu()
Die Funktionsnamen halten sich nicht an die Konvention kleinbuchstaben_und_unterstriche.
sorry ich hab da was anderes gelernt, mir schwebt da irgendwas von UML vor..
Pickle-Dateien müssen als Binärdateien geöffnet werden, sonst sind sie nicht auf andere Plattformen übertragbar.
erledigt!
Das selbe Dictionary auch für "reverse lookup" zu benutzen, bringt spätestens Probleme wenn ein Wort in beiden Sprachen vorkommt, aber unterschiedliche Übersetzungen hat.
was meinst du damit? meinst du ich sollte, wenn ein wort hinzugefügt wird, es nicht ersetzen, sondern den neuen value anhängen?
Bereichsabfragen kann man in Python auch ohne ``and`` ausdrücken: ``if 1 <= sel <= 2:``.
erledigt!
Eine einfache Endlosschleife durch Rekursion auszudrücken (`menu()`), ist in Python keine so gute Idee weil dabei irgendwann der Stack überläuft.
wie kann ich das umgehen? sollte ich vll einfach eine option "beenden" hinzufügen zu menu() ?

es treten jetzt folgende tracebacks auf:

Code: Alles auswählen

Traceback (most recent call last):
  "[..]dict.py", line 45, in ?
  loadDict()
  "[..]dict.py", line 10, in loadDict
  result = pickle.load(f)
  File "E:\python\lib\pickle.py" , line 1390, in load
  return Unpickler(file).load()
  "[..]pickle.py", line 872, in load
  dispatch[key](self)
  "[..]pickle.py", line 980, in load_string
  raise ValueError, "insecure string pickle"
ValueError: insecure string pickle
:shock:

Verfasst: Sonntag 17. Dezember 2006, 14:33
von birkenfeld
cyp++ hat geschrieben:
Die Funktionsnamen halten sich nicht an die Konvention kleinbuchstaben_und_unterstriche.
sorry ich hab da was anderes gelernt, mir schwebt da irgendwas von UML vor..
Was hat UML damit zu tun, wie deine Methoden heißen?
Das selbe Dictionary auch für "reverse lookup" zu benutzen, bringt spätestens Probleme wenn ein Wort in beiden Sprachen vorkommt, aber unterschiedliche Übersetzungen hat.
was meinst du damit? meinst du ich sollte, wenn ein wort hinzugefügt wird, es nicht ersetzen, sondern den neuen value anhängen?
Z.B.
englisch still <-> deutsch noch
deutsch still <-> englisch quiet

Da bekommst du Probleme. Es wäre also besser, zwei Dicts, für jede Richtung eines, zu verwenden.
Eine einfache Endlosschleife durch Rekursion auszudrücken (`menu()`), ist in Python keine so gute Idee weil dabei irgendwann der Stack überläuft.
wie kann ich das umgehen? sollte ich vll einfach eine option "beenden" hinzufügen zu menu() ?
Nein. Das Problem ist, dass menu() wieder menu() aufruft. In diesem Fall, wo die Funktion sich als letzten Schritt aufruft, nennt man das "tail recursion". In funktionalen Programmiersprachen ist das erwünscht, während man in Python lieber eine while-Schleife verwenden sollte.

Verfasst: Sonntag 17. Dezember 2006, 14:38
von Leonidas
Ich habe deinen Code mal etwas umgeschrieben, findest ihn im LodgeIt. Ist allerdings ungetestet, da ich es aus dem Kopf gemacht habe (dafür habe ich ein paar Dinge kommentiert). Ansonsten müsste man wie BlackJack sagte, den Dictionary-Lookup ändern.

Verfasst: Sonntag 17. Dezember 2006, 21:50
von Spaten
..wenn ich als Tip am Rande anmerken darf:
es gibt außer dem Modul Pickle auch noch ein Modul
cPickle, dieses ist mit pickle komplett identisch, arbeitet aber schneller,
da es komplett in C implementiert ist.

Code: Alles auswählen

import cPickle