We now have a working game, however the code isn't very **robust**. Robust code continues to function when errors occur. Here's an example of the start of a game: ```bash A clearing in a forest spanner lockpick What now?use spade What now?use spoon Traceback (most recent call last):   File "M:/PycharmProjects/Adventure/ad6.py", line 81, in <module>     Main()   File "M:/PycharmProjects/Adventure/ad6.py", line 75, in Main     if (objects[noun]==99): # check holding object KeyError: 'spoon' Process finished with exit code 1 ``` There are two problems here, one minor, one major. The  minor problem occurs when the user types use spade. Nothing happens as  the user isn't holding a spade, but the program doesn't alert the user  to that fact. The major problem occurs when the user tries to use spoon. At that point the program **throws an exception** and **terminates**. An **exception** is an error that occurs when the program is running and causes the program to **terminate**. In this case, the program is trying to look up an object that doesn't exist. We need to handle this exception. The following code deals with both the above problems. ```python elif verb == "use":     try: if (objects[noun]==99): # check holding object     use_object(noun) else:     print("I don't have a", noun)     except: print("I don't know what a", noun, "is") ``` You will see **try except** in many pieces of python code. It's the professional way to write **robust code** ![[adgame7.py]] ```python places = ["A clearing in a forest", "An old wooden cabin", "A dark cave", "The top of a Hill", "Deep in the Forest", "An Underground Lake", "Caught in the Brambles"] moves = [{"n": 1, "s": 2, "e":4}, {"s": 0, "e":3}, {"n": 0} , {"w": 1, "s":4}, {"n":3,"w":1, "e":6}, {"w": 2}, {"w": 4}] objects = {"spanner":0, "lockpick":0, "spade":2} location = 0 def print_objects(): for key, val in objects.items(): if val == location: print(key) def items(): print("You are carrying: ") for key, val in objects.items(): if val == 99: print(key) def take_object(noun): for key, val in objects.items(): if key == noun and val == location: print("Got it!") objects[noun] = 99 def drop_object(noun): for key, val in objects.items(): if key ==noun and val == 99: print("Dropped ", noun) objects[noun] = location def use_object(noun): if noun == "spade" and location == 0: objects["gold"] = 0 # create the gold print("You dug up some gold!") if noun == "spade" and location == 2: moves[2] = {"n": 0, "e":5} print("You've opened up a tunnel, leading east...") def Main(): ans = "" global location print(places[0]) print_objects() while ans != "bye": ans = input("What now?") words = ans.split() # Check if it's a move if len(words) == 1: if ans == "items": items() elif ans == "look": print(places[location]) print_objects() elif ans in moves[location]: location = moves[location].get(ans) print(places[location]) print_objects() else: print("I can't move that way") else: verb = words[0] # e.g. Take or Drop noun = words[1] # e.g. hammer or spanner if verb == "take": take_object(noun) elif verb == "drop": drop_object(noun) elif verb == "use": try: if (objects[noun]==99): # check holding object use_object(noun) else: print("I don't have a", noun) except: print("I don't know what a", noun, "is") else: rint("I don't understand what you mean") Main() ``` # Exercise 1. Copy the above code into pycharm and test it. 2. Run the code. What happens if you try to take the spade in the clearing in the forest? 3. Is the behaviour of the code here an error or an exception? 4. Fix the code. 5. What errors can occur when a user tries to drop an object? Fix those errors. 6. What other errors can you find in the code? 7. Are there any other exceptions you can find in the code?