Erstellen einer Filmdatenbank

Code-Stücke können hier veröffentlicht werden.
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Mittwoch 21. Dezember 2011, 13:57

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.
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
BlackJack

Mittwoch 21. Dezember 2011, 14:01

@smodo: Dann steht in der Datei etwas mit dem `pickle` nicht klar kommt.
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Mittwoch 21. Dezember 2011, 14:06

jo und das ist irgendwo ein "\n" so wie es aussieht. :)
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Mittwoch 21. Dezember 2011, 14:33

@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.
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Mittwoch 21. Dezember 2011, 14:50

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 :)
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mittwoch 21. Dezember 2011, 14:56

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?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Mittwoch 21. Dezember 2011, 15:03

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 ;)
Zuletzt geändert von smodo am Mittwoch 21. Dezember 2011, 15:12, insgesamt 1-mal geändert.
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Mittwoch 21. Dezember 2011, 15:12

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'!
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mittwoch 21. Dezember 2011, 15:14

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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Mittwoch 21. Dezember 2011, 15:17

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. !
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mittwoch 21. Dezember 2011, 15:38

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?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Donnerstag 22. Dezember 2011, 10:15

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$ 
:)
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
fon77
User
Beiträge: 17
Registriert: Freitag 10. April 2009, 20:58

Donnerstag 22. Dezember 2011, 12:32

Ich schätze mal Du hast eine leere Datei filme.pkl angelegt. Dein Programm sollte die Datei selbst anlegen beim Speichern...
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Donnerstag 22. Dezember 2011, 16:28

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.
smodo
User
Beiträge: 49
Registriert: Dienstag 18. August 2009, 23:45

Donnerstag 22. Dezember 2011, 18:55

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 ?
Der Zynismus ist meine Rüstung, der Sarkasmus mein Schwert und die Ironie mein Schild.
Antworten