'Is there a way to capture invalid user input? [duplicate]

I am working on a game where the user travels through rooms by choosing a direction (North, South, East, West). My question is how can i capture an invalid user input? My current code errors out if the user selects a direction where there is no room to go. Here is my code:

current_Room='Torture_Room'

Rooms={

    'Torture_Room': {'N': 'Sawdust_Room', 'W':'Boiler_Room', 'S': 'Incinerator','E':'Meat_Grinder'},
    'Boiler_room': {'E': 'Torture_Room'},
     'Incinerator':{'N': 'Torture_Room', 'E': 'Meat_Hanging_Room'},
    'Sawdust_Room': {'E': 'Exit', 'S': 'Torture_Room'},
    'Meat_Grinder':{'N': 'Observation_Room', 'W': 'Torture_Room'},
    'Observation_Room':{'S':'Meat_Grinder'},
    'Meat_Hanging_Room': {'W': 'Incinerator'}
}




#create a way to get user input and keep track of direction



def get_cardinal_direct_from_user():
    while True:
        direction = input("Which direction would you like to go? >")
        if direction.upper() not in ["N", "S", "E", "W"]:
            print("Please enter a valid direction.")
        else:
            return direction.upper()



def main():
    current_room =  'Torture_Room'
    for i in range(10,1,-1):
        inp=get_cardinal_direct_from_user()
        current_room=Rooms[current_room][inp]
        print('you have entered:', current_room)
        print(f'you have {i} chances left')



if __name__ == "__main__":
    main()


Solution 1:[1]

You could pass a parameter to get_cardinal_direct_from_user to specify the allowable inputs. Then use Rooms[current_room].keys() to get all the allowable directions for that room. This way, your while True loop will run until one of the keys in the current room's dictionary is selected.

def get_cardinal_direct_from_user(allowed_inputs="NESW"):
    allowed_prompt = ", ".join(list(allowed_inputs))
    while True:
        direction = input(f"Which direction would you like to go? ({allowed_prompt})>")
        if direction.upper() not in allowed_inputs:
            print("Please enter a valid direction.")
        else:
            return direction.upper()

I set the default value of allowed_inputs to the string "NESW" so that you can call the function without passing that parameter, and direction.upper() in allowed_inputs will still work because x in some_string checks if the string x exists in some_string.

I also modified the input prompt to show the allowed inputs, so that your user isn't just guessing which inputs are valid.

In main(), when you ask for input:

    inp=get_cardinal_direct_from_user(Rooms[current_room].keys())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1