'How to prevent python program crash when receiving alphabetical characters

My code is working just the way I want - unless input contains alphabetical characters. If so, is crashes. How can I prevent that? My code is as follows:

def main():
    
    choice ='0'

    while choice =='0':
        print ("-" * 30 + "MENU" + "-" * 30)
        print ("|" + " " * 19 + "1. Hourly to annual pay" + " " * 20 + "|")
        print ("|" + " " * 19 + "2. Annual to hourly pay" + " " * 20 + "|")
        print ("|" + " " * 19 + "3. Exit" + " " * 36 + "|")
        print ("-" * 64)
    
        choice = input ("Choose an option 1-3: ")
        if choice =="1":
            hourly = input ("Enter hourly pay: ")
            annual = float (hourly) * 2080
            print ("Annual pay is: ")
            print ("{:0.2f}".format(annual))
            main()
        elif choice =="2":
            a = input ("Enter annual pay: ")
            h = float (a) / 2080
            x = round(h, 2)
            print ("{:0.2f}".format(x))
            main()
        elif choice =="3":
            print ("Program exited gracefully.")
            raise SystemExit(0)
        else:
            print ("Unrecognized command - choose 1-3")
           
        
main()


Solution 1:[1]

You can catch ValueError when trying to convert the input to a float value. I modified your code to show how it could be done:

def get_float_input(prompt: str) -> float:
    try:
        data = input(prompt)
        data = float(data)

        return data
    except ValueError:
        raise ValueError('Please enter a valid number')


def main():
    while True:
        print("-" * 30 + "MENU" + "-" * 30)
        print("|" + " " * 19 + "1. Hourly to annual pay" + " " * 20 + "|")
        print("|" + " " * 19 + "2. Annual to hourly pay" + " " * 20 + "|")
        print("|" + " " * 19 + "3. Exit" + " " * 36 + "|")
        print("-" * 64)

        choice = input("Choose an option 1-3: ")
        if choice == "1":
            try:
                hourly = get_float_input("Enter hourly pay: ")
            except ValueError as e:
                print(e)
                continue

            annual = hourly * 2080
            print("Annual pay is: ")
            print("{:0.2f}".format(annual))

        elif choice == "2":
            try:
                a = get_float_input("Enter annual pay: ")
            except ValueError as e:
                print(e)
                continue

            h = a / 2080
            x = round(h, 2)
            print("{:0.2f}".format(x))

        elif choice == "3":
            print("Program exited gracefully.")
            raise SystemExit(0)

        else:
            print("Unrecognized command - choose 1-3")


if __name__ == '__main__':
    main()

Solution 2:[2]

I think you have to use while True to run program until user enters 3(infinite loop). Inorder to handle this problem you can use try except statement. So, your code needs to be like this

def main():
    
    print ("-" * 30 + "MENU" + "-" * 30)
    print ("|" + " " * 19 + "1. Hourly to annual pay" + " " * 20 + "|")
    print ("|" + " " * 19 + "2. Annual to hourly pay" + " " * 20 + "|")
    print ("|" + " " * 19 + "3. Exit" + " " * 36 + "|")
    print ("-" * 64)
    try:
        while True:
                choice = input ("Choose an option 1-3: ")
                if choice =="1":
                    hourly = input ("Enter hourly pay: ")
                    annual = float (hourly) * 2080
                    print ("Annual pay is: ")
                    print ("{:0.2f}".format(annual))
        
                elif choice =="2":
                    a = input ("Enter annual pay: ")
                    h = float (a) / 2080
                    x = round(h, 2)
                    print ("{:0.2f}".format(x))
        
                elif choice =="3":
                    print ("Program exited gracefully.")
                    raise SystemExit(0)
    except ValueError:
        print ("Unrecognized command - choose 1-3")
        
    
main()

Solution 3:[3]

I use a handy helper whenever I want numerical input.

def get_num(prompt="Enter number: "):
    """
    (str) -> num
    Outputs a prompt and loops until a valid number is
    entered by the user, at which point that value is
    returned and the function terminates
    """
    while True:
        num = input(prompt)
        try:
            num = float(num)
            return num
        except:
            print("Must enter a valid number")
            

def main():
    
    while True:
        print ("-" * 30 + "MENU" + "-" * 30)
        print ("|" + " " * 19 + "1. Hourly to annual pay" + " " * 20 + "|")
        print ("|" + " " * 19 + "2. Annual to hourly pay" + " " * 20 + "|")
        print ("|" + " " * 19 + "3. Exit" + " " * 36 + "|")
        print ("-" * 64)
    
        choice = get_num("Choose an option 1-3: ")
        if choice == 1:
            hourly = get_num("Enter hourly pay: ")
            annual = hourly * 2080
            print ("Annual pay is: ")
            print ("{:0.2f}".format(annual))
            # main() recursive call- don't do this
        elif choice == 2:
            a = get_num("Enter annual pay: ")
            h = a / 2080
            x = round(h, 2)
            print ("{:0.2f}".format(x))
            main()
        elif choice == 3:
            print ("Program exited gracefully.")
            raise SystemExit(0)
        else:
            print ("Unrecognized command - choose 1-3")
        repeat = input("Enter Y to repeat or any other key to quit: ")
        if repeat.lower() != "y":
            break
           
        
main()

Solution 4:[4]

Best thing you can do is to use exception handling while converting the input data to float. It will catch all invalid inputs that cant be converted to float.

def main():

    choice ='0'

    while choice =='0':
        print ("-" * 30 + "MENU" + "-" * 30)
        print ("|" + " " * 19 + "1. Hourly to annual pay" + " " * 20 + "|")
        print ("|" + " " * 19 + "2. Annual to hourly pay" + " " * 20 + "|")
        print ("|" + " " * 19 + "3. Exit" + " " * 36 + "|")
        print ("-" * 64)

        choice = input ("Choose an option 1-3: ")
        if choice =="1":
            hourly = input ("Enter hourly pay: ")
            try:
                annual = float (hourly) * 2080
                print ("Annual pay is: ")
                print ("{:0.2f}".format(annual))
            except:
                print("Invalid Input")
            main()
        elif choice =="2":
            a = input ("Enter annual pay: ")
            try:
                h = float (a) / 2080
                x = round(h, 2)
                print ("{:0.2f}".format(x))
            except:
                print("Invalid Input")
            main()
        elif choice =="3":
            print ("Program exited gracefully.")
            raise SystemExit(0)
        else:
            print ("Unrecognized command - choose 1-3")
main()

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 Leonardo Sirino
Solution 2
Solution 3 srattigan
Solution 4 Dharman