Überprüfung einer Eingabe (Kommandozeile) - Eleganz?

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
Theddun
User
Beiträge: 23
Registriert: Donnerstag 26. Februar 2015, 14:10

So. Ich habe jetzt schon einmal mein erstes kleines Programm geschrieben.

Es handelt sich um einen sehr simplen Dungeon Crawler in der Kommandozeile. Dabei kann der Spieler sich entscheiden in einen bestimmten Raum zu gehen. Es gibt immer drei Räume zur Auswahl. Entsprechend brauche ich eine Eingabe durch den Benutzer, welche dann überprüft werden muss, nämlich einmal ob es überhaupt ein Integer ist bzw. in einen Integer umgewandelt werden kann und, wenn es dann ein Integer ist, dass dieser 1, 2 oder 3 ist. Wenn eine dieser Bedingungen nicht zutrifft muss das Programm eine Ausweichmöglichkeit haben, damit es weiter laufen kann und nicht abstürzt.

Ich habe dafür bisher folgende Lösung gefunden, die auch so funktioniert wie gewollt. Das Ganze erscheint mir aber nicht sonderlich elegant. Zudem gibt mir das Program eine Warnung aus, wenn ich die Eingabe "exit" benutze um es zu beenden. Wie kann ich das abstellen bzw. wo liegt da der Fehler?

Code: Alles auswählen

#import of the modules
from random import randint

#do an infinite loop
starter = True
while starter == True:
    
    #input
    Eingabe = input("Eine 1, 2 oder 3 eingeben.")
    
    #possibility to end program by input, but still gives a warning back
    if Eingabe == "exit":
        exit()

    #check if it is an integer, if not generate one randomly
    try:
        val = int(Eingabe)
    except ValueError:
        print("Das ist kein Integer!")
        Eingabe = randint (1, 3)
        print("Das Programm konnte den Fehler jedoch abfangen und ihre falsche Eingabe durch die zufällig generierte Zahl "  + str(Eingabe) + " ersetzen.")

    #input is converted to integer
    Zahl = int(Eingabe)

    #check if the integer is between 1 and 3, if not generate one randomly
    Pruefer = [1, 2, 3]
    if Zahl in Pruefer:
        print("Stimmt! 1, 2 oder 3 und zudem ein Integer.")
    else:
        print("Stimmt nicht, aber zumindest ein Integer!")
        Eingabe = randint (1, 3)
        print("Das Programm konnte den Fehler jedoch abfangen und ihre falsche Eingabe durch die zufällig generierte Zahl "  + str(Eingabe) + " ersetzen.")

Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Ich würde die Funktionen aufteilen.

Eine Funktion könnte sicherstellen, dass nur Integer-Werte eingegeben werden.

Code: Alles auswählen

def get_integer_value(prompt):
    while True:
        value = input(prompt)
        try:
            return int(value)
        except ValueError:
            pass
Eine zweite Funktion könnte diese verwenden und eine Liste der erlaubten Antworten mitgeben.

Code: Alles auswählen

def get_action(prompt, actions):
    while True:
        action = get_integer_value(prompt)
        if action in actions:
            return action
Der Aufruf erfolgt dann wie folgt.

Code: Alles auswählen

action = get_action('Enter room number:', (1, 2, 4))
print(action)
Du kommst aus den Schleifen regulär nicht heraus, bis du eine gültige Antwort eingibst.

Jetzt kannst du dir den Code noch beliebig nach deinen Bedürfnissen anpassen. So könntest du, wie du es in deinem Code gezeigt hast, bei Fehleingaben eine zufällige Antwort wählen. Ich halte es allerdings für besser noch einmal nachzufragen.
BlackJack

@Theddun: Bei `exit()` bekommst Du eine Warnung weil es die Funktion an der Stelle eigentlich gar nicht gibt. Das ist keine eingebaute, dokumentierte Funktion. Stattdessen solltest Du die `exit()`-Funktion aus dem `sys`-Modul verwenden, oder noch besser: den Programmablauf so gestalten das man gar keine spezielle Funktion benötigt um das Programm zu beenden.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Theddun: in Zeile 6 ist das explizite Testen auf True unnötig, weil das sowieso implizit gemacht wird. Es reicht also "while starter:" und da Du starter nie änderst, kannst Du gleich den konstanten Wert eintragen, also "while True:". Zeile 13: statt exit würde ich mit break die Schleife verlassen. Warum weist Du in Zeile 17 der Variable val etwas zu, was Du nie wieder verwendest. Dagegen machst Du in Zeile 24 die Umwandlung in ein int nochmal. Das Erzeugen einer Zufallszahl und die entsprechende Bildschirmausgabe hast Du zwei mal geschrieben. Fass das doch zusammen. Bei drei Zahlen ist es noch nicht so schlimm, aber wenn Du mal einen Bereich 1..1000 testen willst, ist das mit > und < viel effektiver, also "if 1 <= Zahl <= 3:".
Die Mischung aus englischen Kommentaren und deutschen Variablennamen ist lustig. Häufiger ist es andersherum. Trotzdem sollten nach Python-Namenskonvention Variablen klein geschrieben werden um sie von Klassen unterscheiden zu können.
Theddun
User
Beiträge: 23
Registriert: Donnerstag 26. Februar 2015, 14:10

VIelen Dank für die wertvollen Hinweise. Werde ich versuchen alles so schnell wie möglich umzusetzen!
Antworten