Seite 2 von 3

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 13:57
von smodo
habs grad mal mit:

Code: Alles auswählen

def film_hinzu(titel):
    with open("filme.pkl", "rb") as pkl_file:
        movie_list = pickle.load(pkl_file)
    movie_list.append(titel)
    with open("filme.pkl", "wb") as output:
        pickle.dump(movie_list, output)
probiert.

Code: Alles auswählen

Film Hinzufügen: Batman
Traceback (most recent call last):
  File "filbi.py", line 84, in <module>
    main() 
  File "filbi.py", line 69, in main
    film_hinzu(titel)
  File "filbi.py", line 12, in film_hinzu
    movie_list = pickle.load(pkl_file)
  File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
KeyError: '\n'

und ja ich habs jetzt verstanden, ich kann an der quelle nicht rumpfuschen, ich kann nur eine "kopie" machen, die bearbeiten und dann neu in die quelle einfügen.

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 14:01
von BlackJack
@smodo: Dann steht in der Datei etwas mit dem `pickle` nicht klar kommt.

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 14:06
von smodo
jo und das ist irgendwo ein "\n" so wie es aussieht. :)

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 14:33
von Rekrul
@Hyperion
Hyperion hat geschrieben:Und was kann `shelve`, was pickle nicht kann?
Da shelve auf pickle aufbaut, behaupte ich einfach mal: es kann nicht mehr.
Es vereinfacht die 'Persitenzhaltung' für dictionaries. Daher auch der Hinweis mit weiteren Attributen.

@smodo
Kann es sein das du in die *.pkl Datei noch das von vorher stehen hast?

Code: Alles auswählen

filme = []
S'Batman'
p0
.
Entferne am besten die Datei. Wenn du dein Script startest und die Datei noch nicht existiert, dann musst du sie eben erstellen. Entweder gleich beim Start oder erst bei Bedarf.

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 14:50
von smodo
nene die war total leer, nur filme = [], stand drinnen.

Aber ich machs jetzt mit einer .txt wieder und ohne pickle, es gab mit zu strange fehler aus, wo ich evtl, alles nochmal schreiben muss und sorry das wäre zuviel.... von wegen KeyError "\n" ... :) Ich mache jetzt einfach die funktion so, das sie den inhalt der .txt in eine liste packt und nachher bestimmte elemente lösche und dann mit der aktuellen liste, die datei überschreiben... fertig :)

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 14:56
von Hyperion
smodo hat geschrieben: Aber ich machs jetzt mit einer .txt wieder und ohne pickle, es gab mit zu strange fehler aus, wo ich evtl, alles nochmal schreiben muss und sorry das wäre zuviel.... von wegen KeyError "\n" ... :)
Hu? Dann benutzt Du `pickle` sicherlich falsch!
smodo hat geschrieben: Ich mache jetzt einfach die funktion so, das sie den inhalt der .txt in eine liste packt und nachher bestimmte elemente lösche und dann mit der aktuellen liste, die datei überschreiben... fertig :)
Ich kann verstehen, dass man nicht `pickle` nutzen will, aber wieso willst Du ein eigene Textformat nutzen? Oder verwendest Du jetzt einen (anderen) Standard?

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 15:03
von smodo
hmm irgendiwe denke ich es zu einfach...
funktioniert nicht ganz... :) Es gibt an den Film nicht zu finden, löscht aber alles und überschreibt mir die datei :)

Code: Alles auswählen

def film_del(titel):
    datei = open("filme.txt", "a+") 
    make_in = []
    for element in datei:
        make_in.append(element)
        if titel in make_in:
            del make_in[title]
            datei.write(make_in)
            datei.close()
        else:
            print "Nicht vorhanden. "
            datei.close()
hmm nein nein pickel ist ja schon gut und recht, das sicherlich, aber ich habs nach vorgabe genutzt und es kammen immer KeyError entweder "\n" oder "A" und sonstiges.

Edit, so ist es aktuell, geht aber immer noch nicht, ich glaub ich schmeiss mein pc gleich zum fenster raus ;)

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 15:12
von Rekrul
smodo hat geschrieben:nene die war total leer, nur filme = [], stand drinnen.
Du kannst nicht einfach 'filme = []' in diese Datei schreiben.

Vielleicht solltest du mal folgendes versuchen. Beim starten deines Scriptes alle abgespeicherten Filme laden:

Code: Alles auswählen

import os
import pickle

def load_movie_data(filename):
    """
    Load a movie-list from a pickled file.
    """
    if os.path.exists(filename):
        #wenn die Datei existiert, dann Filmliste aus Datei laden
        with open(filename, 'rb') as pickle_file:
            return pickle.load(pickle_file)
    else:
        #wenn die Datei nicht existiert, dann leere Liste
        return []
