Search code examples
pythonuser-inputtry-except

Multiple User Input with Try Except Python


I have been tasked with creating a python program that will ask for user inputs and calculate monthly loan repayments, this is the formula I have to work off: Formula. Doing this was not too difficult, however the tutor asked as a bonus to try to make the user inputs 'unbreakable', meaning if any value other than the expected were input it wouldn't break the program. I thought this can easily be done with Try Except, and that's what I did, however I believe my code can be written in a much more concise manner, instead of a Try Except for every input as below:

err = "Please enter a number only!!"
while True:
    try:
        A = int(input("How much were you loaned? "))
    except ValueError:
        print(err)
        continue
    else:
        break
while True:
    try:
        R = float(input("At what monthly rate interest? ")) / 100
    except ValueError:
        print(err)
        continue
    else:
        break
while True:
    try:
        N = int(input("And how many years is the loan for? "))
    except ValueError:
        print(err)
        continue
    else:
        break
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £", P, "yearly", "or, £", P / 12, "monthly") 

I feel as if perhaps the user inputs could be put into a For Loop, or perhaps all of this into one Try Except block? After thinking about it, I put all the inputs into one Try Except block, however as soon as you fail to correctly input the expected data for the user input, it goes right back to the beginning, not to the question you were on. This is not what I want. Have a look:

err = "Please enter a number only!!"
while True:
    try:
        A = int(input("How much were you loaned? "))
        R = float(input("At what monthly rate interest? ")) / 100
        N = int(input("And how many years is the loan for? "))
    except ValueError:
        print(err)
        continue
    else:
        break
RA = R * A
RN = 1 - (1 + R) ** -N
P = RA / RN
print("You will pay £", P, "yearly", "or, £", P / 12, "monthly")

How do you think I can modify this code to make it more concise, shorter, and efficient without having a Try Except for every user input?


Solution

  • Modularise it, and use a generic function that handles input and loops until the user enters what is asked.

    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 do_calc():
        """(None) -> None
        Get user input, perform calculations and output results
        """
        A = int(get_num("How much were you loaned? "))
        R = get_num("At what monthly rate interest? ") / 100
        N = int(get_num("And how many years is the loan for? "))
        RA = R * A
        RN = 1 - (1 + R) ** -N
        P = RA / RN
        print(f"You will pay £{round(P, 2)} yearly or £{P/12:.2f} monthly")
    
    do_calc()
    

    Using the f-string from Python 3 is really nice and elegant- just plug in the values or calculations inside the curly braces. As per suggestion in comment, you may wish to show to two decimal places using either the round function or the formatting option as shown.

    A more pythonic way to name your variables would be

    • amount rather than A
    • rate rather than R
    • num_years rather than N and so on.