dictionary als datenbank

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.
Antworten
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
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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 ...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

PyXO finde ich für den Anfang etwas schwer zu verstehen/programmieren.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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 ;)
[code]#!/usr/bin/env python
import this[/code]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
Benutzeravatar
knekke
User
Beiträge: 100
Registriert: Freitag 29. Oktober 2004, 17:23
Wohnort: Schweden

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 :wink:

bis später,
Thomas
Benutzeravatar
knekke
User
Beiträge: 100
Registriert: Freitag 29. Oktober 2004, 17:23
Wohnort: Schweden

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 :wink: )

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
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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 ;)
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

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
[code]#!/usr/bin/env python
import this[/code]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hier mal das Quizprogramm in GTK. Kommentare erwünscht, blos nicht zu sehr als Vorbild nehmen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten