1

Im practicing with try and raise exceptions as I've still not fully grasped how to use them correctly.

I want to raise an exception here in this bit of code when the user enters a choice that't not in my 3 specified choices:

    inventory = []
    print "You can choose 2 items from the following:"
    print "Gun, Grenade, Smoke bomb. Type your weapon choices now: " 

    try:
        choice1 = raw_input("Choice 1:  ")
        inventory.append(choice1)

    except:
        if choice1 not in ('gun', 'grenade', 'smoke bomb'):
            raise Exception("Please enter one of the 3 choices only only")

However when I run it the users choice will be accepted no mater what they type in and Im not clear why.

I know I can make this work with other ways such as putting a while loop after the raw_input to check what was entered against those 3 items but I want to do this with try and except.

thanks

easy_c0mpany80
  • 327
  • 1
  • 7
  • 18
  • 2
    to `raise` exception you don't need `try/except`. You need `try/except` only when you need to catch exception. – furas Jan 26 '16 at 06:09

3 Answers3

7

I'm not sure why are you putting your check inside the exception handler. Fix it:

choice1 = raw_input("Choice 1:  ")
if choice1 not in ('gun', 'grenade', 'smoke bomb'):
    raise Exception("Please enter one of the 3 choices only only")

By the way, the built-in ValueError sounds like a logical exception choice here:

raise ValueError("Please enter one of the 3 choices only only")

And note the only only typo.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • I think raise Exception before `inventory.append(choice1)` is more reasonable – realli Jan 26 '16 at 06:13
  • OK, I guess my understanding of this topic is messed up then. When I use your solution it works but the program then ends when I want it to keep running (its part of a bigger part of code) and keep asking the user until they choose one of the correct answers, my understanding was that is how its supposed to work with an exception. Or should I just use a while loop? – easy_c0mpany80 Jan 26 '16 at 06:30
  • 1
    @easy_c0mpany80 it sounds like you don't need to actually raise an exception, but print out the choice validation error and let the user attempt it more. These are related threads: http://stackoverflow.com/q/1781445/771848, http://stackoverflow.com/questions/17394495/how-to-use-raw-input-with-while-loop. – alecxe Jan 26 '16 at 06:35
4

The advantage of error handling like Python's is that errors can be detected at one level but handled by another. Suppose you had a custom input function that tried to verify input and raised one of several exceptions if there was a problem. Here we'll use a custom exception but using a built-in one like ValueError, as was suggested, is good too:

class BadChoiceError(Exception):

    def __str__(self):
        return "That choice not available!"

def get_choice(prompt):
    choice = raw_input(prompt)
    if choice not in {'gun', 'grenade', 'smoke bomb'}:
        raise BadChoiceError()
    return choice

inventory = []

print "You can choose 2 items from the following:"
print "Gun, Grenade, Smoke bomb. Type your weapon choices now: " 

try:
    choice1 = get_choice("Choice 1: ")

    inventory.append(choice1)

except BadChoiceError as error:
    print(str(error))
    print("Please enter one of the 3 choices only.")

except:
    exit("Unknown error.  Try again later.")

The input function could have chosen to handle the error itself but instead it's allowing higher level code decide the best way to handle this situation (or not.)

cdlane
  • 40,441
  • 5
  • 32
  • 81
  • thanks, this makes sense to me but it seems like a lot of code for a simple task, is this the best way to do it? – easy_c0mpany80 Jan 26 '16 at 06:33
  • 1
    I can't say what is the best way -- I believe this style of exception handling came about to handle errors in larger programs and so may seem a bit cumbersome in smaller ones. But getting practice with it is a good thing. – cdlane Jan 27 '16 at 04:51
0

for this you can make your own custom exception ... make a respective class inheriting the Exception class try to catch th eexception with...s

class YourException(Exception):
    def __repr__(self):
        return 'invalid choice'
invent = []
try:
    c = raw_input("enter your choice :")
    if c not in ['dvdvdf','vfdv','fvdv']:#these are your choice
        raise YourException()