cPickle Importproblem

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.
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Bin grad dabei, einen Terminplaner zu schreiben...
ich will das erstmal mit ganz primitiven Mitteln zur Kommunikation testen, indem ich die Termine mit cPickle einfriere, damit man sie veröffentlichen kann... aber wenn ich die Datei mit cPickle wieder laden will, dann meckert Python...

import cPickle as pickle

Code: Alles auswählen

class Termin:

    def __init__(self,name=None,datum=None,ort=None,beschreibung=None):
        self.Name=name
        self.Datum=datum
        self.Ort=ort
        self.Beschreibung=beschreibung
        print "Termin gespeichert!"
        print " Name: "+self.Name
        print "Datum: "+self.Datum
        print "  Ort: "+self.Ort
        print "Beschreibung: \n"+self.Beschreibung

    def bearbeiten(self,name=None,datum=None,ort=None,beschreibung=None):
        if name:
            self.Name=name
        if datum:
            self.Datum=datum
        if ort:
            self.Ort=ort
        if beschreibung:
            self.Beschreibung=beschreibung

class Terminplaner:

    def __init__(self):
        self.terminliste=[]

    def hinzufuegen(self,name,datum,ort,beschreibung):
        exec "self."+name+"=Termin(name='"+name+"',datum='"+datum+"',ort='"\
             +ort+"',beschreibung='"+beschreibung+"')"
        exec "self.terminliste.append(self."+name+")"

    def zeigen(self):
        for termin in self.terminliste:
            print " Name: "+termin.Name
            print "Datum: "+termin.Datum
            print "  Ort: "+termin.Ort
            print "Beschreibung:"
            print termin.Beschreibung
            print

def starten():
    termindatei="termine_nephilim.data"        
    datei=file(termindatei,"w")
    planer=Terminplaner()
    print "           Terminplaner V. 1.0"
    while True:
        print
        print "Hallo! Dies ist die erste Version des Terminplaners\
der Gilde Nephilim!"
        print "Wähle eine Option aus"
        print "(gib bitte NUR die Zahl ein, die vor der Option steht!!!)"
        print
        print "1 Termine ansehen"
        print "2 Termine importieren"
        print "3 Termin hinzufügen"
        print "4 Termine ändern"
        print "5 Termine speichern"
        print "6 Beenden"
        auswahl=raw_input()
        terminplaner=Terminplaner()
        if auswahl=="1":
            print "Es wurde die Funktion 'Termine ansehen' gewählt"
            planer.zeigen()
        elif auswahl=="2":
            print "Es wurde die Funktion 'Termine importieren' gewählt"
            planer=pickle.load(datei)
        elif auswahl=="3":
            print "Es wurde die Funktion 'Termin hinzufügen' gewählt"
            print "Gib bitte folgende Daten zum Termin ein:"
            name=raw_input("Name des Termins: ")
            datum=raw_input("Datum des Termins: ")
            ort=raw_input("Wo findet der Termin statt? ")
            beschreibung=raw_input("Eine kurze Beschreibung, mehrere Zeilen\
            \nsind möglich. Bitte keine Absätze (Enter-Taste) machen,\
            \nda sonst die Beschreibung gespeichert wird!")
            planer.hinzufuegen(name=name,datum=datum,ort=ort,\
                               beschreibung=beschreibung)
        elif auswahl=="4":
            print "Es wurde die Funktion 'Termine ändern' gewählt"
            print "Gib bitte den Terminnamen ein!"
            terminname=raw_input("Name des Termins: ")
            print "Gib bitte folgende Daten zum Termin ein, die du ändern\
            \nwillst (sonst drücke einfach Enter):"
            name=raw_input("Name des Termins: ")
            datum=raw_input("Datum des Termins: ")
            ort=raw_input("Wo findet der Termin statt? ")
            beschreibung=raw_input("Eine kurze Beschreibung, mehrere Zeilen\
            \nsind möglich. Bitte keine Absätze (Enter-Taste) machen,\
            \nda sonst die Beschreibung gespeichert wird!")
            if name!="":
                exec "planer."+terminname+".bearbeiten(name="+name+")"
            if datum!="":
                exec "planer."+terminname+".bearbeiten(datum="+datum+")"
            if ort!="":
                exec "planer."+terminname+".bearbeiten(ort="+ort+")"
            if beschreibung!="":
                exec "planer."+terminname+".bearbeiten(\
                beschreibung="+beschreibung+")"
            print "Änderung durchgeführt!"
        elif auswahl=="5":
            print "Es wurde die Funktion 'Termine speichern' gewählt"
            pickle.dump(planer,datei)
            print "Gespeichert!"
        elif auswahl=="6":
            print "Programmende. Du kannst das Fenster nun schließen!"
            break
starten()
hoffe, es ist übersichtlich... ich fand alles selbsterklärend, hab noch keine Kommentare reingemacht... falls die nötig sind, mach ich sie noch rein

Kann mir da jemand helfen?
Zuletzt geändert von Vingdoloras am Freitag 7. Dezember 2007, 19:38, insgesamt 1-mal geändert.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

1. Schreib'ne verständlichere Überschrift ._. Etwas zum Thema oder so,...
2. Lager den Code aus nach http://paste.pocoo.org ... Dann fällt das Antworten leichter.
3. Sag' uns die gesamte Fehlermeldung, falls es keinen Traceback gib, sag uns das Verhalten, was das Programm den Tag legt.
4. PEP8vielleicht nochmal ansehen, beim groben drüberschauen sind mir alleine schon die Operatoren negativ aufgefallen...
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\Ronny\Eigene Dateien\Ronny\Schule\Informatik\Programme\Eigene\Gilde\terminplaner1.py", line 114, in ?
    start()
  File "C:\Dokumente und Einstellungen\Ronny\Eigene Dateien\Ronny\Schule\Informatik\Programme\Eigene\Gilde\terminplaner1.py", line 72, in start
    planer=pickle.load(datei)
EOFError
sagt er mir, wenn ich speichere und dann ohne zu beenden importieren will
Zuletzt geändert von Vingdoloras am Freitag 7. Dezember 2007, 19:44, insgesamt 1-mal geändert.
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Wenn ich das Programm beende und neu starte und dann importieren will, sagt er mir

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\Ronny\Eigene Dateien\Ronny\Schule\Informatik\Programme\Eigene\Gilde\terminplaner1.py", line 114, in ?
    start()
  File "C:\Dokumente und Einstellungen\Ronny\Eigene Dateien\Ronny\Schule\Informatik\Programme\Eigene\Gilde\terminplaner1.py", line 72, in start
    planer=pickle.load(datei)
IOError: (0, 'Error')
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

So Überschrift geändert, Tracebacks reingeschrieben und jetz der
PASTE!
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Hmpf, noch ein paar Kleinigkeiten ._.

1. Der Editbutton ist keine Schlimme Sache, die Leute schauen auch ohne bumping in den Thread! Beachte ihn.
2. Jetzt, wo der Code im Paster ausgelagert ist, könntest du ja den Code oben ersetzen. Die Codetags mit Pythonhighlighting belasten scheinbar irgendwie den Server oder irgendwas.
3. Du könntest im Paster auch das Pythonhighlighting verwenden.
4. Deine Struktur ist ein wenig merkwürdig und verworren für mich, ein wenig wie Spaghetticode in den ersten 10 Minuten. Und schwer zu lesen, ein bissel arg wenig Leerzeichen zwischen den Operatoren und keine Leerzeilen zwischen klar getrennten Vorgängen. Deswegen weise ich nochmal ganz dolle auf PEP8 hin und bitte dich darum, ein wenig die Struktur zu überarbeiten, oft fallen einen dort dann Sachen auf, die man sonst nicht gesehen hätte.
5. Du solltest dir angewöhnen, im Fragepost folgende Sachen unterzubringen:
- Was willst du erreichen?
- Wie weit bist du oder denkst du zu sein?
- WAS genau tust du, bevor der Fehler auftritt?
- Was ist der Fehler genau? Am besten mit einigen Zeilen, die du vorher eingetippt hast.
- Lauffähige Version, die den Fehler reproduziert.
- Vielleicht eine kleine Laiendiagnose, wenn dir was einfällt.


Ich hoffe, du kommst dir nicht degradiert oder sowas vor. Ich will's nur dir und uns leichter machen, dir zu helfen!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ein Programm mit `exec`? Sieht aus wie ein Kandidat um nochmal gründlich über die Struktur nachzudenken.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@Vingdoloras: Dateien öffnet man besser nicht "auf Vorrat" sondern nur dann wenn man sie braucht. Und gleich danach das schliessen nicht vergessen.

Du öffnest eine Datei zum *schreiben* und bekommst dann entsprechend einen Fehler wenn Du daraus *lesen* willst.

Und die ``exec``\s sind wirklich gruselig.
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

@ BlackVivi: ich fühl mich nich degradiert :D
Bin noch Anfänger und sehr verständnisvoll was meine Unlesbarkeit angeht... und bin sowieso (fast immer) offen für Kritik :wink:

@ BlackJack: Danke, ich werd das mal ändern, womöglich liegt da der fehler...

und @ BlackJack und Leonidas: Was habt ihr gegen exec? Das tut doch keinem was :twisted:
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Es funktioniert! Danke, ich werde versuchen, eine möglichst hilfreiche kurze Beschreibung zu schreiben...

Also, das Problem war, dass das Programm keine Dateien importieren wollte. Abgesehen von dem klaren Fall, dass die Datei fehlt, gab es zwei Fälle... einmal ein EndOfFileError, wenn ich erst exportiere (siehe Programm) und dann danach gleich importiere,
und einmal ein IOError, wenn ich exportiere, dann das Programm neustarte, damit die exportierten Dateien nurnoch in der Speicherdatei sind und nichmehr im Arpeitsspeicher, und dann gleich importiere.

