Schere Stein Papier. Unbekannter Fehler

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
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

Code: Alles auswählen

#!/usr/bin/python3
import random
from helper_functions import integerüberprüfung
unentschieden = 0
sieg = 0
niederlage = 0
regeln = { 1 : 2, 2 : 3, 3 : 1 }
symbole = { 1 : "Stein", 2 : "Schere", 3 : "Papier" }
ende = False

while ende == False:
    print("***********************")
    print("* Schere Stein Papier *")
    print("***********************")

    print("Waehle zwischen Stein, Schere und Papier:\n")
    print("1. Stein")
    print("2. Schere")
    print("3. Papier\n")

    spieler = integerüberprüfung("Geben sie ihre Wahl ein: ",1,3)
    computer = random.randint(1,3)
    if spieler == computer:
        print("Stechen!")
        unentschieden += 1
        print("Statistik: Siege: {0}, Stechen: {1}, Niederlagen: {2}".format(sieg,unentschieden,niederlage))
    elif regeln[spieler] == computer:
        print(symbole[spieler] + " schlaegt " + symbole[computer] + ".")
        print("Du hast gewonnen!")
        sieg += 1
        print("Statistik: Siege: {0}, Stechen: {1}, Niederlagen: {2}".format(sieg,unentschieden,niederlage))
    else:
        print(symbole[computer] + " schlaegt " + symbole[spieler] + ".")
        print("Du hast verloren!")
        niederlage += 1
        print("Statistik: Siege: {0}, Stechen: {1}, Niederlagen: {2}".format(sieg,unentschieden,niederlage))


def integerüberprüfung(message, mindestzahl,höchstzahl):
    test = True
    while test == True:
        try:
            zahl = int(input(message))
            if zahl >= mindestzahl and zahl <= höchstzahl:
                print("Die Eingabe war in Ordnung!")
                test = False
            else:
                print("Die Höhe der Zahl ist NICHT in Ordnung")
        except ValueError:
            print("Das ist kein Integer")

Guten morgen,
Ich habe hier ein kleiner Konsolen Spiel. Alles funktionierte auch einwandfrei, bis ich die Funktion "integerüberprüfung" eingefügt habe.
Nun weiss ich nicht wo der Fehler steckt..

Der Fehler lautet:
Traceback (most recent call last):
File "./Schere_Stein_Papier.py", line 27, in <module>
elif regeln[spieler] == computer:
KeyError: None
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Fehler muss man lesen und verstehen. Hier ist meine Vorgehensweise in diesem Fall.


Fehlerdiagnose

Offensichtlich hat spieler den Wert None und das Dictionary regeln hat keinen Eintrag mit dem Key None. Woher stammt der Wert? Aha, es ist der Rückgabewert der (nicht gut benannten) Funktion integerüberprüfung. Wie kann es dazu kommen, dass von dort None zurückgegeben wird? Oh, offensichtlich wird dort niemals ein Wert zurückgegeben und damit ist der Rückgabewert automatisch None. Offensichtlich muss ich die Funktion korrigieren und zum passenden Zeitpunkt einen Wert zurückgeben.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

/me hat geschrieben:Fehler muss man lesen und verstehen. Hier ist meine Vorgehensweise in diesem Fall.


Fehlerdiagnose

Offensichtlich hat spieler den Wert None und das Dictionary regeln hat keinen Eintrag mit dem Key None. Woher stammt der Wert? Aha, es ist der Rückgabewert der (nicht gut benannten) Funktion integerüberprüfung. Wie kann es dazu kommen, dass von dort None zurückgegeben wird? Oh, offensichtlich wird dort niemals ein Wert zurückgegeben und damit ist der Rückgabewert automatisch None. Offensichtlich muss ich die Funktion korrigieren und zum passenden Zeitpunkt einen Wert zurückgeben.

Code: Alles auswählen

def integerüberprüfung(message, mindestzahl,höchstzahl):
    test = True
    while test == True:
        try:
            zahl = int(input(message))
            if zahl >= mindestzahl and zahl <= höchstzahl:
                print("Die Eingabe war in Ordnung!")
                return zahl      #<------------
                test = False
            else:
                print("Die Höhe der Zahl ist NICHT in Ordnung")
        except ValueError:
            print("Das ist kein Integer")
so ok?:)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nfehren hat geschrieben:so ok?:)
Jetzt hast du dadurch noch Überflüssiges im Code. Die Stelle mit "test = False" wird gar nicht mehr erreicht da die Funktion vorher durch return verlassen wird.. Die Zeile kann somit gelöscht werden. Damit ist auch die Bedingung "while test = True:" nicht mehr relevant, da test immer True ist. Du kannst damit also stattdessen einfach schreiben "while True:". Welche Zeile dadurch nun wieder überflüssig wird müsstest du eigentlich selber erkennen können. Such mal.
nfehren
User
Beiträge: 98
Registriert: Donnerstag 31. Oktober 2013, 15:11

/me hat geschrieben:
nfehren hat geschrieben:so ok?:)
Jetzt hast du dadurch noch Überflüssiges im Code. Die Stelle mit "test = False" wird gar nicht mehr erreicht da die Funktion vorher durch return verlassen wird.. Die Zeile kann somit gelöscht werden. Damit ist auch die Bedingung "while test = True:" nicht mehr relevant, da test immer True ist. Du kannst damit also stattdessen einfach schreiben "while True:". Welche Zeile dadurch nun wieder überflüssig wird müsstest du eigentlich selber erkennen können. Such mal.

Code: Alles auswählen

def integerüberprüfung(message, mindestzahl,höchstzahl):
    while True:
        try:
            zahl = int(input(message))
            if zahl >= mindestzahl and zahl <= höchstzahl:
                print("Die Eingabe war in Ordnung!")
                return zahl
            else:
                print("Die Höhe der Zahl ist NICHT in Ordnung")
        except ValueError:
            print("Das ist kein Integer")
So müsste es ja dann eigentlich passen :) Danke für die Hilfe!
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@nfehren
Ich würde ja die Validierung der Zahl nicht innerhalb des ``try...except`` Blocks durchführen, da ein eventuell dort auftretender Fehler nichts mit dem zu tun haben muss, der durch das ``except`` abgefangen wird. Zudem könnte man sich das ``else:`` sparen und die Meldung, dass alles ok ist gehört IMHO auch an eine Stelle außerhalb, wenn überhaupt nötig.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

nfehren hat geschrieben:So müsste es ja dann eigentlich passen :)
Funktionieren tut es, obwohl ich es noch etwas anders strukturieren würde.

Du solltest dir jetzt nur noch angewöhnen passende Namen zu wählen. "integerüberprüfung" ist unglücklich gewählt, da die Funktion ja eben nicht nur eine Prüfung durchführt ob ein Wert ein Integer (bzw. in einen solchen konvertierbar) ist. Bei einer Prüfung würde ich als Ergebnis auch eher True oder False erwarten. Hier hingegen wird eine Zahl zurückgegeben die in der Funktion auch noch per Eingabe abgefragt wird. Nichts davon geht aus dem Funktionsnamen hervor. Ich würde hier im Kontext der restlichen Namensgebung des Programms eher so etwas wie "symbolauswahl" als Namen verwenden.
Antworten