Seite 1 von 1

Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 14:35
von Lou Cyphr3
Hallo Alle,

ich brauche mal einen Arschtritt, weil ich nicht drauf komme wie ich sinnvoll, die Wiederholung der Funktion eliminiere.

Code: Alles auswählen

    def control1(self):
        if not self.lock:
            if self.right_ans != self.a1:
                self.answer_button1.configure(bg="red")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock = True
Das Script funktioniert so, aber es sind noch einige Schönheitsfehler drin, also erstmal diesen.
Die Funktion soll das Ergebnis kontrollieren. Leider funktioniert das nur korrekt, wenn ich die Funktion in 4 verschiedenen Ausführungen
implementiere. Das geht mit Sicherheit besser und eleganter. Kann wer was dazu sagen?

Danke


hier nochmal der ganze code zum besseren Verständnis

Code: Alles auswählen

from tkinter import Button, Label, Tk, Text, END
import random

root = Tk()
root.title("Quizzz")
root.geometry("800x700")

questions = [["Wessen Mutter schwitzt nicht beim kacken?", "Merkels Mom", "Merkel selbst", "Söders Mom", "Chuck Norris Mom"],
             ["Wer oder was ist ein 'Spahn?", "Patient Zero", "Füllmaterial für Hamsterkäfig", "berühmte Trümmerfrau", " aktueller Gesundheitsminister"]]


def clear():
    line = root.grid_slaves()
    for n in line:
        n.destroy()

class Quiz:
    def __init__(self,quest):
        clear()
        self.questions = []
        for n in quest:
            self.questions.append(n)
        self.a1 = ""
        self.a2 = ""
        self.a3 = ""
        self.a4 = ""
        self.right_ans = ""

        self.right_ans_button = Button(root, text="", font=("Arial", 14))
        self.answer_button1 = Button(root, text="", font=("Arial", 14))
        self.answer_button2 = Button(root, text="", font=("Arial", 14))
        self.answer_button3 = Button(root, text="", font=("Arial", 14))
        self.answer_button4 = Button(root, text="", font=("Arial", 14))
        self.next = Button(root, text="nächste Frage", font=("Arial", 14), command=self.question)
        self.lock_button = Button(root, text="bestätigen", font=("Arial", 14), command=self.lock_it)

        self.lock = False
        self.right = 0
        self.number = 0
        self.Max = 2  # input button erstellen
        self.question()

    def lock_it(self):
        pass          # lock funktion schreiben

    def question(self):
        self.next.grid(column=0, row=6, pady=5)
        self.lock_button.grid(column=0, row=5, pady=5)
        if len(self.questions) > 0 and self.number < self.Max:
            self.number += 1
            self.lock = False
            rand_num = random.randint(0, len(self.questions) - 1)
            quest_line = self.questions[rand_num][0]
            self.right_ans = self.questions[rand_num][-1]
            answers = []
            for i in range(1,5):
                answers.append(self.questions[rand_num][i])
            random.shuffle(answers)

            self.a1 = answers[0]
            self.a2 = answers[1]
            self.a3 = answers[2]
            self.a4 = answers[3]

            the_question = Text(root, font=("Arial", 14), width=40, height=2)
            the_question.insert(END, quest_line)
            the_question.grid(column=0, row=0, padx=80, pady=(75, 0))

            self.answer_button1 = Button(root, text=self.a1, font=("Arial", 14), width=39, command = self.control1)
            self.answer_button2 = Button(root, text=self.a2, font=("Arial", 14), width=39, command = self.control2)
            self.answer_button3 = Button(root, text=self.a3, font=("Arial", 14), width=39, command = self.control3)
            self.answer_button4 = Button(root, text=self.a4, font=("Arial", 14), width=39, command = self.control4)

            self.answer_button1.grid(column=0, row=1, pady=5)
            self.answer_button2.grid(column=0, row=2, pady=5)
            self.answer_button3.grid(column=0, row=3, pady=5)
            self.answer_button4.grid(column=0, row=4, pady=5)

            if self.a1 == self.right_ans:
                self.right_ans_button = self.answer_button1
            elif self.a2 == self.right_ans:
                self.right_ans_button = self.answer_button2
            elif self.a3 == self.right_ans:
                self.right_ans_button = self.answer_button3
            elif self.a4 == self.right_ans:
                self.right_ans_button = self.answer_button4
            self.questions.pop(rand_num)
        else:
            clear()
            lb = Label(root, text="Du hast " + str(self.right) + " von " + str(self.Max) + " Fragen richtig beantwortet!", font=("Arial", 14))
            lb.grid(column=0,row=0,padx=120,pady=(170,15))
            to_menu = Button(root, text="zurück zum Start", font=("Arial", 14), command=create_menu)
            to_menu.grid(column=0,row=1)

    def control1(self):
        if not self.lock:
            if self.right_ans != self.a1:
                self.answer_button1.configure(bg="red")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock = True

    def control2(self):
        if not self.lock:
            if self.right_ans != self.a2:
                self.answer_button2.configure(bg="red")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock = True

    def control3(self):
        if not self.lock:
            if self.right_ans != self.a3:
                self.answer_button3.configure(bg="red")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock = True

    def control4(self):
        if not self.lock:
            if self.right_ans != self.a4:
                self.answer_button4.configure(bg="red")
            else:
                self.right += 1
            self.right_ans_button.configure(bg="green")
            self.lock = True