Beide Male lag es daran, dass ich die Datei, aus der ich laden wollte, "auf Vorrat", wie lackJack es nannte, geöffnet hatte... und dazu noch im "write"-Modus.

Als Lösung habe ich, getreu BlackJacks Tipp, die Datei jedes Mal erst geöffnet, wenn sie benötigt wurde, und danach sofort wieder geschlossen.

Ich Paste gleich den richtigen Code...

Ach und BlackVivi: wie mach ich das Pythonhighlighting im Paster?
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Links neben "Paste!" statt Text --> Python auswählen. Vergiss den Edit Button nicht :3 und PEP8! Lieber 2mal den Code durchlesen und posten!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Vingdoloras hat geschrieben:und @ BlackJack und Leonidas: Was habt ihr gegen exec? Das tut doch keinem was :twisted:
Es macht das Programm unübersichtlich, und kann leicht zu Sicherheitslücken führen. Wenn du Variablennamen zusammensetzt dann hast du was falsch gemacht - Listen und Dictionaries existieren.
Vingdoloras hat geschrieben:Ach und BlackVivi: wie mach ich das Pythonhighlighting im Paster?
Steht in den FAQ.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Mit Dictionaries kann ich noch nich umgehen... das hatte ich noch nicht im Unterricht und die Bücher, aus denen ich mein Wissen hab, verwirren mich bei dem Thema nur... außerdem find ich es irgendwie faszinierend, aus nem String nen Befehl zu formen (nimm mir das bitte nich übel :wink: )

Ich werd den Code mal bei Gelegenheit den PEP8 anpassen...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Vingdoloras hat geschrieben:Mit Dictionaries kann ich noch nich umgehen... das hatte ich noch nicht im Unterricht und die Bücher, aus denen ich mein Wissen hab, verwirren mich bei dem Thema nur... außerdem find ich es irgendwie faszinierend, aus nem String nen Befehl zu formen (nimm mir das bitte nich übel :wink: )

Code: Alles auswählen

d = {'eins': 1, 'zwei': 2}
print d['eins']
Also schwer war das jetzt nicht.

Wenn du so seltsame Dinge machst dann musst du dich darauf einstellen, dass dir dann keiner hilft etwaige Fehler in deinen Programmen zu finden - das ist einfach mühselig.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Sry, werds mir merken...
Ich finde exec halt irgendwie faszinierend... deswegen nutze ich es wohl...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Wenn du dynamische Codegenerierung magst, dann könnte dir Lisp mit seinen Makros gefallen :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Wobei die Makros in Lisp und Scheme etwas besser und sicherer sind als ``exec`` in Python. Programmstrukturen als Datenstrukturen zu manipulieren ist viel sicherer und weniger Fehleranfällig als beliebige Zeichenketten als Code zu interpretieren.
Vingdoloras
User
Beiträge: 53
Registriert: Sonntag 2. Dezember 2007, 18:25

Hört sich interessant an... aber ich habe leider noch nie von Lisp und Scheme gehört :cry:
Vielleicht könnt ihr mich ja aufklären? :D :D :D
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Vingdoloras hat geschrieben:Hört sich interessant an... aber ich habe leider noch nie von Lisp und Scheme gehört
http://de.wikipedia.org/wiki/Lisp

Lisp und Scheme sind sogenannte Funktionale Programmiersprachen.
Der Grundsätzliche unterschied zu (hauptsächlich) imperativen Programmiersprachen wie Python ist, dass du nicht schreibst "tu dies, tu dass", sondern, dass du nur Funktionen schreibst, die beschreiben, was für ein resultat sie haben.
Dadurch hast du kaum feste Syntaktische konstrukte wie if oder for, da diese durch eigene Funktionen dargestellt werden, und du solche Funktionen auch
selber schreiben kannst.
Lisp wird häufig als "programmable programming language" gerühmt.
Das Ganze erfordert allerdings erstmal einiges Umdenken, von dem einiges deutliche Nachwirkungen in deinem Stil hinterlassen wird ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Naja, tu-das und tu-jenes geht mit Lisp auch, denn sie sind ja "impure". D.h. du kannst sowohl funktional als auch imperativ an dein Problem rangehen. Der Unterschied ist darin, wie du auf Seiteneffekt reagierst - entweder ist eine Funktion eine Black-Box und gibt bei jedem Aufruf das gleiche zurück (Funktional) oder sie modifiziert den Zustand (imperativ), was als Seiteneffekt bezeichnet wird.

Außerdem ist LISP made with alien technology. Aber es ist hart sich da reinzudenken, ehrlich.

Wenn du magst kannst du dir die Lehrbücher SICP und HTDP ansehen oder auch Practical Common Lisp.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten