Seite 1 von 2

Dictionaries speichern

Verfasst: Mittwoch 19. Dezember 2007, 15:36
von Brafil
Hallo allerseits
Ich bin neu hier und habe eine frage zu meinem ersten script:

Code: Alles auswählen

def viewlist():
    print mylist

def Addtolist():
    print "Which name would you like to add?"
    name = raw_input("> ")
    print "What do you want to assign to", name + "?"
    value = raw_input("> ")
    print "OK.", name, "with the value", value, "has been added."
    mylist[name] = value

def Delfromlist():
    print "Which name do you want to delete?"
    delname = raw_input("> ")
    del mylist[delname]
    print "OK.", delname, "has been removed from the list."

def loadfile():
    print "Please enter the name of the file"
    namefile = raw_input("> ")
    namefile = namefile + ".txt"
    fopen = open(namefile)
    readdata = fopen.read()
    fopen.close()
    print readdata
    print
    print "Do you want to save the read data?"
    print "1. Yes"
    print "2. No"
    print
    commandread = raw_input("> ")
    if commandread == "1":
        print "What's the name of the data?"
        datadefname = raw_input("> ")
        datadefname = readdata

def savefile():
    print "Please enter a name for your list."
    listdefname = raw_input("> ")
    listdefname = listdefname + ".txt"
    print "WARNING!!! The file, if already exists, will be overwritten COMPLETELY!"
    print
    print "1. Overwrite"
    print "2. Append"
    print "Write 'exit' to exit writing"
    commandnow = raw_input("> ")
#########################PROBLEM IS HERE#########################
    if commandnow == "1":
        f = file(listdefname, "w")
        f.write(mylist)
        f.close()
    elif commandnow == "2":
        f.append(mylist)
        f. close()
#################################################################
    elif commandnow != "exit" and commandnow != "1" and commandnow != "2":
        print "Sorry, unkown command!"
        f.close

print
print "List@Generator v0.1 Copyright by Kaan D. Ocal"
print
print "---------------------------------------------"

command = 0
mylist = {}

while command != "quit":
    
    print
    print "Please choose an action"
    print
    print " 1. Look at your list"
    print " 2. Add a name to your list"
    print " 3. Remove a name from your list"
    print " 4. Load a list"
    print " 5. Save your list"
    print
    print "Write 'quit' to quit"
    print
    
    command = raw_input("> ")
    
    if command != "1" and command != "2" and command != "3" \
    and command != "4" and command != "5" and command != "quit":
        print
        print "Sorry, invalid command"
    
    elif command == "1":
        viewlist()
        
    elif command == "2":
        Addtolist()
        
    elif command == "3":
        Delfromlist()
        
    elif command == "4":
        loadfile()
        
    elif command == "5":
        savefile()
       
Ich würde gerne wissen wie ich diese Dictionaries speichern könnte und wie der Benutzer selbst aussuchen kann, welches Dictionary er ansehen kann. z.b.

Code: Alles auswählen

...
    print "Which Dictionary do you want to look at?"
    chosendict = raw_input("> ")
    print chosendict
...
Das würde ja nur die eingabe anzeigen... Nicht das Dict.
Ich würde mich freuen, wenn jemand mir helfen könnte.

Verfasst: Mittwoch 19. Dezember 2007, 15:50
von The Spirit
zum speichern würde ich mir an deiner stelle mal pickle ansehen.

und auswählen, welches dictionary er ansehen möchte, würde ich eine kleine funktion machen. entweder ganz einfach mit glob, oder etwas schöner, vor allem wenn es mehrere ordner mit einbeziehen soll, das walk bzw. os.walk modul

Danke

Verfasst: Mittwoch 19. Dezember 2007, 16:25
von Brafil
Danke, das pickle war super! Es geht jetzt! :lol:
Nur den zweiten Teil habe ich nicht verstanden. :(

PS: Ein GUI Tut wäre auch net schlecht!!! Danke im voraus! :lol:

Verfasst: Mittwoch 19. Dezember 2007, 16:34
von Leonidas
Hallo Brafil, willkommen im Forum,

Du musst einfach mit ``rawdata = file(chosendict, 'r'); print pickle.load(rawdata)`` die Datei öffnen.

Verfasst: Mittwoch 19. Dezember 2007, 16:45
von Brafil
Ja, da war ich wohl zu ungenau... 8)
Das "pickln" habe ich ganz verstanden, aber nicht wie man die namen der listen manuell verändern kann... z.b.

Code: Alles auswählen

...
print "Which Dictionary do you want to look at?"
chosendict = raw_input("> ")
undsoweiter
Endeffekt: Python zeigt das Dict mit dem namen chosendict an
...
oder

Code: Alles auswählen

...
print "What will be the name of the list?"
nameofthelist = raw_input("> ")
undsoweiter
Endeffekt: mylist wurde in nameofthelist umgewandelt
Wie kann man in beiden fällen den Endeffekt erzielen?

Verfasst: Mittwoch 19. Dezember 2007, 16:47
von birkenfeld
Leonidas hat geschrieben:Hallo Brafil, willkommen im Forum,

Du musst einfach mit ``rawdata = file(chosendict, 'r'); print pickle.load(rawdata)`` die Datei öffnen.
Für pickle sollte man sich übrigens gleich die Modi "rb" bzw. "wb" angewöhnen.

Verfasst: Mittwoch 19. Dezember 2007, 17:41
von Leonidas
birkenfeld hat geschrieben:Für pickle sollte man sich übrigens gleich die Modi "rb" bzw. "wb" angewöhnen.
Ups, ja, habe ich gerade übersehen.

Brafil, nachdem du das dict entpickelt hast, reicht doch einfach ein print.

Verfasst: Mittwoch 19. Dezember 2007, 18:28
von Brafil
Brafil hat geschrieben: Das "pickle" habe ich ganz verstanden, aber nicht wie man die namen der listen manuell verändern kann... z.b.

Code: Alles auswählen

...
print "Which Dictionary do you want to look at?"
chosendict = raw_input("> ")
undsoweiter
Endeffekt: Python zeigt das Dict mit dem namen chosendict an
...
oder

Code: Alles auswählen

...
print "What will be the name of the list?"
nameofthelist = raw_input("> ")
undsoweiter
Endeffekt: mylist wurde in nameofthelist umgewandelt
Wie kann man in beiden fällen den Endeffekt erzielen?

GUI added!

Verfasst: Donnerstag 20. Dezember 2007, 14:21
von Brafil
I added a simple GUI.
Im gonna add a menu and fix this "Look at the list" issue. Currently it's showing the list in a Pop-Up window.

Here some screenshots:

http://img2.freeimagehosting.net/image. ... d07264.jpg
http://img2.freeimagehosting.net/image. ... e21bda.jpg
http://img2.freeimagehosting.net/image. ... 2656ee.jpg

Verfasst: Donnerstag 20. Dezember 2007, 14:52
von Brafil
Ich hab das Menü gemacht. Ich frage mich wie ich daraus etwas wie ein Runtime machen kann

PS: Sorry for speaking english in my last post, it was out forsee (aus versehen) :wink:

Verfasst: Freitag 21. Dezember 2007, 05:24
von nkoehring
Hallo,

also ich bin mir absolut nicht sicher, ob ich verstanden habe, was du eigentlich moechtest, aber wenn du mehrere Dictionarys in einer Datei und auf ein bestimmtes (eben das der Nutzer eingab) zugreifen willst, dann packe sie doch einfach wieder in ein Dictionary...

Code: Alles auswählen

listen = dict()
listen["namen"] = dict(("ralfi", "cool"), ("horsti", "nicht so cool"))
listen["autos"] = dict(("mercedes", "teuer"), ("audi", "teuer, aber schoen"), ("trabant", "kult"))
# [...]
whichone = raw_input("Welche Liste willst du? ")
if listen.has_key(whichone):
    print listen[whichone]
else:
    print "hab ich nich..."

Verfasst: Freitag 21. Dezember 2007, 10:27
von Brafil
Gute lösung, aber bei Addtolist geht das nicht:

Code: Alles auswählen

def addtolist():
    listname = inputname.get()
    listvalue = inputvalue.get()
    whichlist = askstring("Choose List", "To which list do you want to add this name?")
    mylists[whichlist[listname] = listvalue]
...
PS: Ich glaube, das manuelle auswählen der liste ist nicht mehr notwendig, da ich ein GUI und speichermöglichkeit hinzugefügt habe:
Hier das Programm, alle Vorschläge verbessern es:

Click Here

Verfasst: Freitag 21. Dezember 2007, 11:11
von gerold
Hallo Brafil!

