Problem mit while-Schleife

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
manuel97
User
Beiträge: 1
Registriert: Montag 6. Juli 2015, 21:08

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)
Zuletzt geändert von Anonymous am Montag 6. Juli 2015, 21:35, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
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.
bb1898
User
Beiträge: 200
Registriert: Mittwoch 12. Juli 2006, 14:28

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.
Antworten