class Menu:
    def __init__(self):
        clear()
        self.Quiz = Button(root, text="das Quiz beginnen", font=("Arial", 14), command=create_quiz, width=15, height=3)
        self.Quiz.grid(column=0,row=0,padx=275,pady=200)

def create_menu():
   return Menu()

def create_quiz():
  return Quiz(questions)

create_menu()
root.mainloop()

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 15:10
von __blackjack__
@Lou Cyphr3: Du musst halt schauen wie die sich unterscheiden. Soweit ich das sehe durch den Antwort-Button. Der darf nicht fest in der Methode stehen, sondern muss als Argument übergeben werden. `functools.partial()` ist das was man da üblicherweise nimmt um aus einer Funktion/Methode eine neue Funktion zu erstellen bei der Argumente an Werte gebunden sind.

Als nächstes solltest Du die ganzen nummerierten Namen loswerden und diese Werte in Listen stecken.

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 15:22
von Lou Cyphr3
@__blackjack__
cool danke das seh ich mir Mal an.

Das mit den Listen kann ich mir gerade nur bedingt vorstellen. Kannst du mir einen kleines Beispiel geben?

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 16:37
von __deets__

Code: Alles auswählen

liste_von_dingen = [Ding(), AnderesDing()]
for ding in liste_von_dingen:
       ding.machwas()

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 16:51
von Lou Cyphr3
__deets__ hat geschrieben: Samstag 24. Oktober 2020, 16:37

Code: Alles auswählen

liste_von_dingen = [Ding(), AnderesDing()]
for ding in liste_von_dingen:
       ding.machwas()

okay gut, aber wie kann ich die liste dazu benutzen um nummerierte Namen und dummy's zu vermeiden?

Code: Alles auswählen

	self.a1 = ""
        self.a2 = ""
        self.a3 = ""
        self.a4 = ""
        
[...]
        
        self.answer_button1 = Button(root, text="", font=("Arial", 14))
        self.answer_button2 = Button(root, text="", font=("Arial", 14))
        self.answer_button3 = Button(root, text="", font=("Arial", 14))
        self.answer_button4 = Button(root, text="", font=("Arial", 14))

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 17:18
von __deets__
Indem du

self.answer_buttons = [Button(...), Button(...), ...]

machst.

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 17:29
von __blackjack__
Und als nächster Schritt dann da wo es Sinn macht, Schleifen verwendest um die Listen zu erstellen. Also in dem Beispiel würde man ja nicht viermal den gleichen `Button`-Aufruf schreiben wollen, sondern eine Schleife schreiben, die das macht. Ein Methodenaufruf zum anordnen des Widgets (`pack()` oder `grid()`) gehört da ja auch noch dazu der für jedes dieser Objekt gleich, oder fast gleich ist.

Edit: Und Dummywerte sollte man in der Regel ganz weg lassen. Wenn Du eine Liste mit leeren Zeichenketten hast die aber nie irgendwo benutzt werden, solltest Du diese Liste mit den leeren Zeichenketten auch nicht erstellen.

Falls man irgendwo etwas hat, wo man eine Definition braucht, beispielsweise weil das Attribut in der `__init__()` angelegt werden soll, wo man aber zu dem Zeitpunkt noch keinen Wert dafür hat, dann ist der dafür vorgesehene Wert, der dem Leser sagt, hier gibt es (noch) keinen Wert: `None`.

Re: Redundanzen vermeiden

Verfasst: Samstag 24. Oktober 2020, 17:31
von Lou Cyphr3
okay, ich versuchs mal. danke schön!

Re: Redundanzen vermeiden

Verfasst: Dienstag 27. Oktober 2020, 16:22
von Lou Cyphr3
@__blackjack__

ich bin gerade noch am rum probieren und frage mich ob du das so meinst oder ich auf dem Holzweg bin.

Ich bekomme eine Ausgabe, die mich glauben lässt das 3 Buttons erstellt wurden.

Code: Alles auswählen

from tkinter import Button

root = None
answer_button = Button(root, text="", font=("Arial", 14), width=39 )