Vielleicht bringt es dir etwas, wenn du mehr über die Möglichkeiten erfährst, mit denen man etwas unter Python speichern kann.

http://www.python-forum.de/topic-6157.html

mfg
Gerold
:-)

Verfasst: Freitag 21. Dezember 2007, 12:03
von BlackJack
@Brafil: Sternchenimporte sollte man vermeiden, weil man sich damit viele Namen in den Namensraum holt, die miteinander kollidieren können und man weiss bei vielen solchen Importen im Quelltext dann nicht mehr woher eigentlich welcher Name kommt.

Die meisten Leute schreiben die ``import``-Anweisungen am Anfang des Moduls. Manchmal macht es Sinn sehr "teure" und selten benutze Importe in Funktionen zu schreiben, aber dort etwas zu importieren was am Anfang im Modul sowieso schon importiert wurde, macht keinen Sinn. Insbesondere steigt hier bei einem Sternchenimport auch noch die Gefahr, dass dabei ein Name von der Modulebene durch etwas Importiertes verdeckt wird.

``global`` auf Modulebene hat keinen Effekt und in Funktionen sollte man es nicht benutzen. Globale Namen für Daten machen Programme schwerer verständlich und fehleranfälliger.

Ein Dictionary `mylist` zu nennen ist irreführend. Gilt auch für die anderen Namen die ein `list` in sich tragen, aber mit einem Dictionary arbeiten.

Pickle-Dateien sollte man immer im Binärmodus öffnen, da es sich um Binärdateien handelt. Auch bei dem "Text"-Format. Das ist im Grunde ein Binärformat, bei dem die Bytewerte im ASCII-Bereich bleiben. Wenn man das nicht tut, sind die Daten unter Umständen nicht unter verschiedenen Plattformen austauschbar. Die Dateinamenserweiterung '*.txt' ist deshalb auch etwas ungünstig.

``except`` sollte man nie ohne konkrete Ausnahme verwenden. So werden einfach *alle* Ausnahmen behandelt. Wenn man sich bei einem Namen vertippt, wird zum Beispiel auch der daraus folgende `NameError` einfach in eine nichts sagende Fehlermeldung umgewandelt. Solche Fehler können dann sehr schwer zu finden sein. Ein schönes Beispiel ist `savefile()` wo man in *jedem Fall* ein Fenster mit dem Text "Couldn't save file" bekommt, weil `asksavefilename` einen `NameError` auslöst.

Die Elemente selber auf einem `Canvas` zu platzieren ist ungewöhnlich bis schlecht. Das Layout sollte man einem Layout-Manager überlassen, statt selber Koordinaten fest zu legen, die bei einer anderen Bildschirmauflösung und/oder anderer Schriftgrösse nicht mehr Stimmen. Bei mir ragen die `Entry`\s zum Beispiel ein klein wenig in die `Button`\s hinein.

`Button`\s einfach nur als Textanzeige zu missbrauchen ist auch nicht schön. Da hätte es auch ein `Label` getan.

Die "Tab"-Reihenfolge beim Eintragen ist subobtimal. Vom Schlüssel zum Wert kommt man per Tab-Taste, aber danach geht's dann nicht gleich zum "OK"-Button weiter.

Verfasst: Freitag 21. Dezember 2007, 12:26
von Brafil
Danke für die Hilfe.
(Manchmal muss ich widersprechen)

1. Die sternchenimporte hab ich absichtlich gemacht, und dafür gesorgt dass nix kollidiert. (Außer Pickle)

2. Die module brauche ich oft für mehrere codes des Programms

3. Global ist auch extra, weil ein einziges dict verwendet wird. sonst fügt man einen namen hinzu, dann ist die liste immer noch leer.

4. mylist habe ich ganz am anfang geschrieben, deshalb sollte es so bleiben, hab keine lust den quellcode nach mylist zu durchsuchen, (auch mit Find nicht), in der neuen version an der ich arbeite ist es zu schwer. Außerdem finde ich das in dem fall passender. Aber wenns so dringend ist...

5. Wie speichert man im Binärmodus?

6. Warum gibt es da immer eine fehlermeldung? Hab ich grade jetzt bemerkt. Deshalb habe ich da try...except weggelassen, aber jetzt printet es die fehlermeldung...

7. Ja, ich weiß. Was für ein Layout manager wäre da am besten?

8. Ja, weiß ich auch, aber solange ich das textfenster wo das programm mylist (bzw. mydict) ausgibt, geht es nur so.

9. Werde ich auch machen. nervt mich auch.

PS: mylist ist jetzt mydict

Verfasst: Freitag 21. Dezember 2007, 12:52
von gerold
Hallo Brafil!
Brafil hat geschrieben:1. Die sternchenimporte hab ich absichtlich gemacht, und dafür gesorgt dass nix kollidiert.
Es gibt Leute, die einen Quellcode mit Sternchenimporten nicht lesen. Einfach deshalb, weil es ein ständiges Hin- und Hergehüpfe ist. Nur um herauszufinden, woher den dieser oder jener Befehl kommt. Ich gehöre auch dazu.
Brafil hat geschrieben:3. Global ist auch extra, weil ein einziges dict verwendet wird.
Wenn man "global" vermeiden kann, dann sollte man es vermeiden. Das funktioniert meist mit einer Umstellung des Programmes. Das möchte ich dir aber nicht unterschlagen: Es gibt auch Fälle (sehr sehr wenige), in denen ein "global" im Code den Code nicht verkompliziert.

Ich habe mir deinen Code nicht angesehen. Deshalb kann ich dir jetzt keine Alternative vorschlagen. Aber meist genügt es, wenn man an Funktionen alles übergibt, was diese zum Arbeiten brauchen. Alles, wirklich alles! Und beim "return" liefert man alles wieder zurück, was außerhalb dieser Funktion gebraucht wird. Eine Funktion sollte (wenn möglich) niemals ein externes Objekt ändern, sondern immer nur die geänderten Objekte mit "return" zurück liefern. Das ist eine Sache der Programmplanung. Aber wie ich schon schrieb: "Ich habe mir deinen Code nicht angesehen." Deshalb kann ich jetzt keinen detaillierteren Vorschlag machen.
Brafil hat geschrieben:4. mylist habe ich ganz am anfang geschrieben, deshalb sollte es so bleiben
Ein Name sollte dem Programmierer wissen lassen, mit was man es zu tun hat. "mylist" für ein Dictionary ist keine gute Idee und sollte geändert werden. Auch wenn man Stunden dafür braucht. Viel besser als "mylist" oder "mydict" wäre ein Name der aussagt, was mit dem Namen verknüpft ist. Als Beispiel: Wenn es Adressen sind, dann wäre z.B. "addresses" angebracht. Ob Dictionary oder Liste ist dann auch egal. Eine gute IDE wie z.B. WingIDE zeigt dir sowiso an, ob es eine Liste oder ein Dictionary ist. Und auch die Attribute...
Brafil hat geschrieben:5. Wie speichert man im Binärmodus?
``my_file = file("filename.dat", "wb")``
Brafil hat geschrieben:PS: mylist ist jetzt mydict
Besser als "mydict" aber noch nicht optimal. Aber das kommt mit der Zeit. ;-)

mfg
Gerold
:-)

Verfasst: Freitag 21. Dezember 2007, 12:57
von Leonidas
Brafil hat geschrieben:1. Die sternchenimporte hab ich absichtlich gemacht, und dafür gesorgt dass nix kollidiert. (Außer Pickle)
Warum beharrst du darauf es falsch zu machen? -> [wiki]Import[/wiki]
Brafil hat geschrieben:5. Wie speichert man im Binärmodus?
Mit ``wb`` als Modus.

Verfasst: Freitag 21. Dezember 2007, 13:02
von Brafil
gerold hat geschrieben:Hallo Brafil!...
import kann ich verändern. :evil: außer Tkinter
return hatte ich nie richtig kapiert, dsehalb wusste ich nicht, dass es noch mehr müglichkeiten gibt.
es speichert jetzt auch im .dat format, allerdings muss der benutzer filename.dat eingeben, also es ist nicht automatisch, aber es funktioniert.

Verfasst: Freitag 21. Dezember 2007, 13:13
von Brafil
Import is jetzt geregelt, außer Tkinter, das ist immer noch mit *

Verfasst: Freitag 21. Dezember 2007, 13:31
von gerold
Brafil hat geschrieben:allerdings muss der benutzer filename.dat eingeben
Hallo Brafil!

Auch dafür gibt es eine einfache Lösung:

Code: Alles auswählen

filename = raw_input("Bitte geben Sie den Dateinamen ein: ")
if not filename.lower().endswith(".dat"):
    filename = filename + ".dat"
mfg
Gerold
:-)