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
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.")
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.
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
...
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)
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)
Related
My assignment is to make a secret number, which is 26, and make a guessing game saying the guess is either "too low" or "too high". I made two functions, int_guess for if the input is an integer and not_int_guess for when the input is not an integer. The problem that i have though is when im counting the amount of guesses, i dont know how to make both functions share a count of how many guesses they inputted.
print("Guess the secret number! Hint: it's an integer between 1 and 100...")
secret_num = 26
guess = int(input("What is your guess? "))
def int_guess(guess):
count = 0
while guess != 26:
if guess > secret_num:
print("Too high!")
guess = int(input("What is your guess? "))
count += 1
elif guess < secret_num:
print("Too low!")
guess = int(input("What is your guess? "))
count += 1
else:
print("You guessed it! It took you", count, "guesses.")
def not_int_guess(guess,count):
print("Bad input! Try again: ")
guess = int(input("What is your guess? "))
while guess != 26:
if guess > secret_num:
print("Too high!")
guess = int(input("What is your guess? "))
elif guess < secret_num:
print("Too low!")
guess = int(input("What is your guess? "))
else:
print("You guessed it! It took you", count, "guesses.")
try:
int_guess(guess)
except:
not_int_guess(guess,count)
One part of the assignment that i need to have is a try and except, the problem is that the count will reset to zero if the except is used, but i need the count to carry over to the exception case. I tried carrying the "count" variable over to the not_int_guess by placing it like not_int_guess(guess,count) but that doesnt work for a reason i dont understand.
Instead of using two functions, use the try and except within the while loop. That way everything is much neater and more efficient (also good to define functions before any main code):
def int_guess(secret_num):
count = 0
guess = 0 #Just defining it here so everything in the function knows about it
while guess != secret_num:
try:
guess = int(input("What is your guess? "))
except ValueError as err:
print("Not a number! Error:", err)
continue #This will make the program skip anything underneath here!
if guess > secret_num:
print("Too high!")
elif guess < secret_num:
print("Too low!")
count += 1 #Adds to count
#This will run after the while loop finishes:
print("You guessed it! It took you", count, "guesses.")
#Main code:
print("Guess the secret number! Hint: it's an integer between 1 and 100...")
int_guess(26)
Like this, the function will run until the user has guessed the number no matter what they input, while also keeping count through any errors
You can use the count variable outside the functions to use it in both the variables globally.
I have also made some changes to the code to make it work properly
print("Guess the secret number! Hint: it's an integer between 1 and 100...")
secret_num = 26
count = 0
guess = 0
def int_guess(guess):
count = 0
while guess != 26:
guess = int(input("What is your guess? "))
if guess > secret_num:
print("Too high!")
count += 1
elif guess < secret_num:
print("Too low!")
count += 1
else:
print("You guessed it! It took you", count, "guesses.")
def not_int_guess(guess):
print("Bad input! Try again: ")
int_guess(guess)
try:
int_guess(guess)
except:
not_int_guess(guess)
I am trying to add an error when a string is entered instead of an integer. I've looked at other similar posts but when I try and implement it into my code it keeps spitting errors out. I have a number guessing game between 1 and 50 here. Can't for the life of me figure out what's wrong.
import random
number = random.randrange(1, 50)
while True:
try:
guess = int ( input("Guess a number between 1 and 50: ") )
break
except ValueError:
print("Please input a number.")**
while guess != number:
if guess < number:
print ("You need to guess higher. Try again.")
guess = int ( input("\nGuess a number between 1 and 50: ") )
else:
print ("You need to guess lower. Try again.")
guess = int ( input("\nGuess a number between 1 and 50: "))
print ("You guessed the number correctly!")
Note that you're asking three times for the exact same input. There is really no need for that and no need for two loops at all. Just set the guess to a default value that will never be equal to the number (None) and use one single input, wrapped with try/except:
import random
number = random.randrange(1, 50)
guess = None
while guess != number:
try:
guess = int(input("Guess a number between 1 and 50: "))
except ValueError:
print("Please input a number.")
else:
if guess < number:
print("You need to guess higher. Try again.")
elif guess > number:
print("You need to guess lower. Try again.")
print("You guessed the number correctly!")
You could try running a while loop for the input statements. Checking if the input(in string format) is numeric and then casting it to int.
Sample code:
a = input()
while not a.isnumeric():
a = input('Enter a valid integer')
a = int(a)
The code executes until the value of a is an int
your code did not work because the indentation is not right
import random
number = random.randrange(1, 50)
while True:
try:
guess = int ( input("Guess a number between 1 and 50: ") ) # here
break # here
except ValueError: # here
print("Please input a number.")
while guess != number:
if guess < number:
print ("You need to guess higher. Try again.")
guess = int ( input("\nGuess a number between 1 and 50: ") )
else:
print ("You need to guess lower. Try again.")
guess = int ( input("\nGuess a number between 1 and 50: "))
print ("You guessed the number correctly!")
Output
Guess a number between 1 and 50: aa
Please input a number.
Guess a number between 1 and 50: 4
You need to guess higher. Try again.
Newbie here. I'm using the variable number_guessed to store the guessed number and the correct number is 9. I want whoever's playing the game to only enter integers and I understand the variable stores string. Line 3 creates an error ValueError: invalid literal for int() with base 10: 'e'. I understand why this is and would appreciate some help with an interactive way to go about this problem. By the way, I'm using Python 3 and here's my code.
number_guessed = input('Guess a number between 0 and 10? ')
guess_count = 1
if type(int(number_guessed)) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
while int(number_guessed) != 9:
number_guessed = input('Try Again! Guess a number between 0 and 10? ')
if type(int(number_guessed)) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
guess_count += 1
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
exit()
if guess_count == 3:
msg = f"""
You're out of Luck!
It was 9 by the way
"""
print(msg)
Please save my soul. Would be very much appreciated.
Your problem is that int() will try to convert whatever is passed to it to an integer, which fails when it isn't a value that can be converted to an integer, resulting in the ValueError exception being thrown.
A solution is to 'catch' that exception like this:
number_guessed = input('Guess a number between 0 and 10? ')
try:
# try to convert it to an actual integer instead of a string
number_guessed = int(number_guessed)
except ValueError:
print('Whole numbers only!')
What doesn't work is to try and check the type of what was entered, that will always be a string, since you enter the number as text (that's the problem you're trying to solve), so some of the suggested solutions checking the type of the input won't work.
You cannot use int on a string. To fix this problem, you can do:
if type(number_guessed) is int:
print('Whole numbers only!')
Something like this might work. If a string is passed, it should use the strings length as a guess. In general, it’s more convenient to use the isinstance method, which is a built in function. Hope this is helpful :)
the_num = 9
guess = 0
guess_count = 0
while guess != the_num:
if guess_count >= 3:
print(“oh no!”)
break
guess = input(“guess a number in [0,10] “)
if isinstance(guess, int):
if guess == the_num:
print(“yay!”)
break
if guess != the_num:
guess_count += 1
elif isinstance(guess, str):
if len(guess) == the_num:
print(“yay”)
break
if len(guess) != the_num:
guess_count += 1
else:
guess_count += 1
My apology also for making edit, I’m not very efficient with the iOS app 🤷♂️
your logic is correct but you are casting your input to ing before the comparisson.
if type(int(number_guessed)) != int:
instead, you should try casting your raw input to int before comparing the number. You can do it by replacing the above line with
try:
number_guessed = int(number_guessed)
except:
pass
if type(number_guessed) != int:
...
this code will first try to convert your input to an int in the try block. If it is successful, your variable will be treated as an int later in the code thus redirecting the user to the if clause.
If the cast fails, then the code inside the except block will run. The pass keyword in the except clause tells your application to ignore what happened in the try clause thus your number_guessed will remain a string, redirecting the user to the else clause.
Another note - try to DRY your code up a bit. you are repeating
the same logic in two places - initial guess (lines 3-7) and
subsequent guesses (lines 10-14). try to restructure your code to
extract the key functionalities into separate functions.
Working code:
number_guessed = input('Guess a number between 0 and 10? ')
guess_count = 1
try:
number_guessed = int(number_guessed)
except:
pass
if type(number_guessed) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
while int(number_guessed) != 9:
number_guessed = input('Try Again! Guess a number between 0 and 10? ')
try:
number_guessed = int(number_guessed)
except:
pass
if type(number_guessed) != int: # restricting input to integers: start
print('Whole numbers only!')
number_guessed = input('Guess a number between 0 and 10? ') # restricting input to integers: end
guess_count += 1
if int(number_guessed) == 9:
print("Correct. That's some good luck right there:)")
exit()
if guess_count == 3:
msg = f"""
You're out of Luck!
It was 9 by the way
"""
print(msg)
Here is the concept of my game, the computer randomly generates a number from 1-100 and the player has to guess that number. If the number they guess is higher or lower the computer tells them so.
I added some code to make sure that the guess that the user enters is a number, but for some reason, it only works for their first guess.
import random
x = random.randint(1, 100)
guess = input("Guess the number")
while guess.isnumeric() == True:
if x > int(guess):
print("Too low, guess again")
guess = input("Guess the number")
if x < int(guess):
print("Too high, guess again")
guess = input("Guess the number")
if x == int(guess):
print ("That is correct!")
break
if guess.isnumeric() == False:
print("Please enter a valid number")
guess = input("Guess the number")
I don't really know how to else to explain it. But for example, if I guess the number 20 as my first guess, it would output too high or too low depending on the randomly generated number, but after that, if I input a bunch of random letters it would give me an error that the guess could not be compared to the randomly generated number.
I've fixed your code for you. Try this:
import random
x = random.randint(1, 100)
while True:
try:
guess = int(raw_input("Guess the number: "))
except ValueError:
print("Not a valid number, try again!")
continue
if guess < x:
print("Too low, guess again")
elif guess > x:
print("Too high, guess again")
elif x == guess:
print ("That is correct!")
break
You don't need to prompt the user for input after every guess, that's what the first input prompt is for. Because we are specifying while True, the user will get prompted to input a number every single time unless they enter the correct number, which in that case, we break the infinite loop.
Additionally, we can put the input statement in a try block, because we are casting the input as an integer right there. If the user enters a string, the program would otherwise fail if it tried to cast it as an integer, but if we except ValueError: and then continue, we will alert the user that their input is invalid, and then prompt them for input once again.
Your if statements are all independent:
if x > int(guess):
print("Too low, guess again")
guess = input("Guess the number")
if x < int(guess):
print("Too high, guess again")
guess = input("Guess the number")
if x == int(guess):
print ("That is correct!")
break
The second and third if statements will always test guess again, even if the first if test matched. And if the first if test matched and you entered a non-numeric guess value, those two tests will fail as the int() call will throw a ValueError exception.
You could tell Python that the tests are interdependent by using elif and else; now Python will only execute the first matching block, and skip the others entirely:
if x > int(guess):
print("Too low, guess again")
guess = input("Guess the number")
elif x < int(guess):
print("Too high, guess again")
guess = input("Guess the number")
else:
print ("That is correct!")
break
This means that execution continuous after the else block when either the if or elif tests matched.
Note that I used else at the end; if the number is neither too high nor too low, the number must be equal, there is no other option. There is no need to test for that explicitly.
You are now repeating yourself however. You are asking for a guess in 3 different places. You could ask once and let the loop take care of asking for a new value:
while True:
while True:
guess = input("Guess the number:")
if guess.isnumeric():
break
print("Not a valid number, try again!")
guess = int(guess)
if x > guess:
print("Too low, guess again")
elif x < guess:
print("Too high, guess again")
else:
print ("That is correct!")
break
That's a lot less repetition already; a separate while loop asks for a number until it is actually numeric, and guess is converted to int() just once.
You could remove that nested while True: and just use the outer one here, the result would be the same, provided you use the continue keyword to skip the rest of the loop when you don't have a numeric value:
while True:
guess = input("Guess the number:")
if not guess.isnumeric():
print("Not a valid number, try again!")
continue # skip to the top of the loop again, so ask again
guess = int(guess)
if x > guess:
print("Too low, guess again")
elif x < guess:
print("Too high, guess again")
else:
print ("That is correct!")
break
You need to surround your guessing logic in another loop that continues until the guess is correct.
pseudocode:
choose_target_answer
while player_has_not_guessed_answer
get_player_guess
if player_guess_is_valid
respond_to_player_guess
else
give_error_message
I want to add code so that if the user enters anything other than an integer, it prints something out. On the last line where I wrote
if guess != int I want the program to decide if the guess is anything other than a number.
import random
number = random.randint(1,100)
guess = 0
guesses = 0
while guess != number:
guess = int(input("Guess my number between 1 and 100(inclusive):"))
guesses = guesses + 1
if guess == number:
print("Well done! My number is:"number,"You had",guesses,"guesses"
elif guess < number:
print ('sorry, my number is higher')
elif guess > number:
print ('Sorry, My number is lower')
if guess != int:
print ("Enter a Number!!")
Let's use good old EAFP
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.
guess = input("Guess my number between 1 and 100(inclusive):")
try:
guess = int(guess)
except ValueError:
print ("Enter a Number!!")
else:
if guess == number:
print("Well done! My number is:"number,"You had",guesses,"guesses"
elif guess < number :`
print ('sorry, my number is higher')
else:
print ('Sorry, My number is lower')
After I was kindly warned about raw input always being a string. Perhaps this is what you need
guess =int(input("Guess my number between 1 and 100(inclusive):"))
guesses = guesses + 1
try:
guess = int(guess)
if guess == number:
print("Well done! My number is:", number,"You had",guesses,"guesses")
elif guess < number :
print ('sorry, my number is higher')
elif guess > number:
print ('Sorry, My number is lower')
except:
print("Enter a number!")
Do notice that you don't use guesses anywhere, and that this isn't a loop so it will repeat itself only once and that also you never defined what your number is. Perhaps a more complete example would be this:
guesses = 0
number = 10
while True:
try:
guess =int(input("Guess my number between 1 and 100(inclusive):"))
except:
print("Enter a number!")
continue
guesses = guesses + 1
if guess == number:
print("Well done! My number is:", number,"You had",guesses,"guesses")
break
elif guess < number :
print ('sorry, my number is higher')
elif guess > number:
print ('Sorry, My number is lower')
I like #Nsh's answer - it's more common and probably better in practice. But if you don't like using try-catch statement and a fan of sql...
import random
my_number = random.randint(1,100)
your_number = None
counter = 0
While your_number != my_number:
s = input("Guess my number between 1 and 100(inclusive):")
counter += 1
if all(i in '0123456789' for i in s):
your_number = int(s)
if my_number == your_number: print 'Well done!'
else: print 'sorry, my number is {}'.format('higher' if my_number > your_number else 'lower')
Enjoy.