Quiz

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
sunny0303
User
Beiträge: 5
Registriert: Freitag 6. Juni 2008, 15:55

Hey wär lieb wenn jemand mal drüber schauen könnte!

Code: Alles auswählen

from Tkinter import *
from random import randint

fragen = {1: ('Welcher Fluss fließt durch Berlin?',
              'Spree', 'Mosel', 'Rhein', 'Oder',
              'r',     'f',     'f',     'f'),
          2: ('Welcher Verein ist deutscher Fussballmeister 2002?',
              'Bayern', 'Dortmund', 'Schalke', 'Leverkusen',
              'f',      'r',        'f',       'f'),
          3: ('Mondamin ist ein/e ... ',
              'Sprache', 'chemisches Element', 'Backzutat', 'Schimpfwort',
              'f',       'f',                  'r',         'f')}




# >>>>Arbeiten mit Klassen
class Quiz:
    def __init__(self,fenster):
        self.root = fenster
        self.root.title('Superhirn')
        self.schon_gestellt = []
        self.hauptfenster()
        self.z = 0    # initialer Wert

    def hauptfenster(self):
        ueberschrift1 = Label(self.root, text='Wer wird Millionär?')
        ueberschrift1.pack(anchor='w')
        ueberschrift2 = Label(self.root, text='Bitte die richtige Antwort '\
                              'anklicken! Erst denken dann klicken!')
        ueberschrift2.pack(anchor='w')

        self.frage = Label(self.root, text = 'Hier erscheinen die Fragen',\
                           fg = "blue")
        self.frage.pack(padx = 5, pady = 5)

        #####>>>Die Radiobuttons:		      
        self.antwort = StringVar()

        whlrahmen = Frame(self.root)  # ...für die Optik! 
        whlrahmen.pack()

        self.ant1 = Radiobutton(whlrahmen, text = 'Antwort 1',\
                           variable = self.antwort, value = 1)
        self.ant1.pack(anchor='w')

        self.ant2 = Radiobutton(whlrahmen, text = 'Antwort 2',\
                           variable = self.antwort, value = 2)
        self.ant2.pack(anchor='w')

        self.ant3 = Radiobutton(whlrahmen, text = 'Antwort 3',\
                           variable = self.antwort, value = 3)
        self.ant3.pack(anchor='w')

        self.ant4 = Radiobutton(whlrahmen, text = 'Antwort 4',\
                           variable = self.antwort, value = 4)
        self.ant4.pack(anchor='w')

        #####>>>Label und Entry für die Namenseingabe:
        eingaberahmen = Frame(self.root)
        eingaberahmen.pack()

        ueberschrift3 = Label(eingaberahmen, text = 'Ihr Name:')
        ueberschrift3.pack(side=LEFT)

        name = Entry(eingaberahmen)
        name.pack(side=LEFT)

        self.ergebnis = Label(self.root, text = 'Ergebnis')
        self.ergebnis.pack(fill = BOTH, expand = 1)

        #####>>>Knöpfe zur Spielsteuerung und zum Beenden:       
        self.startknopf = Button(self.root, text='Spiel starten!', fg = "red")
        self.startknopf.pack(fill = BOTH, expand = 1)
        Widget.bind(self.startknopf, '<Button-1>', self.weiter)

        endeknopf = Button(self.root, text='ENDE', command = self.root.destroy)
        endeknopf.pack(fill = BOTH, expand = 1)




    def weiter(self, e):
        self.z = randint(1, 3)	# Der Zufallsgenerator wird angeschmissen!!
 
    # Will der Zufallsgenarator auf eine bereits gestellte Frage zugreifen, wird
    # er nach einem Test nochmals gestartet, bis eine noch nicht gestellte Frage
    # gewählt wird!

        while self.z in self.schon_gestellt:
                self.z = randint(1, 3)

    # Hier werden die bereits gestellten Fragen an die Liste angehängt:
        self.schon_gestellt.append(self.z)
                                                            
        self.frage.config(text = fragen[self.z][0])
        
        self.ant1.config(text = fragen[self.z][1])
        self.ant2.config(text = fragen[self.z][2])
        self.ant3.config(text = fragen[self.z][3])
        self.ant4.config(text = fragen[self.z][4])
        self.ergebnis.config(text = 'Bitte wählen!', fg = "red")
        self.startknopf.config(text = 'Weiter')
        Widget.bind(self.startknopf, '<Button-1>', self.auswerten)


    def auswerten(self, e):
        awort = self.antwort.get()
        if fragen[self.z][eval(awort) + 4] == 'r':
            if len(self.schon_gestellt) == 3:
                self.ergebnis.config(text = 'Toll du hast alles richtig '\
                                     'beantwortet!!!\nYou are the champion '\
                                     '... leider ohne Musike, die musst du '\
                                     'dir denken!!!', fg = "black",\
                                     bg = "yellow")
            else:
                self.weiter(e)
        else:
            self.ergebnis.config(text = 'Leider Falsch! ... vielleicht klappt'\
                                 'es beim nächsten Mal!!!\nSchade: Du hast lei'\
                                 'der verloren!')
                
# Programmstart:
test = Tk()
Quizzz = Quiz(test)
test.mainloop()

Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Und dann? ;-)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Für mich hört es sich so an, dass wir den Code zerreißen und auf unter die Hälfte LOC bringen sollen :wink: Die Klausuren in der nächsten Woche halten mich aber jetzt davon ab :roll:
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Minimalantwort: Nimm dir drei beliebige Programme aus dem Showcase, lies die Kommentare und wende sie auf dein Programm an :lol:


Edit: Rechtschreibung ...
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Okay, ich fang mal mit ein paar konkreten Codezeilen an. Die bisherigen Kommentare - so richtig sie ja sein mögen - helfen dir wahrscheinlich nicht so viel weiter.

a)
Besser als

Code: Alles auswählen

from Tkinter import *
ist

Code: Alles auswählen

import Tkinter as tk
Warum das besser ist, kannst du im Forum selbst herausfinden. Such z.B. mal nach den Stichwörtern "Sternchenimport" und "böse" ... :wink:

b)
Es gibt gute Konventionen z.B. für die Bezeichnung von Objekten. Such doch mal im Forum nach dem Stichwort "PEP8". Das hilft anderen (und dir selbst) Code besser lesen zu können.

c)
Die Zeilen 43-57 und alles, was damit zu tun hat, ist nicht gut gelöst.
Hier wird doch für jeden Radiobutton dasselbe gemacht, also könntest du z.B. eine Liste von Radiobuttons anlegen und diese dann durchlaufen.

d)
Die Verwendung von eval() ist selten eine gute Idee. In deinem Fall ganz sicher eine schlechte. Überleg mal, wie du das anders lösen könntest.

e)
Die Datenstruktur für die Fragen ist nicht optimal. In deinem Fall - wo die Schlüssel einfach nur aufeinanderfolgende Zahlen sind - genügt eine Liste.
Überlegen sollte man, ob man die einzelnen Einträge nicht anders aufbaut, indem man z.B. eine Antwort mit "r/f" jeweils in einem Tupel zusammenpackt oder auch eine Klasse Antwort definiert und dann mit Antwort-Objekte arbeitet.

Das genügt erstmal für den Anfang.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich würde die Fragen so repräsentieren:

Code: Alles auswählen

fragen = (
    Frage("Welcher Fluss...", "*Spree, Mosel,..."),
    Frage("Welcher Verein...", "Bayern, *Dortmund,..."),
    ...
)

class Frage:
    def __init__(self, frage, antworten):
        self.frage = frage
        self.antworten = []
        for antwort in map(str.strip, antworten.split(',')):
            if antwort[0] == '*':
                antwort = antwort[1:]
                self.richtig = antwort
            self.antworten.append(antwort)

    def pruefe(self, antwort):
        return antwort.lower() == self.richtig.lower()
Stefan
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Eine andere Möglichkeit wäre es, die richtige Antwort stets als erste Antwort abzulegen bzw. bei der Instanzbildung anzugeben und dann bei der Ausgabe der möglichen Antworten für den Anwender diese zuvor zu mischen (z.B. mit shuffle()). Dann spart man sich die Geschichte mit dem "*".
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

numerix hat geschrieben:Eine andere Möglichkeit wäre es, die richtige Antwort stets als erste Antwort abzulegen...
Viel besser. Ich dachte da zu kompliziert...

Stefan
Antworten