0

I am new to python and been trying to write a small code for mortgage calculator. I use three variable namely interest, no_of_month and principal_amt and its value is taken using input function.

Below is the code for the same.

#######################
while True:
    try:
        no_of_month = int(input('Enter no of months you want for payment: '))
    except ValueError: 
        print('The value you entered is not integer')
        continue
    else:
        break
##############################
while True:
    try:
        interest = int(input('Enter interest you want for the loan: '))
    except ValueError:
        print('The value you entered is not integer')
        continue
    else:
        break
    ################################    
while True:
    try:
        principal_amt = int(input('Enter principal amount you want as loan:'))
    except ValueError:
        print('The value you entered is not integer')
        continue
    else:
        break

Now the above code works fine for me, but I am not happy repeating my block of code. I wish to use function or may be something else so has to minimize my line of code.

Is there a way to define a function and call it with proper validation in place?

Thanks in advance

4
  • Yes, defining a function is exactly the way. Did you try that? What happened? Commented Apr 19, 2020 at 7:29
  • Yes, I tried doing that. I defined a function, passed in the variable in the function. But since, I put my try and except block into the function and input function outside of it. It throws and error. interest = int(input('Enter interest you want for the loan')) check_if_int_or_not(interest) Commented Apr 19, 2020 at 7:35
  • 1
    Is that surprising? The code that throws the error needs to be inside the try block. Commented Apr 19, 2020 at 7:36
  • I knew the code that throws error needed to be inside try/catch bloc. Just didn't knew how to put it there inside using a function. Looks like one can simply pass in the question and put int(input(question)) inside the try block code. Commented Apr 19, 2020 at 7:41

2 Answers 2

2

You could define a function which takes care of the validation process for you.
An example:

def get_input(question):
    """Read user input until it's not an integer and return it."""
    while True:
        try:
            return int(input(question))
        except ValueError: 
            print('The value you entered is not integer')


no_of_month = get_input('Enter no of months you want for payment: ')
interest = get_input('Enter interest you want for the loan: ')
principal_amt = get_input('Enter principal amount you want as loan:')
Sign up to request clarification or add additional context in comments.

2 Comments

Don't we have to write break after the return int(input(question)). Since its a while loop, why does the loop stop itself after a correct value is entered? Dont we have to explicitly write down break?
if no exception is raised when converting to float, then the return will succeed and give control back to the function caller
0

You are absolutely correct that it's most often a good idea to factor out common code, since this can lead to far less clutter in your code, making it much clearer and maintainable.

For example, the thing you probably want to aim for here is a situation where your input statements are no more complex than something like:

no_of_months = get_int("Enter no of months you want for payment: ")
interest = get_int("Enter interest you want for the loan: ")
principal_amount = get_int("Enter principal amount you want as loan: ")

Then you place all the complex logic (printing the prompt, getting the value, checking for errors and retrying if need be) inside that get_int() function so that it doesn't pollute your main code at all. By way of example, here's a minimalist function that does what you want:

def get_int(prompt):
    while True:
        try:
            input_val = input(prompt)
            return int(input_val)
        except ValueError:
            print(f"The value '{input_val}' is not a valid integer.\n")

The advantage of localising the code can be seen when you want to add extra features. This can often be done seamlessly by using default parameters, but still give more functionality if you decide to use it.

Consider, for example, a case where you want to ensure the entered values are within a specified range, such as if you decide loans should be between one month and three years inclusive, or the interest rate must be greater than 3%. A simple change to get_int() to do this would be:

def get_int(prompt, min_val = None, max_val = None):
    while True:
        # Get input, handle case where non-integer supplied.

        try:
            input_val = input(prompt)
            value = int(input_val)
        except ValueError:
            print(f"The value '{input_val}' is not a valid integer.\n")
            continue

        # If min or max supplied, use that for extra checks.

        if min_val is not None and min_val > value:
            print(f"The value {value} is too low (< {min_val}).\n")
            continue

        if max_val is not None and max_val < value:
            print(f"The value {value} is too high (> {max_val}).\n")
            continue

        # All checks passed, return the value.

        return value

no_of_months = get_int("Enter no of months you want for payment: ", 1, 36)
interest = get_int("Enter interest you want for the loan: ", 3)
principal_amount = get_int("Enter principal amount you want as loan: ")

You can see from the final line that the old parameters still work fine but, from the preceding two lines, you know have the ability to specify the range of values that are allowable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.