How to distinguish negative numbers from input that is not a number

780 views Asked by At

I am trying to build a simple game and I would like Python to return a message when a player enters a negative number. My issue is that negative numbers are interpreted as strings when the player tries to enter them.

Here is my script:

while True:
    user_guess = input("Guess a number: ")
    if user_guess.isdigit():
        user_guess = int(user_guess)
        if user_guess < 0:
            print("Too low, guess a number between 0 and 10.")
        if user_guess > 10:
            print("Too high, guess a number between 0 and 10.")
    else:
        print("It is not a number.")
        break
5

There are 5 answers

1
rada-dev On
def input_number(message):
    while True:
        user_guess = input(message)
        try:
            n = int(user_guess)
            if n < 0:
                print("Too low, guess a number between 0 and 10.")
            elif n > 10:
                print("Too high, guess a number between 0 and 10.")
            else:
                return n
        except ValueError:
            print("It is not a number. Try again")
            continue


if __name__ == '__main__':
    number = input_number("Guess a number.")
    print("Your number", number)
0
kakben On

Edit: I will explain my code and why it solves your problem. The isdigit method you use will only check if the characters of a string consist of digits. The minus sign is not a digit, and so it returns False.

Instead, I try to convert the string to a number, and if python fails, I just loop again (continue) and ask for a new number. If the input is indeed a number, the lower part of the code checks for a valid interval. Only if the number is within the interval, the variable controlling the loop gets set, and the loop exits.

My code does not depend on isdigit, and therefore avoids your problem. Hope this helps and provides insight.

user_guess = None
while user_guess is None:
    inp = input("Guess a number: ")

    try:
        nr_inp = int(inp)
    except ValueError:
        print("It is not a number.")
        continue

    if nr_inp < 0:
        print("Too low, guess a number between 0 and 10.")
    elif nr_inp > 10:
        print("Too high, guess a number between 0 and 10.")
    else:
        user_guess = nr_inp

print("Done:", user_guess)
3
Adam Smith On

The code you have written is not wrong but it's not very idiomatic in Python and because of that you'll have to fight the language to add the "parse negative" functionality. Consider you could write something like:

user_guess = input("Guess a number: ")
if is_positive_or_negative_number(user_guess):
    user_guess = int(user_guess)
# continue as before

def is_positive_or_negative_number(s: str) -> bool:
    """Checks if a given string represents a positive or negative number"""
    if s.startswith('-'):
        s = s[1:]  # strip off the optional leading unary negation
    return s.isdigit()  # do not allow decimals, so no need to worry
                        # about allowing a "."

However it's easier if you just write idiomatic Python! Your code is written in a style affectionately termed LBYL (Look Before You Leap) code checks to make sure a thing can be done before doing it. Python prefers EAFP (Easier to Ask Forgiveness than Permission), which has you try to do a thing and catch the error if it's thrown.

The idiomatic code then just tries to cast the input to int and pays attention if it fails.

while True:
    user_guess = input("Guess a number: ")
    try:
        user_guess = int(user_guess)
    except ValueError:
        print("It is not a number.")
        break
    # if we get here, user_guess is guaranteed to be an int
    # and int(user_guess) knows how to parse positive and
    # negative numbers
    if user_guess < 0:
        print("Too low, guess a number between 0 and 10.")
    elif user_guess > 10:
        print("Too high, guess a number between 0 and 10.")
1
Ayoife On

The reason it's returning "It is not a number" for negative numbers is because user_guess.isdigit() treats negative numbers as strings (or non-digits).

Here's a code that could work as you expect:

while True:
    user_guess = input("Guess a number: ")
    try:
        user_guess = int(user_guess)
        if user_guess < 0:
            print("Too low, guess a number between 0 and 10.")
        if user_guess > 10:
            print("Too high, guess a number between 0 and 10.")
    except ValueError:
        print("It is not a number.")
        break

Since the int() function can recognize negative numbers, using try-except can help you catch the ValueError exception that is raised whenever you try to use the int() function on non-integers.

0
user3435121 On

The problem is with isdigit(). isdigit() will return False if minus sign. One solution is to ask int() to validate the user_guess.

while True:
  try:
    user_guess = int( input( "Guess a number: "))
  except ValueError:
    print( "It is not a number.")
    break # exit loop
  # validate user entry
  if user_guess < 0:
    print("Too low...")
    continue
  elif user_guess > 10:
    print("Too high...")
    continue
  # do processing
  ...