String Abgleich mit Zufallsgenerator in tkinter

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
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Hallo,
teste mich zurzeit als Python Neuling in tkinter. ich habe das Ziel eine Art Rate Spiel zu schreiben, bei dem man Filmzitate dem richtigen Film zuordnen muss. Als normales Python Skript hab ich das alles auch schon geschafft, nur in der tkinter Entwicklung scheiterts noch... Hier mal der Code den ich haben möchte:

Code: Alles auswählen

S1 = "Schreibe Test"
S2 = "Falsch!"
S3 = "Immer noch falsch!"
from tkinter import *
from tkinter import messagebox

def Start():
    import random
    testing = [S1, S2, S3]
    Zufall = random.choice(testing)
    label1.config(text=Zufall)
    label1.grid(row = 0, column = 0)

def String1():
    import random
    testing = [S1, S2, S3]
    Zufall = random.choice(testing)
    label1.config(text=Zufall)
    label1.grid(row = 0, column = 0)
    
def Überprüfen():
    string1 = eingabefeld.get()
    if S1 in Zufall:    
        if "Test" in string1:   
             f2 = Tk()
             f2.title("Richtig!")
             label2 = Label(f2, text="Richtig!")
             exit_button2 = Button(f2, text="Schließen", command=f2.destroy)
             label2.grid(row = 0, column = 0)
             exit_button2.grid(row = 1,  column = 0)
         
    else:
                f2 = Tk()
                f2.title("Falsch!")
                label2 = Label(f2, text="Falsch!")
                exit_button2 = Button(f2, text="Schließen", command=f2.destroy)
                label2.grid(row = 0, column = 0)
                exit_button2.grid(row = 1, column = 0)
            
fenster = Tk()
fenster.title("Strings Abgleich")

#Start Label
label1 = Label(fenster, text="Start drücken")


#Hier Eingabe machen
eingabefeld = Entry(fenster, bd=5, width=40)

start_button = Button(fenster, text="Start", command=String1)
test_button = Button(fenster, text="Überprüfen", command=Überprüfen)
exit_button = Button(fenster, text="Beenden", command=fenster.destroy)


#Hinzufügen
label1.grid(row = 0, column = 0)
start_button.grid(row = 2, column = 0)
eingabefeld.grid(row = 0, column = 1)
test_button.grid(row = 1, column = 0)
exit_button.grid(row = 1, column = 1)


mainloop()
Was hier nicht stimmt? Also wenn da steht "Schreibe Test" soll er darauf warten dass der User Test reinschreibt, dann soll er mit richtig antworten. Aber: es klappt nicht wirklich :K ich kann das Problem auch nicht ganz erklären, mal sagt er Test wäre falsch, mal sagt er Test wäre bei allem richtig, egal was da steht... Jemand vllt Zeit und Lust sich ne Lösung für nen verzweifelten Python Programmierer auszudenken?

Hier wäre nochmal der Code als normales Python Skript ohne tkinter, der ja bereits funktioniert:

Code: Alles auswählen

#Film Zitate
fzhdr = "Du kannst nicht vorbei!"
fzhdr2 = "Ein Ring, sie zu knechten..."
fzpre = "Wenn es blutet, können wir es töten."
fzpre2 = "Du bist so abgrundtief hässlich..."
fzses = "Ich sehe tote Menschen"
fzsl1245 = "Jippi ya yeay, Schweinebacke!"
fzte1 ="Ich komme wieder!"
fztea = "Komm mit mir wenn du leben willst!"
fzte2 = "Hasta la Vista, Baby"
fzjb = "Mein Name ist Bond. James Bond."
fzbnt = "Ich bin Batman!"
fzb2 = "Warum so ernst?"
fzbmk = "Hast du schonmal mit dem Teufel im Mondschein getanzt?"
fzap = "Wie heißer Apfelkuchen..."
fzmps = "One batch. Two batch. Penny and dime. Hier komme ich."
fzsw5 = "Ich bin dein Vater"




print("Willkommen beim Film Zitate raten! Hier müssen sie den Zitaten den passenden Film zuordnen!")
print("Bitte beachten sie, dass dieses Modul noch in der Entwicklung ist.")
print("Ein Punkte-System ist noch in der Entwicklung")
            
Start = str(input("Bereit? [Ja/Nein] "))
p = 0
while Start:
    if "Ja" in Start:
        import random
        fz = [fzhdr, fzhdr2, fzpre, fzpre2, fzses, fzsl1245, fzte1]
        Zitat = random.choice(fz)
        print(Zitat)

        if fzhdr in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Herr der Ringe" in Welcher or "Herr der RInge" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p)
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktzahl: ", p)
                p = 0
                Start = str(input("Bereit? "))
        elif fzhdr2 in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Herr der Ringe" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p)
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktzahl: ", p)
                p = 0
                Start = str(input("Bereit? "))
        elif fzpre in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Predator" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p)
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktezahl: ", p)
                p = 0
                Start = str(input("Bereit? "))
        elif fzpre2 in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Predator" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p, "Punkte")
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktezahl: ", p)
                p = 0
                Start = str(input("Nochmal? "))
        elif fzses in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Sechster Sinn" in Welcher or "Sixt sense" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p, "Punkte")
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktezahl: ", p)
                p = 0
                Start = str(input("Nochmal? "))
        elif fzsl1245 in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Stirb langsam" in Welcher or "Die Hard" in Welcher or "Stirbt Langsam" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p, "Punkte")
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktezahl: ", p)
                p = 0
                Start = str(input("Nochmal? "))
        elif fzte1 in Zitat:
            Welcher = str(input("Welcher Film? "))
            if "Terminator" in Welcher:
                print("Richtig!")
                p = p + 10
                print(p, "Punkte")
                Start = str(input("Bereit? "))
            else:
                print("Leider falsch!")
                print("Erreichte Punktzahl: ", p)
                p = 0
                Start = str(input("Nochmal? "))
                            
    elif "Punkte" in Start:
        print("Ihre aktuelle Punktzahl: ", p)
        Start = str(input("Bereit? "))

    elif "Nein" in Start:
        print("Ok!")
        Start = str(input("Bereit? "))
    elif "Ende" in Start:
        print("Ok, bis zum nächsten mal!")
        p = 0
        Eingabe = str(input("Was wollen sie jetzt machen? "))
        break
    else:
        print("Ich verstehe ihre Eingabe nicht!")
        Start = str(input("Bereit? "))

Wäre echt toll wenn jemand die Lösung kennt :D
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Das ist schlicht furchtbarer Code, weshalb dir wahrscheinlich auch momentan niemand antwortet. Ich arbeite praktisch nicht mit tkinter, aber ich nehme an, dass Du da einen Logikfehler (oder auch eine falsche Einrückung) im Quellcode hast. Mit dem GUI komme ich nicht zurecht, d. h. ich verstehe nicht, was Du vom Benutzer eigentlich erwartest.

Zu deinem zweiten Codebeispiel: Packe die Zitate doch zumindest in eine Liste (empfohlen!) oder in ein Wörterbuch, wenn es denn sein muss, und entschlacke deinen Code im Hauptteil. Mir erschließt sich nicht, warum du da jeden einzelnen Fall testet und nicht einfach für einen gegebenen Fall (https://de.wikipedia.org/wiki/Don’t_repeat_yourself). Ferner musst du die Daten von der Programmlogik sauber trennen, weil du ansonsten bei einer Anpassung enorm viel fixen musst, was nicht Sinn der Übung ist.

Die Variablen-Namen sind nicht glücklich gewählt, schau dir bitte PEP8 an. Zudem packst Du m. E. zu viel ins Programm und hast einige Male um Ecken gedacht; dein Hauptprogramm prüft z. B. Eingaben, zu denen der Benutzer nicht (!) aufgefordert wurde. Ferner sind importe bitte an den Anfang zu stellen und nicht im Programmtext irgendwo reinzusetzen.

Soweit erst einmal.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Magst Du mal drüber schauen? Das ist mein Versuch den Konsolen-Quiz umzusetzen. Da ist nach oben noch Luft (main-Funktion, stärkere Strukturierung durch Funktionen, Feintuning), aber ich denke, man erkennt grob, wie ich es anders gemacht habe. Ich hoffe, dass es Dir beim Verständnis hilft...

Code: Alles auswählen

import random


filmzitate = [("Herr der Ringe", "Du kannst nicht vorbei!"),
              ("Herr der Ringe", "Ein Ring, sie zu knechten..."),
              ("Predator", "Wenn es blutet, können wir es töten."),
              ("Predator 2", "Du bist so abgrundtief hässlich..."),
              ("Star Wars", "Ich bin dein Vater"),
              ("James Bond", "Mein Name ist Bond. James Bond.")]
              # to be continued


filme = set([kombination[0] for kombination in filmzitate])
print("Film-Zitate-Quiz\n\nZu folgenden Filmen gibt es Zitate:")
for film in filme:
    print("* {}".format(film))
print("Nur diese Filme sind als Eingabe akzeptabel!\n")

while True:
    
    versuche = 1
        
    film, zitat = random.choice(filmzitate)

    while True:
        
        print("Zitat:\n\t{}\n".format(zitat))

        print("Mit e beenden Sie das Quizspiel. Erwartet wird sonst die Eingabe des Films.")
        eingabe = input("Aus welchem Film stammt das Zitat? ")

        if eingabe == film:
            print("\nSie haben das Zitat korrekt dem zugehörigen Film zugeordnet. Sie haben {} Versuch(e) benötigt.\n".format(versuche))
            versuche = 0
            break
        elif eingabe == "e":
            break
        else:
            print("\nIhre Eingabe war falsch!\n")

            weiter_raten = input("Möchten Sie es noch einmal versuchen (j/n)? ")
            if weiter_raten == "j":
                versuche += 1
            else:
                break
            

    if eingabe == "e":
        print("\nSpiel wurde beendet. Vielen Dank!")
        break
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Hi, ich habe mal die ganzen Breaks entfernt und die Textausgabe wird durch F-Strings übersichtlicher.
Mit Sicherheit nicht perfekt, nur mein Stil.

Code: Alles auswählen

import random

filmzitate = [("Herr der Ringe", "Du kannst nicht vorbei!"),
              ("Herr der Ringe", "Ein Ring, sie zu knechten..."),
              ("Predator", "Wenn es blutet, können wir es töten."),
              ("Predator 2", "Du bist so abgrundtief hässlich..."),
              ("Star Wars", "Ich bin dein Vater"),
              ("James Bond", "Mein Name ist Bond. James Bond.")]
              # to be continued

filme = set([kombination[0] for kombination in filmzitate])
print("Film-Zitate-Quiz\n")
print("Zu folgenden Filmen gibt es Zitate:")
for film in filme:
    print(f"* {film}")
print("Nur diese Titel sind als Eingabe akzeptabel!\n")

raten = True
while raten:
    versuche = 1
    film, zitat = random.choice(filmzitate)
    nochmal = True
    while nochmal:
        print(f"Zitat:\t{zitat}\n")

        print("Mit e beenden Sie das Quizspiel. Erwartet wird sonst die Eingabe des Films.")
        eingabe = input("Aus welchem Film stammt das Zitat? ")

        if eingabe == film:
            print("\nSie haben das Zitat korrekt dem zugehörigen Film zugeordnet.")
            mehrzahl = '' if versuche == 1 else 'e'
            print(f"Sie haben {versuche} Versuch{mehrzahl} benötigt.\n")
            nochmal = False
        elif eingabe == "e":
            raten = nochmal = False
        else:
            print("Ihre Eingabe war falsch!")
            weiter_raten = input("Möchten Sie es noch einmal versuchen (j/n)? ")
            if weiter_raten != "j":
                nochmal = False
            else:
                versuche += 1

print("\nSpiel wurde beendet. Vielen Dank!")
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Danke! Darauf bin ich nicht gekommen, vielleicht kann ich das noch mal irgendwo einbauen!
Sirius3
User
Beiträge: 17737
Registriert: Sonntag 21. Oktober 2012, 17:20

@ThomasL: breaks sind eigentlich besser, weil man sich dadurch eine Variable spart. Ich hab mal die unnötige Liste beim Erzeugen des Sets entfernt. Konstanten werden generell IN_GROSSBUCHSTABEN geschrieben. Dann sind ein paar Funktionen zur Strukturierung noch nützlich.

Code: Alles auswählen

import random
from itertools import count

FILMZITATE = [
    ("Herr der Ringe", "Du kannst nicht vorbei!"),
    ("Herr der Ringe", "Ein Ring, sie zu knechten..."),
    ("Predator", "Wenn es blutet, können wir es töten."),
    ("Predator 2", "Du bist so abgrundtief hässlich..."),
    ("Star Wars", "Ich bin dein Vater"),
    ("James Bond", "Mein Name ist Bond. James Bond."),
    # to be continued
]

def print_filme(filmzitate):
    filme = set(film for film, _ in filmzitate)
    print("Film-Zitate-Quiz\n")
    print("Zu folgenden Filmen gibt es Zitate:")
    for film in sorted(filme):
        print(f"* {film}")
    print("Nur diese Titel sind als Eingabe akzeptabel!\n")

def rate_film(film, zitat):
    for versuche in count(1):
        print(f"Zitat: {zitat}\n")
        print("Mit e beenden Sie das Quizspiel. Erwartet wird sonst die Eingabe des Films.")
        eingabe = input("Aus welchem Film stammt das Zitat? ")
        if eingabe == film:
            print("\nSie haben das Zitat korrekt dem zugehörigen Film zugeordnet.")
            print(f"Sie haben {versuche} Versuch{'' if versuche == 1 else 'e'} benötigt.\n")
            break
        elif eingabe == "e":
            raise KeyboardInterrupt()
        else:
            print("Ihre Eingabe war falsch!")
            weiter_raten = input("Möchten Sie es noch einmal versuchen (j/n)? ")
            if weiter_raten != "j":
                break

def main():
    print_filme(FILMZITATE)
    try:
        while True:
            film, zitat = random.choice(FILMZITATE)
            rate_film(film, zitat)
    except KeyboardInterrupt:
        pass
    print("\nSpiel wurde beendet. Vielen Dank!")

if __name__ == '__main__':
    main()
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Die Lösung mit count() von itertools ist sehr elegant, wieder was dazu gelernt.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten