DAK
DAK

Reputation: 116

Is one way of returning a user-input value, using a try-except clause, better than the other?

For context, I am new to Python, and somewhat new to programming in general. In CS50's "Little Professor" problem (details here, but not needed: https://cs50.harvard.edu/python/2022/psets/4/professor/) my program passes all correctness checks; but, unfortunately, programs aren't checked for efficiency, style or "cleanliness", making those details harder to learn... Therefore, using the function below as an example, I am trying to grasp how to think about choosing an implementation when there are multiple options.

In the code below, I have a function that prompts the user to input an int(). If the user inputs 1, 2 or 3, return that value. Otherwise, if the user does not input 1, 2 or 3, or the input is not even an int(), re-prompt the user.

The first includes the conditional within the try block, and breaks if the condition is met, returning the value once out of the loop.

def get_level():
    while True:
        try:
            level = int(input("Level: "))
            if 0 < level <= 3:
                break
        except ValueError:
            pass
    return level

In the second, once the input has met the int() condition, if the value is 1, 2 or 3, it breaks out of the loop by returning the value of level, similarly re-prompting if not. (Note: I noticed the below also works without the "else:" statement, which is a little confusing to me as well, why isn't it needed?)

def get_level():
    while True:
        try:
            level = int(input("Level: "))
        except ValueError:
            pass
        else:
            if 0 < level <= 3:
                return level

Is one of these examples better to use than the other, and if so, why? Any help is greatly appreciated, but if there is not a specific answer here, thoughts on the overall concept would be incredibly helpful as well!

Upvotes: 1

Views: 100

Answers (1)

Davis Herring
Davis Herring

Reputation: 39818

Generally, you should put as little code as possible inside a try, so that you don't misconstrue an unrelated error as the one you're expecting. It also makes sense to separate the code that obtains the level from the code that acts on it, so that level has known validity for as much code as possible. Both of these points favor the second approach (the second moreso in a larger example), although in this case you could also write it as

def get_level():
    while True:
        try:
            level = int(input("Level: "))
        except ValueError:
            continue
        if 0 < level <= 3:
            return level

which avoids the else indentation. (You do need that else as given, since otherwise if the first input attempt doesn't parse you'll read level before assigning to it.)

Meanwhile, the question of break vs. return is really just one of style or conceptualization: do you see the value being in the desired range as meaning "we should stop asking" (break) or "we have the answer" (return)?

Upvotes: 1

Related Questions