Seite 1 von 1
dictionary als datenbank
Verfasst: Dienstag 14. Dezember 2004, 20:01
von Gast
Hallo beisammen,
ich bin immernoch dabei zu lernzwecken ein kleines quiz zu basteln.
das funktioniert mittlerweile auch recht gut, aber nun würde ich noch gerne ein extra script scheiben, mit dem neue fragen zu dem quiz hinzugefügt werden können.
Ich hab mir das in etwa so vorgestellt:
Es gibt ein Textfenster, in dem die Frage mit 4 möglichen Antworten eingegeben werden kann.
In eine Eingabezeile wird die korrekte anwort (zahl 1-4) eigetragen.
Bei druck auf den OK button sollen diese angaben in eine externe datei gespeichert werden, aus der das eigentliche quiz nachher die fragen liest.
Jetzt frage ich mich wie diese datei am günstigsten zu gestalten ist, damit immer neue fragen hinzugefügt werden können. Ich dachte da an die dictionary funktion, weiss aber nicht wie sich das schlau bewerkstelligen lässt.
Bisherige Idee:
f001 = "Frage aus Textfeld"
answ = {f001:"2"} #wobei 2 aus der eingabezeile entnommen wird
Das problem das sich mir auftut ist:
1.: daß neue einträge immer ans ende der datei geschrieben werden, d.h. ich hab keine Ahnung wie ich das dictionary integrieren soll
2.: die Variablen für die fragen sollen möglichst fortlaufend sein, d.h. bevor eine neue frage geschrieben wird, muss erst die datei ausgelesen werden, um zu sehen welche variablen als nächstes dran sind
3.: wie schreibe ich denn " (Gänsefüßchen) in eine Datei??? (Wenn ich das weiß fällt mir der rest u.U. leichter....
Danke schonmal,
Thomas
Re: dictionary als datenbank
Verfasst: Dienstag 14. Dezember 2004, 20:09
von jens
Anonymous hat geschrieben:3.: wie schreibe ich denn " (Gänsefüßchen) in eine Datei??? (Wenn ich das weiß fällt mir der rest u.U. leichter....
führe das mal aus:
Code: Alles auswählen
print "das 'Gänsefüßchen' ist in Anführungsstrichen?!?"
print 'das "Gänsefüßchen" ist in Anführungsstrichen?!?'
print """das "Gänsefüßchen" ist in 'Anführungsstrichen'?!?"""
print '''das
"Gänsefüßchen" ist in
'Anführungsstrichen'?!?
"""
Ich denke du solltest vielleicht besser dir überlegen, wie du in Python selber die Daten der Frage organisiert... Wenn du das hast, könntest du Dookie's PyXO benutzen:
http://www.boa3d.de/python/modules/PyXO.php
Eine mini Beispiel, wie PyXO funktioniert:
http://python.sandtner.org/viewtopic.php?p=12992
Oder du nimmst pickle ...
Verfasst: Dienstag 14. Dezember 2004, 21:47
von Leonidas
PyXO finde ich für den Anfang etwas schwer zu verstehen/programmieren.
Verfasst: Dienstag 14. Dezember 2004, 22:49
von Dookie
Hi,
hmm ich würde mir erstmal überlegen, wie die Fragen und Antworten in der Datei stehen sollen.
Das kann z.B. so geschehen:
Code: Alles auswählen
"Frage 1" = "Antwort 1.0", "Antwort 1.1", "Antwort 1.2", "Antwort 1.3", 0
"Frage 2" = "Antwort 2.0", "Antwort 2.1", "Antwort 2.2", "Antwort 2.3", 3
...
"Frage n" = "Antwort n.0", "Antwort n.1", "Antwort n.2", "Antwort n.3", 2
Der letzte Wert ist die Nummer der richtigen Antwort
Sowas lässt sich sehr einfach einlesen:
Code: Alles auswählen
def unquote_text(text):
""" Gänsefüsschen Leerzeichen und Tabulatoren
am Anfang und Ende von 'text' löschen """
return text.strip(' \t"')
data = {}
f = open("quiz.data", 'r')
for line in f:
line = line.split("#")[0].strip() # Kommentare wegschneiden
if line: # nur wenn keine Leerzeile
frage, tmp = line.split("=")
tmp = tmp.split(",")
antworten = [unquote_text(x) for x in tmp[:-1]]
richtig = int(tmp[-1].strip())
data[unquote_text(frage)] = antworten + [richtig]
f.close()
'data' ist dann ein Dictionary das folgendermasen aufgebaut ist:
Code: Alles auswählen
data = {"Frage 1" : ["Antwort 1.0", "Antwort 1.1", "Antwort 1.2", "Antwort 1.3", 0],
"Frage 2" : ["Antwort 2.0", "Antwort 2.1", "Antwort 2.2", "Antwort 2.3", 3],
...
"Frage n" : ["Antwort n.0", "Antwort n.1", "Antwort n.3", "Antwort n.3", 2]}
Schreiben kannst du so ein Dictionary folgendermassen:
Code: Alles auswählen
f = open("quiz.data", "w")
for key, value in data.iteritems():
line = '"%s" = "%s", "%s", "%s", "%s", %i\n' % [key] + value
f.write(line)
f.close()
Die Reihenfolge der Einträge ist allerdings bei einem Dictionary nicht fix, also wenn neue Einträge hinzukommen, wird sich die Reihenfolge ändern. Wenn das unerwünscht ist, musst Du noch eine Liste mit den Schlüsseln ("Fragen") mitlaufen lassen. In den Fragen und Antworten dürfen auch keine '=' oder ',' vorkommen, sollten diese doch erlaubt sein müssen andere Trennzeichen verwendet werden oder diese Zeichen maskiert (wie z.B. manche Zeichen in html) werden.
Gruß
Dookie
P.S.: Die Scripts sind ungetestet, könnten also noch tippfehler enthalten

Verfasst: Dienstag 14. Dezember 2004, 22:58
von Leonidas
Zum speichern wäre warscheinlich
file|dict_to_dict|file für den Anfang am besten, ist ziemlich einfach zu verwenden. Auf jeden Fall mal einen Blick wert.
Verfasst: Dienstag 14. Dezember 2004, 23:47
von Dookie
file_to_dict/dict_to_file ist so nur für einfache Schlüssel/Werte-Paare brauchbar, darum hab ich hier eine abgewandelte Form gepostet.
Dookie
Verfasst: Mittwoch 15. Dezember 2004, 10:15
von knekke
Kann man dieses Forum irgendwo zum Forum des Jahres wählen?? Meine Stimme habt ihr!
Ich werd mich nachher mal durch Eure antworten durcharbeiten (bin noch nicht so schnell im lesen von code). Aber ich bin sicher das da brauchbare sachen bei sind
bis später,
Thomas
Verfasst: Mittwoch 15. Dezember 2004, 15:05
von knekke
Da bin ich wieder!
Das geht alles schon in die richtige Richtung, aber ganz bin ich noch nicht da...
Ich glaube die fragen-datenbank könnte ein anderes python-modul sein, das dann in das eigentliche quiz importiert wird.
könnte so aussehen:
Code: Alles auswählen
#fragen.py
f001="""Dies ist die erste Frage,
welche der antworten ist richtig?
1: blablabla
2: blubblub
3: tralalala
4: keine Ahnung"""
f002="""Hier steht die zweite frage
mit vier antworten"""
f003="""ditte"""
.
.
.
answ={f001:2,f002:1,f003:4,......} #die zahl hinter dem : entspricht der richtigen antwort
Ich müsste wohl zwei dateien draus machen, eine für die fragen, die andere für das dict. Aber wie könnte ich überhaupt die fortlaufenden nummern realisieren (f001,f002....)??? Da muss dann am anfang des scripts einmal fragen.py eingelesen und die letzte variable erkannt werden??!?
Wenn das so funktionieren würde,
dann könnte ich im eigentlichen quiz schnell die fragen stellen und antwort überprüfen:
Code: Alles auswählen
print f001
antwort = input("Antwort 1,2,3 oder 4???")
if antwort == answ[f001]:
print "Richtig!"
else:
print "Falsch!"
(stark abgekürzt

)
Naja, und der Volständigkeit halber nochmal das script zur fragenerstellung:
Code: Alles auswählen
#fragen_erstellen.py
from Tkinter import *
from os import *
root = Tk()
def ok():
frage = fotext.get(1.0,END)
yes = funtry.get()
fotext.delete(1.0,END)
funtry.delete(0,END)
nummer = "\nf001=" #diese nummer muss vorher aus der
datei fragen.py gezogen werden
frfile = file("frage.py","a")
frfile.write(nummer+'"""'+frage+'"""')
frfile.close() #
foben = Frame(root)
foben.pack()
fobel = Label(foben,text="Frage und 4 antworten")
fobel.pack()
fotext = Text(width=30,height=10)
fotext.pack()
funten = Frame(root)
funten.pack()
fubel = Label(funten,text="Richtige Antwort (1-4)")
fubel.pack()
funtry = Entry(funten)
funtry.pack(side=LEFT)
but = Button(funten,text="OK",command=ok)
but.pack(side=RIGHT)
root.mainloop()
Wenn ich euch mit dem Quatsch auf den Keks gehe, sagt bescheid. Mir machts jedenfalls noch Spaß, aber ich denke ich sollte doch mal in ein Nachschlagewerk investieren....
Gruß,
Thomas
Verfasst: Mittwoch 15. Dezember 2004, 15:16
von jens
Warum nimmst du dann nicht Dookie's Version?
fragen.py
Code: Alles auswählen
data = {
"Frage 1" : ["Antwort 1.0", "Antwort 1.1", "Antwort 1.2", "Antwort 1.3", 0],
"Frage 2" : ["Antwort 2.0", "Antwort 2.1", "Antwort 2.2", "Antwort 2.3", 3],
...
"Frage n" : ["Antwort n.0", "Antwort n.1", "Antwort n.3", "Antwort n.3", 2]
}
Im HauptProgramm dann das:
Code: Alles auswählen
for daten in fragen.data.iteritems():
print "Frage:", daten[0]
print "Antwort 1:", daten[1][0]
print "Antwort 2:", daten[1][1]
print "Antwort 3:", daten[1][2]
print "Antwort 4:", daten[1][3]
print "Lösung:", daten[1][4]
print "-"*20
[/python]
Das ist natürlich nur eine Auflistung

Verfasst: Mittwoch 15. Dezember 2004, 15:17
von Dookie
pack die Fragen einfach in eine Liste, dann kannst Du mit den Listenoperationen einfach den Index als Nummer verwenden und die Antworten in einer 2. Liste mitschreiben.
Sicher ginge das auch in einem Pythonmodul das du dann importieren kannst. Oder auch in mehreren Pythonmodulen mit unterschiedlichen Wissensgebieten. Flexiebler ist aber IMHO das Arbeiten mit reinen Textdateien (kann auch XML sein), aus denen du die Daten ausliest. Dann bist du nicht auf Python angewiesen und kannst die Daten auch mal für ein entsprechendes Programm in Lisp z.B. weiterverwenden.
Also wie schon bei meinem Beispiel gesagt, überleg dir erstmal wie du die Daten (Fragen, Antworten, Nummer der richtige Antwort) in Python anlegen willst, mit Dictionary oder mit Listen, oder sonstwie. Dann kannst Du schaun, wie du sie am einfachsten Speicherst, ob als Pythonmodul oder als Text/XML-Datei.
Gruß
Dookie
Verfasst: Mittwoch 15. Dezember 2004, 15:18
von Leonidas
knekke hat geschrieben:Das geht alles schon in die richtige Richtung, aber ganz bin ich noch nicht da...
Ich glaube die fragen-datenbank könnte ein anderes python-modul sein, das dann in das eigentliche quiz importiert wird.
Dann hast du aber das Problem, wenn jemand da etwas ändern will, muss er am Quellcode rumfummeln.
knekke hat geschrieben:Wenn ich euch mit dem Quatsch auf den Keks gehe, sagt bescheid. Mir machts jedenfalls noch Spaß, aber ich denke ich sollte doch mal in ein Nachschlagewerk investieren....
Kein Problem, ich denke ich werde auch mal sowas programmieren, dabei kann ich Glade auch testen (melde mich dann). Aber ich habe leider nicht so wahnsinnig viel Zeit.
Verfasst: Mittwoch 15. Dezember 2004, 16:29
von Dookie
gerade wieder eingefallen, die Klasse "Lict" könnte auch interessant sein für Dein Vorhaben:
http://python.sandtner.org/viewtopic.ph ... 0&start=25
Gruß
Dookie
Verfasst: Mittwoch 15. Dezember 2004, 17:00
von Leonidas
Hier mal das Quizprogramm in GTK. Kommentare erwünscht, blos nicht zu sehr als Vorbild nehmen.