Hallo Leute
bin anfänger.
habe eine liste von 4 worten die zufällig ausgegeben werden sollen, aber das letzte wort darf sich nicht wiederholen. das soll mit dem while-loop passieren. irgendwie krieg ich s nicht hin
danke leute
züfälliges Objekt ohne wiederholung mit while schleife
- __blackjack__
- User
- Beiträge: 14084
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@jamyoy: Wo ist das konkrete Problem? Was hast Du schon programmiert? Wo verhält sich das dann nicht so, wie Du das erwartest?
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
das habe ich bis jetzt programmiert. es geht um die methode getschlange. die methode soll einen doppelten schlangennamen vermeiden
from tkinter import *
from random import choice
class M(object):
schlangen = ["Kreuzotter","Ringelnatter","Python","Zornnatter"]
def __init__(self):
self.__schlange = ""
self.__lastschlange = ""
def getschlange(self):
self.__schlange = choice(M.schlangen)
while self.__schlange == self.__lastschlange:
self.getschlange()
self.__schlange = self.__lastschlange
else:
return self.__schlange
def getTitle(self):
return "Schlangennamen"
class V(object):
def __init__(self, komm):
self.fenster = Tk()
self.label = Label(master=self.fenster, text="",font=("ARIAL",28), fg="red")
self.button = Button(master=self.fenster, text="weitere Schlange", width=20, bg="green", fg="white", font=("ARIAL",28), command = komm)
self.bildKreuzotter = PhotoImage(file=".gif")
self.bildRingelnatter = PhotoImage(file=".gif")
self.bildPython = PhotoImage(file=".gif")
self.bildZornnatter = PhotoImage(file=".gif")
self.label.pack(padx = 10,pady =10)
self.button.pack(padx = 10,pady=10)
self.bildKreuzotter.pack(padx = 10,pady =10)
self.bildRingelnatter.pack(padx = 10,pady =10)
self.bildPython.pack(padx = 10,pady =10)
self.bildZornnatter.pack(padx = 10,pady =10)
def anzeigen(self, schlange):
self.label.config(text=schlange)
def setTitle(self, wert):
self.fenster.title(wert)
class C(object):
def __init__(self):
self.m = M()
self.view = V(self.kommando)
self.view.setTitle(self.m.getTitle())
def kommando(self):
schlange = self.m.getschlange()
self.view.anzeigen(schlange)
if __name__ == "__main__":
C()
from tkinter import *
from random import choice
class M(object):
schlangen = ["Kreuzotter","Ringelnatter","Python","Zornnatter"]
def __init__(self):
self.__schlange = ""
self.__lastschlange = ""
def getschlange(self):
self.__schlange = choice(M.schlangen)
while self.__schlange == self.__lastschlange:
self.getschlange()
self.__schlange = self.__lastschlange
else:
return self.__schlange
def getTitle(self):
return "Schlangennamen"
class V(object):
def __init__(self, komm):
self.fenster = Tk()
self.label = Label(master=self.fenster, text="",font=("ARIAL",28), fg="red")
self.button = Button(master=self.fenster, text="weitere Schlange", width=20, bg="green", fg="white", font=("ARIAL",28), command = komm)
self.bildKreuzotter = PhotoImage(file=".gif")
self.bildRingelnatter = PhotoImage(file=".gif")
self.bildPython = PhotoImage(file=".gif")
self.bildZornnatter = PhotoImage(file=".gif")
self.label.pack(padx = 10,pady =10)
self.button.pack(padx = 10,pady=10)
self.bildKreuzotter.pack(padx = 10,pady =10)
self.bildRingelnatter.pack(padx = 10,pady =10)
self.bildPython.pack(padx = 10,pady =10)
self.bildZornnatter.pack(padx = 10,pady =10)
def anzeigen(self, schlange):
self.label.config(text=schlange)
def setTitle(self, wert):
self.fenster.title(wert)
class C(object):
def __init__(self):
self.m = M()
self.view = V(self.kommando)
self.view.setTitle(self.m.getTitle())
def kommando(self):
schlange = self.m.getschlange()
self.view.anzeigen(schlange)
if __name__ == "__main__":
C()
- __blackjack__
- User
- Beiträge: 14084
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@jamyoy: Jetzt fehlt noch was daran nicht funktioniert. Wenn Fehlermeldungen kommen, bitte gleich mitliefern, damit man das nicht erst selbst herausfinden muss. Du hast die Fehlermeldung ja bereits.
Und die hat nichts mit dem beschriebenen Problem zu tun. `PhotoImage`-Objekte haben keine `pack()`-Methode. Was sollte das denn bringen?
Der gesamte Quelltext hat keine einzige Leerzeile. Üblich sind zwei zwischen Funktionen und Klassen und eine zwischen Methoden.
Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Namen sollten dem Leser vermitteln was der Wert dahinter bedeutet und nicht zum Rätselraten zwingen. Ich rate mal das `M`, `V`, und `C` für `Model`, `View`, und `Controller` stehen sollen. Vergiss diesen MVC-Quatsch gleich wieder. Der ist wie alle Entwurfsmuster dazu da ein Problem zu lösen. Wenn man das Problem gar nicht hat, dann braucht man auch die Lösung nicht. Du pustest da nur unnötig Code auf und machst den unnötig schwerer zu verstehen.
Entscheide Dich für Deutsch *oder* Englisch, am besten Englisch. Am schlimmsten sind Namen wo es *im* Namen gemischt ist.
Vergiss doppelte führende Unterstriche. Das ist *nicht* ``private`` aus anderen Programmiersprachen. Implementierungsdetails werden in Python durch *einen* führenden Unterstrich gekennzeichnet.
Der rekursive Aufruf in `getschlange()` ist auf jeden Fall falsch. Rekursion ist kein Ersatz für einfache Schleifen, zumal der Aufruf ja sogar in einer Schleife steht, die den Job eigentlich erledigen sollte.
Die `bild<Schlangenname>`-Attribute riechen sehr Stark danach, dass das eigentlich *eine* Datenstruktur sein sollte. Eventuell ein Wörterbuch das Schlangennamen auf `PhotoImage`-Objekte abbildet?
Ungetestet:
Was man trennen kann, und wenn es etwas komplexer wird auch sollte, ist die Programmlogik von der GUI. Das Problem was man damit löst ist testbaren Code zu haben. Momentan besteht die Programmlogik ja nur aus einem einzigen simplen Objekt: dem Iterator über die zufälligen Schlangennamen.
Und die hat nichts mit dem beschriebenen Problem zu tun. `PhotoImage`-Objekte haben keine `pack()`-Methode. Was sollte das denn bringen?
Der gesamte Quelltext hat keine einzige Leerzeile. Üblich sind zwei zwischen Funktionen und Klassen und eine zwischen Methoden.
Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.
Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).
Namen sollten dem Leser vermitteln was der Wert dahinter bedeutet und nicht zum Rätselraten zwingen. Ich rate mal das `M`, `V`, und `C` für `Model`, `View`, und `Controller` stehen sollen. Vergiss diesen MVC-Quatsch gleich wieder. Der ist wie alle Entwurfsmuster dazu da ein Problem zu lösen. Wenn man das Problem gar nicht hat, dann braucht man auch die Lösung nicht. Du pustest da nur unnötig Code auf und machst den unnötig schwerer zu verstehen.
Entscheide Dich für Deutsch *oder* Englisch, am besten Englisch. Am schlimmsten sind Namen wo es *im* Namen gemischt ist.
Vergiss doppelte führende Unterstriche. Das ist *nicht* ``private`` aus anderen Programmiersprachen. Implementierungsdetails werden in Python durch *einen* führenden Unterstrich gekennzeichnet.
Der rekursive Aufruf in `getschlange()` ist auf jeden Fall falsch. Rekursion ist kein Ersatz für einfache Schleifen, zumal der Aufruf ja sogar in einer Schleife steht, die den Job eigentlich erledigen sollte.
Die `bild<Schlangenname>`-Attribute riechen sehr Stark danach, dass das eigentlich *eine* Datenstruktur sein sollte. Eventuell ein Wörterbuch das Schlangennamen auf `PhotoImage`-Objekte abbildet?
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import tkinter as tk
import random
from functools import partial
from more_itertools import repeatfunc, unique_justseen
SNAKE_NAMES = ["Kreuzotter", "Ringelnatter", "Python", "Zornnatter"]
class MainWindow(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("Schlangennamen")
font = ("Arial", 28)
self.label = tk.Label(self, font=font, fg="red")
self.label.pack(padx=10, pady=10)
tk.Button(
self,
text="weitere Schlange",
fg="white",
bg="green",
font=font,
command=self.change_snake,
).pack(padx=10, pady=10)
self.snake_name_to_image = dict.fromkeys(
SNAKE_NAMES, tk.PhotoImage(file="test.gif")
)
assert len(SNAKE_NAMES) >= 2
self.random_snake_names = unique_justseen(
repeatfunc(partial(random.choice, SNAKE_NAMES))
)
self.change_snake()
def change_snake(self):
self.label["text"] = next(self.random_snake_names)
def main():
window = MainWindow()
window.mainloop()
if __name__ == "__main__":
main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Vielen Dank.
Jedoch bin ich erst ganz am Anfang und das Programm ist noch nicht 100 % nachzuvollziehen. Mir geht es nur darum das Problem, das nicht zweimal dieselbe Schlange hintereinander angezeigt wird(bei zufälliger Wiedergabe), zu lösen:
class M(object):
schlangen = ["Kreuzotter","Ringelnatter","Python","Zornnatter"]
def __init__(self):
self.__schlange = ""
self.__lastschlange = ""
def getschlange(self):
self.__schlange = choice(M.schlangen)
while self.__schlange == self.__lastschlange:
self.getschlange()
self.__schlange = self.__lastschlange
else:
return self.__schlange
Wie man die Bilder einfügt habe ich jetzt versatnden.
Jedoch bin ich erst ganz am Anfang und das Programm ist noch nicht 100 % nachzuvollziehen. Mir geht es nur darum das Problem, das nicht zweimal dieselbe Schlange hintereinander angezeigt wird(bei zufälliger Wiedergabe), zu lösen:
class M(object):
schlangen = ["Kreuzotter","Ringelnatter","Python","Zornnatter"]
def __init__(self):
self.__schlange = ""
self.__lastschlange = ""
def getschlange(self):
self.__schlange = choice(M.schlangen)
while self.__schlange == self.__lastschlange:
self.getschlange()
self.__schlange = self.__lastschlange
else:
return self.__schlange
Wie man die Bilder einfügt habe ich jetzt versatnden.
Aber dass man statt zwei Unterstriche nur eins schreibt, kannst Du schon nachvollziehen? Oder dass M kein guter Name ist.
Das choice muß in die Schleife und der rekursive Aufruf muß weg.
`schlange` muß kein Attribut sein, last reicht.
Das choice muß in die Schleife und der rekursive Aufruf muß weg.
`schlange` muß kein Attribut sein, last reicht.
- __blackjack__
- User
- Beiträge: 14084
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Und wirklich, vergiss MVC bis Du das tatsächlich mal brauchst. Man pflastert nicht auf ”Vorrat” irgendwelche Entwurfsmuster über das Programm.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
- MaximalMax
- User
- Beiträge: 18
- Registriert: Sonntag 3. Mai 2020, 00:51
Hallo, ich habe dir jetzt mal eine Lösung geschrieben, da ich das in Eile geschrieben habe, ist es kein Clean Code.
So müsste es gehen, falls es einen Error gibt, gehe in die Shell und gib ein:
Hier ist die Code-Lösung:
Einen schönen Tag dir noch!
So müsste es gehen, falls es einen Error gibt, gehe in die Shell und gib ein:
Code: Alles auswählen
pip install random
Code: Alles auswählen
import random
words = ["YouTube", "Instagram", "Twitter", "Snapchat"]
counter = 4
while counter != 0:
random_word = random.choice(words)
print(random_word)
words.remove(random_word)
counter -= 1
@MaximalMax:
random ist ein Modul aus der Standardbibliothek - das muss man nicht mit pip installieren.
Warum hat counter zufällig den Wert der Anzahl der Elemente in "words"? Ist das so gewollt? Wenn ja: Warum nimmst du dann nicht die Anzahl der Elemente in words?
Soll die Schleife so lange laufen, bis die Liste leer ist? Du entfernst je Durchlauf einen Eintrag - also könntest du dir "counter" komplett sparen - die Bedingung wäre dann, dass "words" keine leere Liste ist.
Übrigens ist nicht die Anforderung des Threadstarters, dass jedes Wort aus der Liste nur 1 Mal gewählt wird - die einzige Anforderung ist, dass das _letzte Wort_ nicht noch einmal gewählt wird.
random ist ein Modul aus der Standardbibliothek - das muss man nicht mit pip installieren.
Warum hat counter zufällig den Wert der Anzahl der Elemente in "words"? Ist das so gewollt? Wenn ja: Warum nimmst du dann nicht die Anzahl der Elemente in words?
Soll die Schleife so lange laufen, bis die Liste leer ist? Du entfernst je Durchlauf einen Eintrag - also könntest du dir "counter" komplett sparen - die Bedingung wäre dann, dass "words" keine leere Liste ist.
Übrigens ist nicht die Anforderung des Threadstarters, dass jedes Wort aus der Liste nur 1 Mal gewählt wird - die einzige Anforderung ist, dass das _letzte Wort_ nicht noch einmal gewählt wird.
Wenn man eine Anzahl an zufälligen Werten aus einer Liste möchte, dann benutzt man random.sample.
Hier mal 3 aus 4 Wörtern:
Wenn man alle vier Wörter in zufälliger Reihenfolge möchte, dann ist random.shuffle auch eine Möglichkeit.
Beides ist aber nicht das, was die/der Fragestellende möchte.
Sonstige Anmerkungen: wenn man eine fixe Anzahl an Durchläufen möchte, dann benutzt man keine while-Schleife, sondern eine for-Schleife: `for counter in range(4)`
Hier mal 3 aus 4 Wörtern:
Code: Alles auswählen
words = ["YouTube", "Instagram", "Twitter", "Snapchat"]
print(random.sample(words, 3))
Beides ist aber nicht das, was die/der Fragestellende möchte.
Sonstige Anmerkungen: wenn man eine fixe Anzahl an Durchläufen möchte, dann benutzt man keine while-Schleife, sondern eine for-Schleife: `for counter in range(4)`