"Zahlenraten", Übung aus Lektüre, Bedingung einführen

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
klezub
User
Beiträge: 3
Registriert: Freitag 10. Mai 2013, 19:42

Ich arbeite gerade mit einer Lektüre um Python zu lernen. Bin also noch ganz neu auf dem Gebiet.

In der Lektüre wird ein Zahlenraten "gebaut", das bei mir auch ohne Probleme funktioniert. Ein paar Seiten weiter wird dann die BREAK-Funktion eingebaut, die das Spiel bei Eingabe einer bestimmten Zahl beenden soll. Das klappt auch. Jedoch habe ich auf diese Weise immer das Problem, dass nach Abbruch des Spiels trotzdem eine Erfolgsmeldung erscheint als hätte man das Spiel bestanden. Jedoch wird darauf im Buch nicht weiter eingegangen sondern nur beschrieben: "Mit BREAK brechen Sie die Schleife ab."

Das wäre der Code:

Code: Alles auswählen

#Variablen festlegen
secret = 1000
estimate = 0
trials = 0
#Eingabe mit hinterlegter Zahl vergleichen
while estimate != secret:
    estimate = int(input("Zahl? "))
    if estimate == 0:
        print("Das Spiel wird beendet.")
        break
    if estimate < secret:
        print("Zahl zu klein.")
    if estimate > secret:
        print("Zahl zu gross.")
    trials = trials + 1
#Ausgabe von Erfolgsmeldung
print("Super. Sie haben die Zahl in", trials, "Versuchen erraten.")
Führt man den Code aus und gibt eine 0 ein erscheint folgendes:

Code: Alles auswählen

Zahl? 0
Das Spiel wird beendet.
Super. Sie haben die Zahl in 8 Versuchen erraten.
Jetzt würde ich gerne erreichen, dass die letzte Zeile weggelassen wir und nur dort steht: "Das Spiel wird beendet."

Jemand eine Idee? :K
Zuletzt geändert von Anonymous am Montag 13. Mai 2013, 15:48, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@klezub: Du müsstest die letzte Zeile halt nur unter einer bestimmten Bedingung ausführen. Welche Anweisung man dafür braucht, solltest Du eigentlich wissen wenn Du verstanden hast was der Rest des Programms macht, denn diese Anweisung kommt im Programm bereits mehrfach vor.

Andererseits ist das so ungünstig strukturiert. Statt beim ``while`` die Bedingung zu prüfen würde man eher eine „Endlosschleife” mit ``while True:`` schreiben und die dann im Erfolgsfall abbrechen. Dann würde in diesem Zweig auch die Erfolgsmeldung stehen und nicht nach der Schleife. Und man müsste `estimate` nicht vor der Schleife an irgendeinen Dummy-Wert binden, der garantiert ungleich dem `secret` ist.
av_jui
User
Beiträge: 25
Registriert: Samstag 4. Mai 2013, 12:45

Hi

Ich würde es z.b so lösen

Code: Alles auswählen

#Variablen festlegen
secret = 1000
estimate = 0
trials = 0
#Eingabe mit hinterlegter Zahl vergleichen
while estimate != secret:
    estimate = int(input("Zahl? "))
    if estimate == 0:
        print("Das Spiel wird beendet.")
        break
    if estimate < secret:
        print("Zahl zu klein.")
    if estimate > secret:
        print("Zahl zu gross.")
    trials = trials + 1

if estimate == secret:
    #Ausgabe von Erfolgsmeldung
    print("Super. Sie haben die Zahl in", trials, "Versuchen erraten.")
ungetestet
klezub
User
Beiträge: 3
Registriert: Freitag 10. Mai 2013, 19:42

av_jui hat geschrieben:Ich würde es z.b so lösen.
Der Code funktioniert scheinbar auch. Zumindest bei meinem Test erzielte er ebenso das gewünschte Resultat. :mrgreen:
BlackJack hat geschrieben:Du müsstest die letzte Zeile halt nur unter einer bestimmten Bedingung ausführen. Welche Anweisung man dafür braucht, solltest Du eigentlich wissen wenn Du verstanden hast was der Rest des Programms macht, denn diese Anweisung kommt im Programm bereits mehrfach vor.
Eigentlich habe ich schon verstanden was das Programm macht. Zumindest bilde ich mir das ein. Nur hatte ich irgendwie eine Denkblockade, da mir das für den Anfang zu viele Informationen waren. :?
BlackJack hat geschrieben:Andererseits ist das so ungünstig strukturiert. Statt beim ``while`` die Bedingung zu prüfen würde man eher eine „Endlosschleife” mit ``while True:`` schreiben und die dann im Erfolgsfall abbrechen. Dann würde in diesem Zweig auch die Erfolgsmeldung stehen und nicht nach der Schleife.
Von der Schreibweise her finde ich die Idee mit einer ``while True:``-Schleife viel besser. Die beiden Werte miteinander zu vergleichen, obwohl sie zu Beginn niemals gleich sein können hat mir sowieso nicht wirklich gefallen. Allerdings weiß ich jetzt nicht genau ob ich deine Aussage mit dem Unterbrechen der Schleife und der Anordnung der Erfolgsmeldung getroffen habe. Das BREAK soll dazu dienen, dass das Programm beendet wird, sobald die Bedingung erfüllt worden ist.

Hier der Code wie er jetzt scheinbar so funktioniert wie ich mir das vorstelle:

Code: Alles auswählen

#Variablen festlegen
secret = 1000
estimate = 0
trials = 0
leave = 0
#Eingabe mit hinterlegter Zahl vergleichen
while True:
    trials = trials + 1
    estimate = int(input("Zahl? "))
    #Spiel beenden
    if estimate == leave:
        print("Das Spiel wird beendet.")
        break
    #Erfolgsmeldung ausgeben
    elif estimate == secret:
        print("Super. Sie haben die Zahl in", trials, "Versuchen erraten.")
        break
    if estimate < secret:
        print("Zahl zu klein.")
    if estimate > secret:
        print("Zahl zu gross.")
Ich habe jetzt eine while True-Schleife gestartet, hier eine Bedingung zum Verlassen des Programms definiert, mit einer festen Größe (0), trifft dies nicht zu, wegen anderer Eingabe, wird eine Meldung ausgegeben ob die Zahl zu groß oder zu klein ist. Über die else if-Weiterleitung möchte ich dann definieren, dass eine Erfolgsmeldung ausgegeben wird, wenn nicht zutrifft, dass das Programm beendet worden ist.

Könnte ich das "Anordnungstechnisch" und "Umsetzungsmäßig" nun so lassen?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich würde es noch ein wenig anpassen:

Code: Alles auswählen

LEAVE = 0

secret = 1000
trials = 0

while True:
    trials = trials + 1
    guess = int(input("Zahl? "))
    
    if guess == LEAVE:
        #Spiel beenden
        print("Das Spiel wird beendet.")
        break
    elif guess < secret:
        print("Zahl zu klein.")
    elif guess > secret:
        print("Zahl zu gross.")
    else:
        #Erfolgsmeldung ausgeben
        print("Super. Sie haben die Zahl in", trials, "Versuchen erraten.")
        break
Kurze Zusammenfassung der Änderungen:
- Konstanten solltest du immer vollständig in Großbuchstaben schreiben, dann weiß jeder, dass der Wert nicht verändert werden soll (schau dir mal PEP 8 an)
- Kommentare sollten einen Mehrwert brigen. "Variable festlegen" tut dies nicht, dann kannst du es auch sparen. "Erfolgsmeldung ausgeben" ist ein ähnlicher Fall. Dass eine Meldung ausgegeben wird ist durch den Code offensichtlich, hier sollte eher stehen, dass der Spieler gewonnen hat.
- "estimate" sollte besser "guess" heißen.
- auch die Kleiner-/Größer-Bedingungen gehören in die elifs
- "estimate" (bzw. "guess") sollte nicht vor der Schleife mit einem beliebigen Wert initialisiert werden. Das ist unnötig und führt unter Umständen sogar schwer auffindbaren Fehlern.
- Du solltest noch testen, ob tatsächlich eine Zahl eingegeben wurde.
- Das Zählen der Versuche könntest du auch mit ``itertools.count`` machen, aber per Hand ist das hier auch in Ordnung.
- Den Test auf Gleichheit habe ich einfach mal in else gezogen.
- Kommentare sollten dort stehen, wo sie sinnvoll sind. Also in einem Block und nicht davor.
Das Leben ist wie ein Tennisball.
klezub
User
Beiträge: 3
Registriert: Freitag 10. Mai 2013, 19:42

EyDu hat geschrieben: - (schau dir mal PEP 8 an)
- "estimate" (bzw. "guess") sollte nicht vor der Schleife mit einem beliebigen Wert initialisiert werden. Das ist unnötig und führt unter Umständen sogar schwer auffindbaren Fehlern.
- Du solltest noch testen, ob tatsächlich eine Zahl eingegeben wurde.
- das mit PEP8 werde ich mir definitiv einmal anschauen. Scheint ein sehr informatives Dokument zu sein.
- jetzt wo dus sagst kommt mir erst der Gedanke, dass es eigentlich totaler Blödsinn ist guess einen Wert vorzuschreiben. Immerhin gebe ich diesen ja von Hand ein. :D
- macht das das Programm nicht automatisch? Möchte ich etwas anderes als eine Zahl eingeben, dann kommt folgender Fehler:

Code: Alles auswählen

>>> 
Zahl? hallo
Traceback (most recent call last):
  File "C:\Users\Kleinsteuber\Desktop\spiel.py", line 8, in <module>
    guess = int(input("Zahl? "))
ValueError: invalid literal for int() with base 10: 'hallo'
>>>
Nach der Ausgabe des Fehler wird das Programm jedoch "abgebrochen" und das "Spiel" beendet sich. Doch dazu mache ich mir erst später Gedanken, wenn mein Wissen ein wenig vorangetrieben wurde. :mrgreen:

Eine abschließende Frage habe ich da noch:
Das ist meine allererste Programmiersprache. Als ich nach einer passenden suchte fiel mir auf, dass es dieses: if, elif, else sehr oft gibt. Für ein besseres Verständnis des Ganzen -> Kann man das mit der Excel-Formel: WENN, DANN, SONST vergleichen? IF = WENN, elif = DANN, else: SONST

Oder muss ich das eher so sehen: IF leitet eine Bedingung ein, die erfüllt sein soll. ELIF führt die Bedingung weiter, falls der erste Wert nicht richtig ist. ELSE ist dann für alles, was nicht der Bedingung entspricht?

Ungefähr so:
IF Pommes bestellen
ELIF Ketchup dazu JA/NEIN ? -> NEIN
ELIF Mayonaisse dazu JA/Nein ? -> NEIN
ELIF Serviette dazu JA/NEIN ? -> JA
ELSE Go home!

Wenn ich Pommes bestelle, möchte ich Ketchup? Nein -> dann lieber Mayonaisse? Nein -> dann lieber eine Serviette? Ja. Bedingung erfüllt. Wenn nichts davon zutrifft -> Go home! :mrgreen:
BlackJack

@klezub: DANN wäre ``then``, aber das Schlüsselwort gibt es in Python nicht. Das ist in Python in diesem Fall der Doppelpunkt der die Bedingung von dem trennt was ausgeführt wird, wenn die Bedingung zutrifft. In BASIC gibt es ``then`` zum Beispiel als Schlüsselwort.

So etwas wie ``if`` und ``else`` gibt es in vielen Programmiersprachen, weil die Entscheidung auf Grund einer Bedingung etwas zu tun oder wenn die Bedingung nicht zutrifft etwas anderes zu tun, eine sehr grundlegende Kontrollstruktur ist.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Die Semantik von if/elif/else ist im Prinzip ganz einfach: Die Bedingungen der if/elif werden von oben nach unten getestet. Trifft eine Bedingung zu, so wird der dazugehörige Code ausgeführt und hinter das if/elif/else-Konstrukt gesprungen (es werden keine weiteren Bedingungen getestet und kein else ausgeführt). Wird keine der Bedingungen erfüllt, dann wird der Code im else-Teil ausgeführt.
Das Leben ist wie ein Tennisball.
Antworten