Napon Fire
Napon Fire

Reputation: 9

While loop and conditions

I'm trying to make a menu where the user must enter an integer between 1-200, otherwise, the program will loop until the condition is satisfied. Below is the current code I have but it does not work as entering any number between 2 and 99 won't work. Can anyone help?

if option == "1":
        Width = input("Enter rows (must be an integer between 1-200): ")
        while Width.isdigit() is False:
            Width = input("Enter rows(must be an integer): ")
        while Width < "1" or Width > "200":
            Width = input("Enter rows(must be between 1-200): ")
        Width = int(Width)

Upvotes: 0

Views: 98

Answers (4)

&#193;ngel Igualada
&#193;ngel Igualada

Reputation: 891

You can try doing that width be an integer always in order to make you easy the comparation. In this example i set width to -1 (int) as bad value to do the loop again

if option == "1":
        width = -1
        while  width < 1 or width>200:
            width = input("Enter rows (must be an integer between 1-200): ")
            if width.isdigit():
                width = int(width)
            else:
                width = -1

Upvotes: 0

goodvibration
goodvibration

Reputation: 6206

I'd go along with:

while True:
    userInput = input("Enter rows (must be an integer between 1-200): ")
    if userInput.isdigit() and 1 <= int(userInput) <= 200:
        break
width = int(userInput)

Upvotes: 0

watteri
watteri

Reputation: 1

Use int(input("input description")) and don't do greater-than or lower-than comparisons with strings. So something like this might work:

if option == "1":
        try:
            Width = int(input("Enter rows (must be an integer between 1-200): "))
            while int(Width) < 1 or int(Width) > 200:
                Width = input("Enter rows(must be between 1-200): ")
            Width = int(Width)
        except ValueError:
            Width = int(input("Enter rows (must be an integer between 1-200): "))

edit: somebody gave maybe a lot better answer while I was drafting this...

Upvotes: 0

Adam Smith
Adam Smith

Reputation: 54163

There are some subtle problems here, but the big one is that string compares don't work numerically. "3" > "200" for instance, and "1000000" < "9".

The subtler problem is that you're only checking isdigit once, then potentially prompting for input again afterwards. If I entered 9000000 at the first prompt, then \ at the second prompt, your code would crash with a TypeError when trying to call int(r'\')

You should instead do all your validation at once. The canonical idiom for this is:

while True:
    value = input("some prompt")
    if not some_validation_rule(value):
        print("Some error message")
        continue
    elif not some_other_validation_rule(value):
        print("A different error message")
        continue
    # etc, until
    break

This ensures that every validation case is handled differently, and you run each one every time you prompt for input. Once no validation case fails, you break out of the infinite loop.

That said, for this particular instance, you should prefer EAFP to LBYL, and just try to convert to int and catch the failure.

while True:
    rows = input("Enter rows (1-200): ")
    try:
        rows = int(rows)
    except TypeError:
        print("rows must be a number")
        continue

    if not 1 <= rows <= 200:
        print("rows must be between 1 and 200")
        continue

    break

Upvotes: 2

Related Questions