简体   繁体   中英

Why is my 'else: mainError()' not executing when a user inputs anything other than 1 or 2? E.g. @ or a or any number above 3

This is my code.

print("Welcome to the quiz")

print("Would you like to login with an existing account or register for a new account?")

class validation(Exception):

    def __init__(self, error):
        self.error = error

    def printError(self):
        print ("Error: {} ".format(self.error))

def mainError():
    try:
        raise validation('Please enter a valid input')
    except validation as e:
        e.printError()

def login():
    print ("yet to be made")

def register():
    print ("yet to be made")

while True:
    options = ["Login", "Register"]
    print("Please, choose one of the following options")
    num_of_options = len(options)

    for i in range(num_of_options):
        print("press " + str(i + 1) + " to " + options[i])
    uchoice = int(input("? "))
    print("You chose to " + options[uchoice - 1])

    if uchoice == 1:
        login()
        break
    elif uchoice == 2:
        register()
        break
    else:
        mainError()

If I enter 'a', it comes up with this error:

line 35, in <module>
uchoice = int(input("? "))
ValueError: invalid literal for int() with base 10: 'a'

If I enter a number above 2 like '3':

line 36, in <module>
print("You chose to " + options[uchoice - 1])
IndexError: list index out of range

How can I make sure that if a user enters anything other than 1 or 2, it executes my else commands where it calls my mainError() method which contains my exception that the program would display to my user.

The exception is raising because you don't have the options element you're trying to print in the message

 print("You chose to " + options[uchoice - 1])

Here you're trying to get options[a] or options [3], which doesn't exists. Put this print only inside the if/else that has a related option, and another print in the else without one. Something like this:

for i in range(num_of_options):
        print("press " + str(i + 1) + " to " + options[i])
    uchoice = int(input("? "))

    if uchoice == 1:
        print("You chose to " + options[uchoice - 1])
        login()
        break
    elif uchoice == 2:
        print("You chose to " + options[uchoice - 1])
        register()
        break
    else:
        mainError()
uchoice = int(input("? "))

Well here you have to do some error-checking code like:

try:
    uchoice = int(input("? "))
except ValueError:
    <handling for when the user doesn't input an integer [0-9]+>

Then to handle the overflow when a user enters an index which isn't within the list's range:

try:
    options[uchoice - 1]
except IndexError:
    <handling for when the user inputs out-of-range integer>

Of course this adds overhead due to the try: ... except <error>: ... statement so in the most optimal case you would use conditional checking per something like this:

if (uchoice - 1) > len(options):
    <handling for when the user inputs out-of-range integer>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM