Search code examples
pythonpython-3.xwhile-loopvalueerror

While true loop to check for numbers within range, and also ValueError check?


What I'm trying to do is check to see if inputSeconds is within the range of 0 - 83699, while also checking to see if the user is using integers (with a ValueError check).

I've tried a lot of different iterations of this same code, moving things around... I'm still really new to Python and I've been stuck on this for a long time, any help is appreciated. ♡

Here's the section of code I'm struggling with:

while True:
    try:
        inputSeconds = int(input("♡ Seconds: "))
        break
    except ValueError:
        print("Please enter a valid integer.")
    else:
        if 0 <= inputSeconds <= 86399:
            break
        else:
            print("Please enter a value between 0 and 86399.")

The ValueError check works fine, but the range check is ignored; the code will just carry on and calculate whatever number is thrown in there. Thank you for taking the time to look at my code ♡


Solution

  • As you probably know, the break keyword exits from the current loop. That means you should only write it at a point in your code where the loop has achieved what you wanted it to.

    In this loop, you want to get a number from the user between 0 and 86399, so you should not break until you definitely have a number in that range. When reading and writing code, it is helpful to think about what is "known" at each stage in the code: I have commented the code below to say what is "known" at each stage.

    while True:
        try:
            # at this line, we know nothing
            inputSeconds = int(input("♡ Seconds: "))
            # at this line, we know that int worked, so inputSeconds is a number.
            break
        except ValueError:
            # at this line, we know that int didn't work, so we don't have a number.
            print("Please enter a valid integer.")
        else:
            # this line will never be reached, because of the break at the end of
            # the try block.
            if 0 <= inputSeconds <= 86399:
                break
            else:
                print("Please enter a value between 0 and 86399.")
    
    # at this line, the loop stopped because of the break statement in the try block,
    # so we know what we knew before that break statement: inputSeconds is a number.
    

    Your break statement occurs at a point in the code where we know that inputSeconds is a number. But logically, that is not sufficient to stop the loop, because the purpose of the loop is to make sure inputSeconds is a number and that it is in range. So we shouldn't break at that point. Here is the fixed code, annotated with what we know at each stage:

    while True:
        try:
            # at this line, we know nothing
            inputSeconds = int(input("♡ Seconds: "))
            # at this line, we know that int worked, so inputSeconds is a number.
        except ValueError:
            # at this line, we know that int didn't work, so we don't have a number.
            print("Please enter a valid integer.")
        else:
            # this line is reached when the try block finishes, so we know the same
            # thing we knew at the end of the try block: inputSeconds is a number.
            if 0 <= inputSeconds <= 86399:
                # now we know that inputSeconds is a number and it is within range.
                break
            else:
                # now we know that inputSeconds is a number and it is not within range.
                print("Please enter a value between 0 and 86399.")
    
    # at this line, the loop stopped because of the break statement in the else block,
    # so we know what we knew before that break statement: inputSeconds is a number
    # and it is within range.
    

    Notice also how the print statements occur at the stages in the code where we know what is wrong: we print "Please enter a valid integer" when we know that what the user entered wasn't an integer, and we print "Please enter a value between 0 and 86399" when we know that the user entered a number that is not within range. So this way of thinking about code is useful for writing correct code, not just when it comes to loops and break statements.