AntsOfTheSky
AntsOfTheSky

Reputation: 205

Try and Except (TypeError)

What I'm trying to do is create a menu-style start in my program that let's the user choose whether they want to validate a code or generate one. The code looks like this:

choice = input("enter v for validate, or enter g for generate").lower()

try:
   choice == "v" and "g"

except TypeError:
   print("Not a valid choice! Try again")
   restartCode()    *#pre-defined function, d/w about this*

So I would like my program to output that print statement and do that defined function when the user inputs something other than "v" or "g" (not including when they enter capitalised versions of those characters). There is something wrong with my try and except function, but whenever the user inputs something other than those 2 characters the code just ends.

Upvotes: 4

Views: 30374

Answers (3)

kindall
kindall

Reputation: 184111

The problem is not in your try and except but in the fact that you are using try and except at all. The code in your try block won't give you an error so except will never be triggered. You want to use an if statement.

Also, your condition only checks for choice == "v" because it is evaluated as (choice == "v") and "g", and "g" is a string not of length 0, so is always "truthy" (taken as true in a Boolean context). Anything and True is unchanged, so only the first test has any meaning. The best way to do this test is with in.

Finally, you can and should use a while loop to repeat the prompt until the user enters a valid entry.

Putting it all together, you want something like this:

prompt = "Enter v for validate, or g for generate >"
choice = input(prompt).strip().lower()[:1]   # take at most 1 character

while choice not in ("v", "g"):
    print("Not a valid choice! Try again.")
    choice = input(prompt).strip().lower()[:1]

If you think of how you might generalize the code to use it again (as you probably will in the rest of your script), it's easy and useful to do so. First, you can break out the input stuff into a separate function, since it's called twice:

def input1char(prompt):
    return input(prompt + " >").strip().lower()[:1]

And then break out the while loop into its own function too:

def validinput(prompt, options):
    letters = tuple(options)
    choice = input1char(prompt)
    while choice not in options:
       print("'%s' is not a valid choice! Try again." % choice)
       choice = input1char(prompt)
    return choice

And then you just write:

 choice = validinput("Enter v for validate, or g for generate", "vg")

Upvotes: 2

Rafael
Rafael

Reputation: 3196

Try.

choice = input("enter v for validate, or enter g for generate").lower()

if (choice == "v") or (choice == "g"):
    #do something
else :
   print("Not a valid choice! Try again")
   restartCode()    #pre-defined function, d/w about this*

However, if you really want to stick with try/except you can store the desired inputs, and compare against them. The error will be a KeyError instead of a TypeError.

choice = input("enter v for validate, or enter g for generate").lower()
valid_choices = {'v':1, 'g':1}

try:
    valid_choices[choice]
    #do something

except:
    KeyError
    print("Not a valid choice! Try again")
    restartCode()   #pre-defined function, d/w about this

Upvotes: 4

Chris
Chris

Reputation: 22953

You are confused about what try/except does. try/except is used when an error is likely to be raised. No error will be raised because everything in your program is valid. Errors are raised only when there is an execution error in your code. Errors are not just raised when you need them to be.

You, however, want an error to be shown if the user does not enter a valid choice. You need to use an if/else logic instead, and print the error out yourself. And as a side note, the line choice == "v" and "g" does not test if choice is equal to 'v' or 'g'. It test if choice i equal to v and if the string 'g' is "truthy". Your estenially saying

if variable = value and True

I'm pretty sure that is not what you want. Here is how I would re-write your code.

if choice.lower() in {"v", "g"}: # if choice is 'v' or 'g'
    # do stuff
else: # otherwise
    print("Not a valid choice! Try again") # print a custom error message.

Upvotes: 2

Related Questions