buttons = []

for button in range(0,3):
    buttons.append(answer_button)
    
    
print(buttons)    
   
Ausgabe

Code: Alles auswählen

[<tkinter.Button object .!button>, <tkinter.Button object .!button>, <tkinter.Button object .!button>]

Process finished with exit code 0

Re: Redundanzen vermeiden

Verfasst: Dienstag 27. Oktober 2020, 16:43
von Sirius3
In welcher Zeile erstellst du denn Buttons? Und wie viele sind das?

Re: Redundanzen vermeiden

Verfasst: Dienstag 27. Oktober 2020, 16:49
von Lou Cyphr3
na ich fülle mit der for Schleife ( die 3 mal läuft) besser wäre wohl in range(1, 4), weil sie eigentlich 4 Buttons rein schreiben soll, die Liste mit 4 answer_button
oder nicht?

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 07:27
von Sirius3
Beantworte die Frage präzise: in welcher Zeile wird der Button erzeugt?
Und welchen Button packst Du dann drei mal in eine Liste?

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 09:46
von Lou Cyphr3
@sirius

Der Button wird in Zeile 4 ( answer_button...) erzeugt und genau diesen pack ich in die Liste.
Ich gehe davon aus, jetzt 3 Exemplare von Button in der Liste zu haben oder irre ich hier?
Ich bin mir ziemlich sicher, dass du das gefragte selbst weißt, weiß allerdings nicht auf was du hinaus willst..

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 09:50
von __deets__
Wenn du dreimal dasselbe Ding in eine Liste packst, warum erwartest du dann, dass da dreimal was unterschiedliches drin ist? Und was ist der Unterschied zu deinem Vorgehen und dem, dass ich schon Samstag skizziert habe?

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 11:30
von Lou Cyphr3
@ deets

der Unterschied zu dem was du Samstag skizziert hast, ist das was __ Blackjack__ geschrieben hat. Ich wollte eine Schleife benutzen um die Liste zu erstellen. Letztlich ist
der Button ja auch 3x Mal das gleiche. Es ging ja darum die Redundanz zu vermeiden, was ich nicht tue indem ich das gleiche Objekt mehrfach händisch in die Liste schreibe oder?

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 11:37
von sparrow
Du hast aber nicht 3x den gleichen Button sondern 3x den selben Button in der Liste.
Und wenn du 3x den selben Button hast, dann kannst du dir die Liste auch sparen.

Wenn wir uns beide jeweils ein identisches Auto kaufen und damit jeweils zu unserem gemeinsamen Arbeitgeber fahren, dann werden unsere Kollegen feststellen, dass wir das gleiche Auto fahren.
Wenn wir beide eine Fahrgemeinschaft bilden, dann werden sie bemerken, dass wir im selben Auto ankommen.

Das ist hier sehr wichtig. Ich kann das selbe Objekt in 20 Listen stecken - oder in 20 verschiedene. Aber es bleibt ein Objekt. Es wird nicht magisch kopiert.
Du möchtest aber 3 verschiedene Buttons haben.

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 11:37
von Jankie
Du sollst ja nicht das gleiche Objekt mehrfach in die Liste schreiben, du sollst drei verschiedene Instanzen des Buttons in die Liste schreiben, also es soll drei mal ein Button erzeugt werden. Es soll nicht einmal ein Button erzeugt werden und drei mal in eine Liste gepackt werden.

Vielleicht hilft dir das Snippet hier:

So machst du es im Moment:

Code: Alles auswählen

import random

random_number = random.randint(0,9)

numbers = []

for i in range(0,3):
    numbers.append(random_number)

print(numbers)
So sollte es sein:

Code: Alles auswählen

import random

numbers = []
for i in range(0,3):
    random_number = random.randint(0,9)
    numbers.append(random_number)

print(numbers)
Das kann mann dann noch kürzer als List comprehension schreiben:

Code: Alles auswählen

import random

numbers = [random.randint(0,9) for i in range(0,3)]

print(numbers)

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 12:13
von Lou Cyphr3
okay dann macht natürlich auch der hint von sirius3 mehr Sinn

also sollte dann das zielführender sein, ja?

Code: Alles auswählen

from tkinter import Button

root = None

buttons = []

for button in range(0,3):
    answer_button = Button(root, text="", font=("Arial", 14), width=39 )
    buttons.append(answer_button)
        
print(buttons)

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 13:00
von __deets__
Jupp. Wenn man es als reines Beispiel betrachtet. Anmerkungen zu Code auf Modul Ebene etc findest du ja vielfach.

Re: Redundanzen vermeiden

Verfasst: Mittwoch 28. Oktober 2020, 13:09
von Lou Cyphr3
sehr schön. vielen dank an alle!