Seite 1 von 1
Problem mit while-Schleife
Verfasst: Montag 6. Juli 2015, 21:23
von manuel97
Bei dieser while-Schleife wird unten geprüft ob zahl3 gleich mit zahl1 oder zahl2 ist, und wenn ja wird sie neu generiert. So sollte es sein. Doch es endet in einer Endlosschleife. Warum? Die While schleife ohne "or" wo zahl2 auf zahl1 geprüft wird funktioniert ja auch. Es muss also an der while-Schleife mit "or" liegen. Das Program bleibt an dieser Stelle dann stehen, da es ja eine Endlosschleife ist. Dies weiß ich da ich zum Test ein print ("Test") unter die Schleife gesetzt habe (In dem Code unten nicht zu sehen). Beim Ausführen wird dann nur "Test" unendlichmal angezeigt.
Wo ist hier mein Denkfehler bzw. was muss ich ändern damit es funktioniert?
Code: Alles auswählen
while zähler < eingabe:
zahl1 = random.randint (1,10)
zahl2 = random.randint (1,10)
while zahl2 == zahl1:
zahl2 = random.randint (1,10)
zahl3 = random.randint (1,10)
while zahl3 == zahl1 or zahl2:
zahl3 = random.randint (1,10)
Re: Problem mit while-Schleife
Verfasst: Montag 6. Juli 2015, 21:42
von BlackJack
@manuel97: Du versuchst da etwas umgangssprachlich aufzufassen was in der Programmiersprache formal eine andere Bedeutung hat als Du denkst. „Wenn a gleich b oder c“ kann man in natürlicher Sprache sagen und damit meinen das a gleich b oder a gleich c ist, aber ``a == b or c`` bedeutet etwas anderes. Die implizite Klammerung sieht so aus: ``(a == b) or c``. Es wird also erst der Vergleich zwischen a und b durchgeführt und das Ergebnis dann mit dem Wahrheitswert von c logisch-oder-verknüpft. Und da es sich bei Dir um Zahlen handelt ist jeder Wert ausser 0 ”wahr”. Da `zahl2` aber nicht einmal zufällig 0 werden kann ist das 100% eine Endlosschleife.
Diesen ganzen Umstand möchte man sich aber sowieso nicht machen denn es gibt die `random.sample()`-Funktion womit das zu einem Einzeiler wird.
Re: Problem mit while-Schleife
Verfasst: Dienstag 7. Juli 2015, 16:32
von bb1898
BlackJack hat geschrieben:@manuel97: Du versuchst da etwas umgangssprachlich aufzufassen was in der Programmiersprache formal eine andere Bedeutung hat als Du denkst. „Wenn a gleich b oder c“ kann man in natürlicher Sprache sagen und damit meinen das a gleich b oder a gleich c ist, aber ``a == b or c`` bedeutet etwas anderes. Die implizite Klammerung sieht so aus: ``(a == b) or c``. Es wird also erst der Vergleich zwischen a und b durchgeführt und das Ergebnis dann mit dem Wahrheitswert von c logisch-oder-verknüpft. Und da es sich bei Dir um Zahlen handelt ist jeder Wert ausser 0 ”wahr”. Da `zahl2` aber nicht einmal zufällig 0 werden kann ist das 100% eine Endlosschleife.
Und wenn man die Reihenfolge der Vergleiche durch explizite Klammersetzung verändert, also "if a == (b or c)" schreibt, ist man auch nicht besser dran. Denn dann wird zuerst (b or c) ausgewertet und bekommt den ersten wahren (also hier von 0 verschiedenen) Wert. Wenn also b von 0, aber auch von a verschieden ist, dann wird die ganze Bedingung falsch, egal, ob c mit a übereinstimmt oder nicht. Hier also keine Endlosschleife, aber falsche Ergebnisse. Noch schlimmer, weil u.U. nicht so leicht erkennbar.
Richtig ist hier entweder "if a == b or a == c" oder "if a in (b, c)". Bei zwei Werten ziemlich egal, wenn es mehr werden, würde ich das Tupel (oder eine Liste) vorziehen.
Diesen ganzen Umstand möchte man sich aber sowieso nicht machen denn es gibt die `random.sample()`-Funktion womit das zu einem Einzeiler wird.
Sehr wahr, aber die Art, wie zusammengesetzte logische Ausdrücke ausgewertet werden, muss man unbedingt und ziemlich bald durchschaut haben, sonst wird die ganze Programmiererei nichts.