0
\$\begingroup\$

The function validates whether the input is an int, is there a way to make this more concise and is it best practise to use the try/except or just if/else? I then want to create a similar function for checking whether the input contains letters only using isalpha()

def int_validation(prompt):
    """
    Validate the given input is a positive number
    """

    while True:
        answer = input(prompt)
        if not answer:
            print(blank_input)
        else:
            try:
                answer = int(answer)
            except ValueError:
                print(positive_int_only)
                continue
            if answer < 1:
                print(positive_int_only)
            break
    return answer
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

First, I would suggest that when posting code for review that it be a complete. For example, variables blank_input and positive_int_only are undefined. Moving on:

Your while True loops suggests that you want to repeatedly prompt the user for a positive number until a valid positive number is entered and then return its value. You do repeatedly loop when the user enters an empty string or a string that cannot be parsed as a number (but not necessarily an integer) but not if a non-positive number is entered. In this case you return the invalid non-positive input. That is an inconsistency and I will assume that this was an oversight on your part. But right now your docstring states that the purpose of the function is to validate that an input is a positive integer. What the function is actually doing is accepting input from a user until a valid positive integer is entered and returning that value.

def int_validation(prompt):
    """
    Prompt the user for input until a positive integer
    is entered.
    """

    while True:
        answer = input(prompt)
        # No need to distinguish between blank input vs,
        # an invalid number:
        try:
            int_answer = int(answer)
        except ValueError:
            pass
        else:
            if int_answer >= 1:
                return int_answer
        print('You must enter a positive integer.')

print(int_validation('Enter a positive integer: '))

This will accept input such as 1e2 as valid. If you want to reject this as valid input then you need to ensure the input string contains only numeric digits.

So if you require that the input be strictly composed of only digits, my preference would be to use a regular expression for validation:

import re

def int_validation(prompt):
    """
    Prompt the user for input until a positive integer
    is entered.
    """

    while True:
        answer = input(prompt).strip()
        # Allow leading zeroes, but they must be followed by a non-zero:
        if re.fullmatch(r'0*[1-9][0-9]*', answer):
            return int(answer)
        print('You must enter a positive integer.')

print(int_validation('Enter a positive integer: '))

You might consider defining a default value form the prompt argument if it is not supplied.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I like the """number""" vs int() distinction. // "possible for the user to enter, for example, 1.23 and your code will accept that and return a 1." I don't understand that, as int("1.23") raises ValueError: invalid literal. // Your proposed regex won't let me enter 1_000_000 for a million. In many cases it's sensible to let the high-level code define "error" identically to how the low-level (int()) library defines it. That is, propagate errors without trying any fancy second guessing of whether it seems likely that an input shall provoke an error. EAFP / LBYL. \$\endgroup\$
    – J_H
    Aug 7, 2023 at 15:37
  • \$\begingroup\$ @J_H You are correct about int("1.23") and I have updated my answer accordingly (I must have had a brain malfunction). As far as accepting 1_000_000, that notation has meaning within a Python program and, yes, it will be a valid argument to the int constrictor -- and that is the problem and why I prefer the regex solution: To an end-user this notation is not standard nor natural and is only readily supported in Python programs using the int constructor. But if OP needs to rewrite this in code in, for example, PHP, now extra code is needed to support the unnatural syntax. \$\endgroup\$
    – Booboo
    Aug 7, 2023 at 16:21

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.