Erst beim verlassen des Scriptes die Filmliste wieder abspeichern:

Code: Alles auswählen

def save_movie_data(filename, movie_list):
    """
    Pickle a movie-list.
    """
    with open(filename, 'wb') as output:
        pickle.dump(movie_list, output)
Dein Gerüst könnte dann in etwa so aussehen:

Code: Alles auswählen

filename = 'movies.pkl'
movie_data = load_movie_data(filename)
modified_movie_data = do_something(movie_data)
save_movie_data(filename, modified_movie_data)
EDIT: Öffne Dateien mit 'with'!

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 15:14
von Hyperion
Das kann nicht funzen! Schau Dir mal Deine Datei an... da steht sicherlich nicht das drin, was Du vorher drin stehen hattest.

Nebenbei öffnet man Dateien so:

Code: Alles auswählen

with open() as handler:
    # handler ist hier file-Object
Damit ist sicher gestellt, dass die Datei immer geschlossen wird.

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 15:17
von smodo
hey cool, danke, aber muss ehrlich sein, ich habe mein scheiss dingens komplet gelöscht, bin da irgendwie falsch ran, werde es nach deinem schema machen, was übersichtlicher ist und auch sehr logisch aufgebaut...

War meins zwar auch, also alle funktionen zusammen und ein Gerüst aber anscheinend hatte ich viel zu viel unnötiger text... ;)

with open() as blabla:
ist gemerkt und notiert. !

Re: Erstellen einer Filmdatenbank

Verfasst: Mittwoch 21. Dezember 2011, 15:38
von Hyperion
smodo hat geschrieben: werde es nach deinem schema machen, was übersichtlicher ist und auch sehr logisch aufgebaut...
Was meinst Du mit Schema? Ein Konzept für Dein Film-DB-Projekt oder für das Datenformat, welches Du persistent ablegen willst?

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 10:15
von smodo
so, habs neu geschrieben, bin aber noch nicht ganz fertig, in der main fehlen noch verzweigungen.

Code: Alles auswählen

import os
import pickle


def liste_laden(datei):          # die film-liste laden, sofern vorhanden.
    """ lade film liste aus der pickled datei """
    if os.path.exists(datei):
        with open(datei, "rb") as in_file:
            return pickle.load(in_file)
    else:
        return []

def liste_save(datei, output):   # die bearbeitete liste speichern
    with open(datei, "wb") as out_file:
        pickle.dump(output, out_file)

def film_hinzu(daten_liste):      # film titel hinzufügen
    film_titel = raw_input("\nTitel hinzufügen: ")
    daten_liste.append(film_titel)
    return daten_liste

def film_del(daten_liste, titel): # film löschen
    if titel in daten_liste:
        daten_liste = daten_liste.remove(titel)
        return daten_liste

def menu():
    """\nFilm (H)inzufügen
Film (L)öschen
(A)lle Filme anzeigen
Film (S)uchen
(B)eenden und speichern
\n"""

def main():
    datei = "filme.pkl"
    daten_liste = liste_laden(datei)

    print ("\nFilbi 2\n")
    print menu.__doc__
    auswahl = raw_input("\nAktion: ")

    if auswahl == ("H"):
        daten_liste_neu = film_hinzu(daten_liste)
    elif auswahl == ("L"):
        daten_liste_neu = film_del(daten_liste)
    elif auswahl == ("B"):
        liste_save(datei, liste_daten_neu)
        
if __name__ == '__main__':
    main()
Der Error ist allerdings happig:

Code: Alles auswählen

smodo@wunschbrunnen:~/Dokumente/pystuff/filbi2$ python filbi.py
Traceback (most recent call last):
  File "filbi.py", line 54, in <module>
    main()
  File "filbi.py", line 40, in main
    daten_liste = liste_laden(datei)
  File "filbi.py", line 12, in liste_laden
    return pickle.load(in_file)
  File "/usr/lib/python2.7/pickle.py", line 1378, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 880, in load_eof
    raise EOFError
EOFError
smodo@wunschbrunnen:~/Dokumente/pystuff/filbi2$ 
:)

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 12:32
von fon77
Ich schätze mal Du hast eine leere Datei filme.pkl angelegt. Dein Programm sollte die Datei selbst anlegen beim Speichern...

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 16:28
von nomnom
Warum legst du eine Funktion an, die nichts tut, und benutzt dann den Docstring, um einen String zu speichern?! Mal benutzt du `print()`, mal benutzt du `print`, der Mischmasch aus Deutsch und Englisch ist nicht schön anzusehen, entscheide dich für das eine oder das andere, `datei` ist nicht eine Datei sondern ein Dateiname, deine `ifs` vermitteln den Eindruck, dass du da Tupel vergleichen würdest, `list.remove` liefert nicht die Liste ohne das angegebene Element zurück, sondern entfernt das Element aus der Liste und wie fon77 schon angesprochen hat, ist Pickle ein binäres Dateiformat, das keine Textdateien verarbeiten kann (auch keine leeren). Und deine Funktion, mit der Listen gespeichert werden sollen, wird nur dann aufgerufen, wenn es sinnlos ist.

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 18:55
von smodo
SO ! ;)

Alles Funktioniert wunderbar :) Natürlich wird der Code umgeschriben und gepflegt, das menu z.b., schöner und auch korrekter. Die "Suche" Funktion muss ich noch schreiben und einfügen. Und natürlich schön weiter dran werkeln, bissl brauchbarer machen.
Die Beenden und speichern option, muss als erstes dann noch getrennt werden, kann ja nicht sein, das ich immer erst beim beenden speichern kann... Dazu, das ich nach einem Film reinschreiben, Ihn nicht gleich löschen könnte, da ich zuerst das programm beenden müsste... :)

Code: Alles auswählen

import os
import pickle
import sys


def liste_laden(datei_name):          # die film-liste laden, sofern vorhanden.
    """ lade film liste aus der pickled datei """
    if os.path.exists(datei_name):
        with open(datei_name, "rb") as in_file:
            return pickle.load(in_file)
    else:
        return []

def liste_save(datei_name, output):   # die bearbeitete liste speichern
    with open(datei_name, "wb") as out_file:
        pickle.dump(output, out_file)

def film_hinzu(film_liste):      # film titel hinzufügen
    film_titel = raw_input("\nTitel hinzufügen: ")
    film_liste.append(film_titel)
    return film_liste

def film_weg(film_liste): # film löschen
    titel = raw_input("\nWelchen Film löschen: ")
    if titel in film_liste:
        film_liste = film_liste.remove(titel)
        return film_liste

def alle_filme_anzeigen(datei_name):
    with open(datei_name, "rb") as film_liste_ausgeben:
        print pickle.load(film_liste_ausgeben)

def main():
    datei_name = "filme.pkl"
    film_liste = liste_laden(datei_name)

    while True:
        print "\nFilbi 2\n"
        print "\nFilm (H)inzufügen"
        print "Film (L)öschen"
        print "(A)lle Filme anzeigen"
        print "Film (S)uchen"
        print "(B)eenden und speichern\n"

        auswahl = raw_input("\nAktion: ")

        if auswahl == "H":
            daten_liste_neu = film_hinzu(film_liste)
        elif auswahl == "L":
            daten_liste_neu = film_weg(film_liste)
        elif auswahl == "A":
            alle_filme_anzeigen(datei_name)
        elif auswahl == "B":
            liste_save(datei_name, film_liste)
            sys.exit()
        else:
            print "(H, L, A, B) ONLY ! "
            
        
if __name__ == '__main__':
    main()
und noch eine kleine frage: wen ich nach bestimmten aktionen, wieder ein "clear-terminal-fenster" haben will, aber "os.system("clear") und subprocess.call(["clear"]) nicht verwenden sollte. Wobei ich nur bei ersterem weis wieso. Wie kann ich das problem den auf eine andere weise lösen ?

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 19:33
von derdon
Benutze das curses-Modul.

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 19:48
von smodo
danke für den tip.

und einen schönen abend noch an alle und falls man sich nicht mehr liest, frohe festtage.. :)

Re: Erstellen einer Filmdatenbank

Verfasst: Donnerstag 22. Dezember 2011, 20:12
von Hyperion
Oder `urwid` ;-)

Zum Menü solltest Du Dir mal Dictionaries / Listen angucken und dann die Textmeldung, den/das Steuerbuchstaben/-wort und die Funktion in einem solchen Typen zusammenfassen. Damit kannst Du dann sowohl die Ausgabe, die Abfrage und die richtige Verzweigung (Dispatching) generisch implementieren. Vorteil davon ist das Einsparen langer `if-elif`-Kaskaden und die leichte Erweiterbarkeit, ohne an verschiedenen Code-Stellen etwas ändern zu müssen.

Re: Erstellen einer Filmdatenbank

Verfasst: Freitag 23. Dezember 2011, 15:08
von smodo
danke @hyperion :)

Und ja in urwid hab i mich schon eingelesen, basiert ja auf curses, aber einfacher zu handhaben :) urwid gefällt mir wahnsinnig gut, finde ich echt genial und wie gesagt auch "fast"sehr einfach.