Number guessing game, unable to take the next guess - python

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

Related

How do I make two functions share a variable?

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)

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

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)

how to add an error message when an integer is input instead of a string

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.

How to fix guessing game

The objective is to create a simple program that generates a number between 1 and 100, it will then ask the user to guess this, if they guess outside of the number range it should tell them to guess again, if not it should tell them whether their guess was too high or too low, prompting them to guess again. Once they do guess the correct number it should tell them they've won and the number of tries it took for them to guess it correctly.
Here is what I have so far
import random
def play_game():
number = random.randint(1, 100)
print("Guess a number between 1 and 100 inclusive.")
count = 1
while True:
guess = int(input("Your guess: "))
if guess > 0 and guess <= 100:
#the age is valid
return play_game
else:
print("Invalid number.")
return play_game()
if guess < number:
print("Too low.")
elif guess > number:
print("Too high.")
elif guess == number:
print("You won! You guessed it in " + str(count) + " tries.\n")
return
count+=1
play_game()
The issue I'm currently running into is when it checks to see if their guess was between 1-100 instead of moving on to weather or not their number was too how or to low, it stays and loops.
If anyone could help me with this issue and review the code in general I'd appreciate it.
I think the problem is with some indentation and some logical problems in the flow.
When you call play_game() from inside the game, it starts a completely different game
with different random_number.
A good code that satisfies your condition might look like the following
import random
def play_game():
number = random.randint(1, 100)
print("Guess a number between 1 and 100 inclusive.")
count = 1
while True:
guess = int(input("Your guess: "))
if guess > 0 and guess <= 100:
if guess < number:
print("Too low.")
elif guess > number:
print("Too high.")
elif guess == number:
print("You won! You guessed it in " + str(count) + " tries.\n")
return
count+=1
else:
print("Invalid number.")
play_game()
You could re-adjust your code:
1. if no. within range, run your high, low, match checks
2. break if guess matches the no
import random
def play_game():
number = random.randint(1, 100)
print("Guess a number between 1 and 100 inclusive.")
count = 0
while True:
count += 1
guess = int(input("Your guess: "))
if guess > 0 and guess <= 100:
#the age is valid
if guess < number:
print("Too low.")
elif guess > number:
print("Too high.")
elif guess == number:
print("You won! You guessed it in " + str(count) + " tries.\n")
break
else:
print("Invalid number, try again")
play_game()
The issue you are running into is because of incorrect indentation. The if-else statements that check whether the number is within the valid range are at the same indentation level as the while loop and thus are not executed within it. Simply indenting should fix the problem.
Furthermore, you have called play_game without parenthesis, making it incorrect syntax for a function call. However, rather than checking if the number is greater than 0 and lesser than 100, it would more optimal to check whether number is lesser than 0 or greater than 100, and if that is the case, print invalid number and call play_game().
It would look something like this:
while True:
if guess < 0 and guess > 100:
print ("Invalid number.")
return play_game()
The rest of your code looks good. I've also attached the link on the section of indentations of the Python documentation here.

Python: why is my print statement not running for my else?

import random
number = random.randint(0,10)
#print (number)
guess = int(input("I'm thinking of a number between 1 and 10. \nPlease guess what it is: "))
#print(guess)
while guess != number:
if guess > number:
print("That is too high!")
guess = int(input())
elif guess < number:
print("That is too low")
guess = int(input())
else:
print("Thats it! You win!")
I'm working out a few python coding examples and I am confused why my else statement isn't printing?
The code objective is to generate a random number, and then have the user input a guess and then depending if the guess is lower or higher than the random number for the computer to notify the user and if the user guess correctly, then to tell the user that they won.
I'm tested this out and when I input the correct number the code just ends and doesn't print out "That's it! You win!". Why is this and how can I get it to print it out?
Guess input prior to the loop will most times be different than the number to guess, therefore the loop will not enter.
You also have other more subtle bugs: for instance, input is taken twice in one loop, creating conditions for improper feedback. Further, your win is confirmed by default, that is if guess not too high, and if guess not too low, then it is a win; a positive assertion such as if guess equals number, is probably safer to declare a win.
Here is a design that segregates each actions in one place in the loop, minimizing the risks of a faulty logic.
import random
number = random.randint(0, 10)
guess = None
while guess != number:
guess = int(input())
if guess > number:
print("That is too high!")
elif guess < number:
print("That is too low")
elif guess == number:
print("Thats it! You win!")
else:
print('that was not supposed to happen')

Categories

Resources