3
\$\begingroup\$

I have 3 different functions I have tried in my programs. I want a function which continues to loop until an integer is entered. Which would be the best to use? Or is there a better one?

def valid_int(question):
    """Creates a loop until an integer is entered"""
    py_version = find_version()
    if py_version == 3:
        response = input(question)
        while not response.isdigit():
            print("\nInvalid input! Input must be an integer")
            response = input(question)
        return int(response)
    else:
        response = raw_input(question)
        while not response.isdigit():
            print("\nInvalid input! Input must be an integer")
            response = raw_input(question)
        return int(response)

def valid_int(question):
    """Creates a loop until an integer is entered"""
    py_version = find_version()
    if py_version == 3:
        while True:
            response = input(question)
            try:
                return int(response)
            except ValueError:
                print("\nInvalid input! Input must be an integer")
    else:
        while True:
            response = raw_input(question)
            try:
                return int(response)
            except ValueError:
                print("\nInvalid input! Input must be an integer")

def valid_int(question):
    """Creates a loop until an integer is entered"""
    py_version = find_version()
    if py_version == 3:
        while True:
            response = input("Length of password: ")
            if response.isdigit()
                return int(response)
            print("\nInvalid input! Input must be an integer")
    else:
        while True:
            response = raw_input("Length of password: ")
            if response.isdigit()
                return int(response)
            print("\nInvalid input! Input must be an integer")
\$\endgroup\$
7
\$\begingroup\$

In Python, the standard approach is EAFP: it's Easier to Ask Forgiveness than Permission. So this:

response = raw_input(question)
try:
    return int(response)
except ValueError:
    print("\nInvalid input! Input must be an integer")

is definitely the way to go.

We can even go one step further. Regardless of which python version it is, we're running the same logic. The only difference is which input function to use. So let's just extract that logic outside of the loop so we don't have duplication of effort:

def valid_int(question):
    """Creates a loop until an integer is entered"""
    input_func = input if find_version() == 3 else raw_input

    while True:
        response = input_func(question)
        try:
            return int(response)
        except ValueError:
            print("\nInvalid input! Input must be an integer")
\$\endgroup\$
1
  • \$\begingroup\$ The second part to your answer really helps that can split my entire custom_functions module in half thank you. \$\endgroup\$ Dec 12 '15 at 18:13
1
\$\begingroup\$

Out of the examples you provided, I would say this one is the best practice:

def valid_int(question):
    """Creates a loop until an integer is entered"""
    py_version = find_version()
    if py_version == 3:
        while True:
            response = input(question)
            try:
                return int(response)
            except ValueError:
                print("\nInvalid input! Input must be an integer")
    else:
        while True:
            response = raw_input(question)
            try:
                return int(response)
            except ValueError:
                print("\nInvalid input! Input must be an integer")

But, I just wanted to make a point on these:

returning:

Triggering the inner return int lines, as well as the ValueError lines terminate the function, so the loop cannot be executed without returning.

Meaning the usage of else in these situations is entirely extraneous.

Additionally, when you encounter duplicate code like that, try and make it more dynamic and able to accept both conditions (As Barry's version shows)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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