Ergebnisse auswerten und Schleife weiterlaufen lassen
Dafür hat man eine GUI-Klasse, die den Zustand enthält, bei Dir also ein Attribut spiel vom Typ Spiel. Aber dieses Spiel muß komplett über Methoden spielbar sein, ohne dass innerhalb der Klasse irgendwo direkt Nutzerabfragen stattfinden.
Ok, das bedeutet also, wenn ich dich recht verstanden habe, dass die GUI-Klasse sämtliche Interaktion mit dem Nutzer übernimmt. Die anderen Klassen (nenne ich einfach mal so) berechnen und verwerten usw., aber können selbst keine Nutzereingaben fordern.
Habe ich das so einigermaßen korrekt verstanden? Und ist die GUI-Klasse die mainloop-Funktion?
Habe ich das so einigermaßen korrekt verstanden? Und ist die GUI-Klasse die mainloop-Funktion?
Hallo,
ich habe jetzt mal versucht, das Programm ein wenig GUI-freundlicher zu gestalten. Das Problem, das ich habe, ist nun, dass Datentypen (in meinem Fall Objekte der Klasse Bruch) sich von einer Funktion nicht in die andere übertragen lassen.
Ich hätte 2 Lösungsansätze, weiß aber nicht, ob die gut sind:
1.) In der init-Methode der Spiel-Klasse wird automatisch ein Bruch erzeugt, in dem dann auch das Ergebnis gespeichert wird.
2.) Ich lese die Ausgabe in den labels aus, erstelle daraus einen neuen Bruch und nehme diesen dann als Grundlage zur Ergebnisüberprüfung.
Ich nehme an, da gibts sicherlich bessere Möglichkeiten. Hier mal der Code bis hierher:
ich habe jetzt mal versucht, das Programm ein wenig GUI-freundlicher zu gestalten. Das Problem, das ich habe, ist nun, dass Datentypen (in meinem Fall Objekte der Klasse Bruch) sich von einer Funktion nicht in die andere übertragen lassen.
Ich hätte 2 Lösungsansätze, weiß aber nicht, ob die gut sind:
1.) In der init-Methode der Spiel-Klasse wird automatisch ein Bruch erzeugt, in dem dann auch das Ergebnis gespeichert wird.
2.) Ich lese die Ausgabe in den labels aus, erstelle daraus einen neuen Bruch und nehme diesen dann als Grundlage zur Ergebnisüberprüfung.
Ich nehme an, da gibts sicherlich bessere Möglichkeiten. Hier mal der Code bis hierher:
Code: Alles auswählen
import tkinter
import random
import sys
import os
import math
class Spiel:
#Spiel spielen
def __init__(self):
# das Hauptfenster
self.hauptfenster = tkinter.Tk()
# definiere Darstellung des zu kürzenden Bruches
self.framelinks = tkinter.Frame(self.hauptfenster, width = 50)
self.framelinks.pack(side = "left", pady = 0)
self.zähler_anzeige = tkinter.Label(self.framelinks, text = "3")
self.zähler_anzeige["width"] = 2
self.zähler_anzeige["height"] = 0
self.zähler_anzeige["font"] = "Arial 70 bold"
self.zähler_anzeige["bg"] = "cyan"
self.zähler_anzeige["anchor"] = "s"
self.zähler_anzeige.pack(pady = 30)
self.bruchstrich = tkinter.Label(self.framelinks, text = "_____")
self.bruchstrich["width"] = 0
self.bruchstrich["height"] = 0
self.bruchstrich["font"] = "Arial 40 bold"
#bruchstrich["anchor"] = "n"
self.bruchstrich.pack(pady = 0)
self.nenner_anzeige = tkinter.Label(self.framelinks, text = "4")
self.nenner_anzeige["width"] = 2
self.nenner_anzeige["bg"] = "cyan"
self.nenner_anzeige["height"] = 0
self.nenner_anzeige["font"] = "Arial 70 bold"
self.nenner_anzeige.pack(pady = 50)
self.framemitte = tkinter.Frame(self.hauptfenster, width=50)
#framemitte["bg"] = "red"
self.framemitte.pack(side="left",pady=0)
self.istgleich = tkinter.Label(self.framemitte, text = "=")
self.istgleich["font"] = "Arial 70 bold"
self.istgleich["height"] = 0
self.istgleich["bg"] = "white"
self.istgleich["anchor"] = "n"
self.istgleich.pack(padx = 20)
self.framerechts = tkinter.Frame(self.hauptfenster,width=500)
self.framerechts.pack(side="left",pady=2)
# Definition Ergebniseingabe
self.zähler_eingabe = tkinter.Entry(self.framerechts)
self.zähler_eingabe["bg"] = "white"
self.zähler_eingabe["font"] = "Arial 70 bold"
self.zähler_eingabe["width"] = 2
#zehler_eingabe["anchor"] = "center"
self.zähler_eingabe.pack(padx = 20,pady = 0)
self.bruchstrich2 = tkinter.Label(self.framerechts, text = "_____")
self.bruchstrich2["width"] = 0
self.bruchstrich2["height"] = 0
self.bruchstrich2["font"] = "Arial 40 bold"
#bruchstrich["anchor"] = "n"
self.bruchstrich2.pack(pady = 30)
self.nenner_eingabe = tkinter.Entry(self.framerechts)
self.nenner_eingabe["bg"] = "white"
self.nenner_eingabe["font"] = "Arial 70 bold"
self.nenner_eingabe["width"] = 2
#nenner_eingabe["anchor"] = "center"
self.nenner_eingabe.pack(padx = 20,pady = 20)
# Definition Buttons
self.framebuttons = tkinter.Frame(self.hauptfenster, width=50)
self.framebuttons.pack(side="right",pady=0)
self.buttonende = tkinter.Button(self.framebuttons, text = "Ende", command = self.ende)
self.buttonende.pack(pady=0)
self.buttonaufgabe1 = tkinter.Button(self.framebuttons, text =" Kuerzen", command = self.typ1)
self.buttonaufgabe1.pack(pady=0,side="left")
self.buttonaufgabe2 = tkinter.Button(self.framebuttons, text = "Bruchrechnen", command = self.typ2)
self.buttonaufgabe2.pack()
self.buttonspeed = tkinter.Button(self.framebuttons, text = "Speedrechnen", command = self.speedrechnen)
self.buttonspeed.pack()
self.buttonhighscore = tkinter.Button(self.framebuttons, text = "Highscore ansehen", command = self.siehe_highscore)
self.buttonhighscore.pack()
self.buttonok = tkinter.Button(self.framebuttons, text = "OK", command = self.ergebnisroutine)
self.buttonok.pack()
# Ausgabelabel
self.infoausgabe = tkinter.Label(self.hauptfenster, text = " ", bg = "yellow", width = 50)
self.infoausgabe.pack()
# Anzeige des Hauptfensters
self.hauptfenster.mainloop()
def typ1(self):
bruch = Bruch()
self.zähler_anzeige["text"] = str(bruch.zähler)
self.nenner_anzeige["text"] = str(bruch.nenner)
bruch.kuerze_bruch()
print (bruch)
def typ2(self):
pass
def speedrechnen(self):
pass
def siehe_highscore(self):
pass
def ende(self):
self.hauptfenster.destroy()
def ergebnisroutine(self,bruch):
print (bruch)
class Bruch:
def __init__(self,zähler=0,nenner=0):
self.zähler=zähler
self.nenner=nenner
if zähler==0 or nenner ==0:
wert_zähler = self.generiere_bruchzahl()
wert_nenner = self.generiere_bruchzahl()
self.zähler += wert_zähler
self.nenner += wert_nenner
prob = 2,2,2,2,3,3,3,5,5,7
def __str__(self):
return str(self.zähler) + "/" + str(self.nenner)
def generiere_bruchzahl(self):
prob = 2,2,2,2,3,3,3,5,5,7
wert = 1
#random.choice(prob)
random.seed()
anz = random.randint(2,5)
for i in range(1,anz):
wert *=random.choice(prob)
#print (wert)
return wert
def kuerze_bruch(self):
ggt = math.gcd(self.zähler,self.nenner)
self.zähler = self.zähler // ggt
self.nenner = self.nenner // ggt
self.zähler = int(self.zähler)
self.nenner = int(self.nenner)
def mache_nennergleich(self,other):
self.kuerze_bruch()
other.kuerze_bruch()
print (self)
print (other)
counter=1
counter_b=1
while self.nenner != other.nenner:
if self.nenner < other.nenner:
self.nenner += (self.nenner / counter)
#print ("Nenner_a ", self.nenner)
counter +=1
if other.nenner < self.nenner:
other.nenner += (other.nenner / counter_b)
#print ("Nenner_b ", other.nenner)
counter_b +=1
if self.nenner == other.nenner:
break
self.zähler *= counter
other.zähler *= counter_b
self.nenner = int(self.nenner)
other.nenner = int(other.nenner)
return self, other
def addiere(self,other):
if self.nenner != other.nenner:
self,other=self.mache_nennergleich(other)
ergebnis = self.zähler + other.zähler
nenner = self.nenner
return ergebnis,nenner
def subtrahiere(self, other):
if self.nenner != other.nenner:
self, other = self.mache_nennergleich(other)
ergebnis = self.zähler -other.zähler
nenner = self.nenner
return ergebnis,nenner
def multipliziere(self, other):
self.kuerze_bruch()
other.kuerze_bruch()
erg_z = self.zähler*other.zähler
erg_n = self.nenner*other.nenner
return erg_z, erg_n
def dividiere(self,other):
self.kuerze_bruch()
other.kuerze_bruch()
erg_z = self.zähler*other.nenner
erg_n = self.nenner*other.zähler
return erg_z, erg_n
def ausgabe(self):
print (self.zähler, " / ", self.nenner)
#Hauptprogramm
#if __name__ == '__main':
spiel = Spiel()
Die Klasse Bruch hat immer noch die selben Fehler, die ich schon zu anfang angemerkt hatte.
Und wie schon geschrieben, ist __init__ zum Initialisieren da, nicht dass darin das ganze Programm läuft. Das mainloop hat darin nichts verloren.
Die ganzen Konfigurationen der Labels gibt man schon beim Erzeugen an.
Und warum ist das if-__main__ auskommentiert? Da fehlt auch noch die main-Funktion.
os und sys werden importiert, aber gar nicht benutzt.
Und weder 1 noch 2, denn es gibt Attribute, denen kann man auch neue Werte zuweisen.
Und wie schon geschrieben, ist __init__ zum Initialisieren da, nicht dass darin das ganze Programm läuft. Das mainloop hat darin nichts verloren.
Die ganzen Konfigurationen der Labels gibt man schon beim Erzeugen an.
Und warum ist das if-__main__ auskommentiert? Da fehlt auch noch die main-Funktion.
os und sys werden importiert, aber gar nicht benutzt.
Code: Alles auswählen
import tkinter
import random
import math
class Spiel:
def __init__(self):
# das Hauptfenster
self.hauptfenster = tkinter.Tk()
self.framelinks = tkinter.Frame(self.hauptfenster, width=50)
self.framelinks.pack(side=tkinter.LEFT, pady=0)
self.zähler_anzeige = tkinter.Label(self.framelinks,
text="3", width=2, height=0, font="Arial 70 bold",
bg="cyan", anchor="s")
self.zähler_anzeige.pack(pady=30)
self.bruchstrich = tkinter.Label(self.framelinks,
text="_____", width=0, height=0, font="Arial 40 bold")
self.bruchstrich.pack(pady=0)
self.nenner_anzeige = tkinter.Label(self.framelinks,
text="4", width=2, height=0, font="Arial 70 bold")
self.nenner_anzeige.pack(pady=50)
self.framemitte = tkinter.Frame(self.hauptfenster, width=50)
self.framemitte.pack(side=tkinter.LEFT, pady=0)
self.istgleich = tkinter.Label(self.framemitte,
text="=", height=0, font="Arial 70 bold", bg="white",
anchor=tkinter.N)
self.istgleich.pack(padx=20)
self.framerechts = tkinter.Frame(self.hauptfenster, width=500)
self.framerechts.pack(side=tkinter.LEFT, pady=2)
# Definition Ergebniseingabe
self.zähler_eingabe = tkinter.Entry(self.framerechts,
bg="white", font="Arial 70 bold",width=2)
self.zähler_eingabe.pack(padx=20,pady=0)
self.bruchstrich2 = tkinter.Label(self.framerechts,
text="_____", width=0, height=0, font="Arial 40 bold")
self.bruchstrich2.pack(pady=30)
self.nenner_eingabe=tkinter.Entry(self.framerechts,
bg="white", font="Arial 70 bold",width=2)
self.nenner_eingabe.pack(padx = 20,pady = 20)
# Definition Buttons
self.framebuttons = tkinter.Frame(self.hauptfenster, width=50)
self.framebuttons.pack(side="right",pady=0)
self.buttonende = tkinter.Button(self.framebuttons, text = "Ende", command = self.ende)
self.buttonende.pack(pady=0)
self.buttonaufgabe1 = tkinter.Button(self.framebuttons, text =" Kuerzen", command = self.typ1)
self.buttonaufgabe1.pack(pady=0,side="left")
self.buttonaufgabe2 = tkinter.Button(self.framebuttons, text = "Bruchrechnen", command = self.typ2)
self.buttonaufgabe2.pack()
self.buttonspeed = tkinter.Button(self.framebuttons, text = "Speedrechnen", command = self.speedrechnen)
self.buttonspeed.pack()
self.buttonhighscore = tkinter.Button(self.framebuttons, text = "Highscore ansehen", command = self.siehe_highscore)
self.buttonhighscore.pack()
self.buttonok = tkinter.Button(self.framebuttons, text = "OK", command = self.ergebnisroutine)
self.buttonok.pack()
# Ausgabelabel
self.infoausgabe = tkinter.Label(self.hauptfenster, text = " ", bg = "yellow", width = 50)
self.infoausgabe.pack()
...
def main():
spiel = Spiel()
spiel.hauptfenster.mainloop()
#Hauptprogramm
if __name__ == '__main__':
main()
Ok, sehe ich soweit ein. An der Klasse Bruch arbeite ich nach und nach.
Den Fehler habe ich erstmal gefunden. Habe das "self" vergessen - dann kanns mit den Attributen logischerweise nicht klappen.
Das mit der main- Funktion kann ich leider nicht nach deinem Vorschlag machen - dann bekomme ich aus irgendeinem Grund nichts mehr angezeigt. (wenn ich die auskommentierte Zeile nutze).
Nicht mal eine Fehlermeldung. Programm startet, aber ohne irgendeine Anzeige.
Den Fehler habe ich erstmal gefunden. Habe das "self" vergessen - dann kanns mit den Attributen logischerweise nicht klappen.
Das mit der main- Funktion kann ich leider nicht nach deinem Vorschlag machen - dann bekomme ich aus irgendeinem Grund nichts mehr angezeigt. (wenn ich die auskommentierte Zeile nutze).
Nicht mal eine Fehlermeldung. Programm startet, aber ohne irgendeine Anzeige.
So, bin heute wieder mal ein bisschen zum Programmieren gekommen.
Ich habs jetzt soweit hinbekommen, dass ein Bruch erzeugt wird und das Ergebnis (der gekürzte Bruch) wird dann überprüft.
Wenn ich mehrere Aufgaben hintereinander möchte, habe ich jetzt eine neue Funktion eingebaut: Sie überprüft, ob die Anzahl der Aufgaben erreicht ist und leitet nur dann zur Ergebnisroutine weiter, wenn dies nicht der Fall ist.
Leider scheitert es daran, dass ich aus dieser Kontrollfunktion die Ergebnisroutine nicht aufrufen kann. Er meint, dass self nicht definiert sei ...
Weiß jemand Abhilfe? Hier mal der Code:
Ich habs jetzt soweit hinbekommen, dass ein Bruch erzeugt wird und das Ergebnis (der gekürzte Bruch) wird dann überprüft.
Wenn ich mehrere Aufgaben hintereinander möchte, habe ich jetzt eine neue Funktion eingebaut: Sie überprüft, ob die Anzahl der Aufgaben erreicht ist und leitet nur dann zur Ergebnisroutine weiter, wenn dies nicht der Fall ist.
Leider scheitert es daran, dass ich aus dieser Kontrollfunktion die Ergebnisroutine nicht aufrufen kann. Er meint, dass self nicht definiert sei ...
Weiß jemand Abhilfe? Hier mal der Code:
Code: Alles auswählen
import tkinter
import random
import sys
import os
import math
class Spiel:
#Spiel spielen
def __init__(self):
# das Hauptfenster
self.hauptfenster = tkinter.Tk()
# definiere Darstellung des zu kürzenden Bruches
self.framelinks = tkinter.Frame(self.hauptfenster, width = 50)
self.framelinks.pack(side = "left", pady = 0)
self.zähler_anzeige = tkinter.Label(self.framelinks, text = "3")
self.zähler_anzeige["width"] = 2
self.zähler_anzeige["height"] = 0
self.zähler_anzeige["font"] = "Arial 70 bold"
self.zähler_anzeige["bg"] = "cyan"
self.zähler_anzeige["anchor"] = "s"
self.zähler_anzeige.pack(pady = 30)
self.bruchstrich = tkinter.Label(self.framelinks, text = "_____")
self.bruchstrich["width"] = 0
self.bruchstrich["height"] = 0
self.bruchstrich["font"] = "Arial 40 bold"
#bruchstrich["anchor"] = "n"
self.bruchstrich.pack(pady = 0)
self.nenner_anzeige = tkinter.Label(self.framelinks, text = "4")
self.nenner_anzeige["width"] = 2
self.nenner_anzeige["bg"] = "cyan"
self.nenner_anzeige["height"] = 0
self.nenner_anzeige["font"] = "Arial 70 bold"
self.nenner_anzeige.pack(pady = 50)
self.framemitte = tkinter.Frame(self.hauptfenster, width=50)
#framemitte["bg"] = "red"
self.framemitte.pack(side="left",pady=0)
self.istgleich = tkinter.Label(self.framemitte, text = "=")
self.istgleich["font"] = "Arial 70 bold"
self.istgleich["height"] = 0
self.istgleich["bg"] = "white"
self.istgleich["anchor"] = "n"
self.istgleich.pack(padx = 20)
self.framerechts = tkinter.Frame(self.hauptfenster,width=500)
self.framerechts.pack(side="left",pady=2)
# Definition Ergebniseingabe
self.zähler_eingabe = tkinter.Entry(self.framerechts)
self.zähler_eingabe["bg"] = "white"
self.zähler_eingabe["font"] = "Arial 70 bold"
self.zähler_eingabe["width"] = 2
#zehler_eingabe["anchor"] = "center"
self.zähler_eingabe.pack(padx = 20,pady = 0)
self.bruchstrich2 = tkinter.Label(self.framerechts, text = "_____")
self.bruchstrich2["width"] = 0
self.bruchstrich2["height"] = 0
self.bruchstrich2["font"] = "Arial 40 bold"
#bruchstrich["anchor"] = "n"
self.bruchstrich2.pack(pady = 30)
self.nenner_eingabe = tkinter.Entry(self.framerechts)
self.nenner_eingabe["bg"] = "white"
self.nenner_eingabe["font"] = "Arial 70 bold"
self.nenner_eingabe["width"] = 2
#nenner_eingabe["anchor"] = "center"
self.nenner_eingabe.pack(padx = 20,pady = 20)
# Definition Buttons
self.framebuttons = tkinter.Frame(self.hauptfenster, width=50)
self.framebuttons.pack(side="right",pady=0)
self.buttonende = tkinter.Button(self.framebuttons, text = "Ende", command = self.ende)
self.buttonende.pack(pady=0)
self.buttonaufgabe1 = tkinter.Button(self.framebuttons, text =" Kuerzen", command = self.typ1)
self.buttonaufgabe1.pack(pady=0,side="left")
self.buttonaufgabe2 = tkinter.Button(self.framebuttons, text = "Bruchrechnen", command = self.typ2)
self.buttonaufgabe2.pack()
self.buttonspeed = tkinter.Button(self.framebuttons, text = "Speedrechnen", command = self.speedrechnen)
self.buttonspeed.pack()
self.buttonhighscore = tkinter.Button(self.framebuttons, text = "Highscore ansehen", command = self.siehe_highscore)
self.buttonhighscore.pack()
self.buttonok = tkinter.Button(self.framebuttons, text = "OK", command = self.checkergebnis)
self.buttonok.pack()
# Ausgabelabel
self.infoausgabe = tkinter.Label(self.hauptfenster, text = " ", bg = "yellow", width = 50)
self.infoausgabe.pack()
self.anzahl = 3
self.aufgabenzähler = 0
def typ1(self):
self.bruch = Bruch()
self.zähler_anzeige["text"] = str(self.bruch.zähler)
self.nenner_anzeige["text"] = str(self.bruch.nenner)
self.bruch.kuerze_bruch()
print (self.bruch)
def typ2(self):
pass
def speedrechnen(self):
pass
def siehe_highscore(self):
pass
def ende(self):
self.hauptfenster.destroy()
def checkergebnis(aufgabenzähler):
if aufgabenzähler == 3:
self.infoausgabe["text"] = "Alle Aufgaben gelöst"
else:
ergebnisroutine()
def ergebnisroutine(self):
ergebnis_zähler = 0
ergebnis_nenner = 0
try:
ergebnis_zähler = int(self.zähler_eingabe.get())
ergebnis_nenner = int(self.nenner_eingabe.get())
#print (ergebnis_zähler)
except:
self.infoausgabe["text"] = "Bitte Zahl eingeben"
#self.infoausgabe["text"] = str(ergebnis_zähler)
else:
self.infoausgabe["text"] = str(ergebnis_zähler)
if ergebnis_zähler == self.bruch.zähler and ergebnis_nenner == self.bruch.nenner:
self.infoausgabe["text"] = "richtig"
self.aufgabenzähler +=1
self.typ1()
else:
self.infoausgabe["text"] = "falsch"
class Bruch:
def __init__(self,zähler=0,nenner=0):
self.zähler=zähler
self.nenner=nenner
if zähler==0 or nenner ==0:
wert_zähler = self.generiere_bruchzahl()
wert_nenner = self.generiere_bruchzahl()
self.zähler += wert_zähler
self.nenner += wert_nenner
prob = 2,2,2,2,3,3,3,5,5,7
def __str__(self):
return str(self.zähler) + "/" + str(self.nenner)
def generiere_bruchzahl(self):
prob = 2,2,2,2,3,3,3,5,5,7
wert = 1
#random.choice(prob)
random.seed()
anz = random.randint(2,5)
for i in range(1,anz):
wert *=random.choice(prob)
#print (wert)
return wert
def kuerze_bruch(self):
ggt = math.gcd(self.zähler,self.nenner)
self.zähler = self.zähler // ggt
self.nenner = self.nenner // ggt
self.zähler = int(self.zähler)
self.nenner = int(self.nenner)
def mache_nennergleich(self,other):
self.kuerze_bruch()
other.kuerze_bruch()
print (self)
print (other)
counter=1
counter_b=1
while self.nenner != other.nenner:
if self.nenner < other.nenner:
self.nenner += (self.nenner / counter)
#print ("Nenner_a ", self.nenner)
counter +=1
if other.nenner < self.nenner:
other.nenner += (other.nenner / counter_b)
#print ("Nenner_b ", other.nenner)
counter_b +=1
if self.nenner == other.nenner:
break
self.zähler *= counter
other.zähler *= counter_b
self.nenner = int(self.nenner)
other.nenner = int(other.nenner)
return self, other
def addiere(self,other):
if self.nenner != other.nenner:
self,other=self.mache_nennergleich(other)
ergebnis = self.zähler + other.zähler
nenner = self.nenner
return ergebnis,nenner
def subtrahiere(self, other):
if self.nenner != other.nenner:
self, other = self.mache_nennergleich(other)
ergebnis = self.zähler -other.zähler
nenner = self.nenner
return ergebnis,nenner
def multipliziere(self, other):
self.kuerze_bruch()
other.kuerze_bruch()
erg_z = self.zähler*other.zähler
erg_n = self.nenner*other.nenner
return erg_z, erg_n
def dividiere(self,other):
self.kuerze_bruch()
other.kuerze_bruch()
erg_z = self.zähler*other.nenner
erg_n = self.nenner*other.zähler
return erg_z, erg_n
def ausgabe(self):
print (self.zähler, " / ", self.nenner)
def main():
spiel = Spiel()
spiel.hauptfenster.mainloop()
#Hauptprogramm
if __name__ == '__main__':
main()