Why does my inner loop never finish in my number guessing game? - python

When I try to guess the randomly generated number, the correct guess is never correct, and therefore the inner loop never finishes. I have tried debugging with print statements.
from random import randint
print('Welcome to the Number Guessing Game (Numbers 1 - 1000).')
while True:
tries = 0
random_num = randint(1, 10)
print(random_num)
guess = input('guess my number, human: ')
while random_num is not guess:
guess = input('Try again: ')
print(guess)
tries += 1
print('Correct!' + ' It took you' + str(tries) + ' tries.')

First of all, you have to convert the guess variable to an integer. Input simply returns strings and a string can't be equal to an integer.
The second problem with your programme is that is and is not keywords check, whether two "variables" (in Python, variables are just references to an object) are/aren't pointing to the same object.
This might not be your case even if your guess was correct (even though they can have the same value they are different objects). Sometimes this is not a problem since Python will point both "variables" to the same object for efficiency. But you can't be sure, can you!
Check this: Why does comparing strings in Python using either '==' or 'is' sometimes produce a different result?
Anyways, it's better to use the == and != operator in similar cases and the second problem will disappear.

Type error...
Add more debug code for the answer
print('random_num',random_num, type(random_num))
print('guess', guess, type(guess))
Output
Welcome to the Number Guessing Game (Numbers 1 - 1000).
random_num 2 <class 'int'>
guess my number, human: 2
guess 2 <class 'str'>
Fix:
while random_num is not int(guess):

Related

Python: Cows and Bulls game

I am writing a code fora game which randomly generates a 4-digit number. Ask the user to guess a 4-digit number. For every digit that the user guessed correctly
in the correct place, they have a “cow”. For every digit the user guessed correctly in the wrong place is a “bull.” Every time the user makes a guess, tell them how many “cows” and “bulls” they have. Once the user guesses the correct number, the game is over. Keep track of the number of guesses the user makes throughout the game and tell the user at the end.
The code is below.
import random
rand=[random.randint(0,9) for n in range(3)]
user_guess=[input("Please guess 4-digit number: ")]
def game():
count=0
while True:
guess=[i for i in rand]
listnum=[i for i in user_guess]
if guess == listnum:
print("You won.")
print("It took you "+str(count)+" guess.")
break
if guess != listnum:
cow=0
bull=0
count+=1
for x in range(0,3):
if guess[x]==listnum[x]:
cow+=1
if len(set(guess)&set(listnum))>num:
bull=len(set(guess)&set(listnum)) - cow
print("Cows: "+str(cow)+' Bulls: '+str(bull))
game()
But I am getting the following error after it asks the user to guess the number and takes the input. The error is given below.
Please guess 4-digit number: 1234
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-48-64a0b0d4d766> in <module>()
41 print("Cows: "+str(cow)+' Bulls: '+str(bull))
42
---> 43 game()
44
45
<ipython-input-48-64a0b0d4d766> in game()
33 count+=1
34 for x in range(0,3):
---> 35 if guess[x]==listnum[x]:
36 cow+=1
37
IndexError: list index out of range
What mistake am I making here?
So it's basically a variant of Mastermind, eh? Anyway, for user_guess, you have brackets around the entire return of input. Since input is a string, then this gives you back a list with just one item. For example, if the user enters 1234, then user_guess becomes the list ['1234'], not ['1', '2', '3', '4']. This means listnum=[i for i in user_guess] just gives you back [1234] (a list with one element, which is the number one thousand, two hundred thirty-four), not [1,2,3,4]. So try removing the brackets you have around input.
Also, you should change your creation of listnum to listnum=[int(i) for i in user_guess], since you're ultimately trying to compare integers, not strings.
Some other things I noticed:
You tell users to use a 4-digit number. So you should be using range(4)
You ask the user to guess only once. You should have the input statement in your function.
Your counter for the number of guesses is off by one. Try putting the count += 1 right after the while True.
The guess=[i for i in rand] seems redundant. You could just use the list rand here. Also, it seems counter-intuitive to call the secret answer "guess".
In fact, since you have everything as a function, there's no need for a while loop. You can just call the game() function again after a wrong guess, and use return when the user finally wins.
For the bull count, you use a variable called num, but I don't see this defined anywhere. Shouldn't this just be 8? Also, consider the case where the bull count should be 4, or the secret answer is something like '1233': should a guess of '3354' give you two bulls?
And a grammatical point: the answer you print says "It took you [however many] guess", not "guesses" if the number of guesses is more than one.
Your definition of when a digit is a bull is a little bit unclear. Let's say your solution key is e.g. [1, 8, 5, 8] and your guess 8888. The number 8 is present multiple times in the solution key. So you have 2 cows. But what is your expected output for bulls in this case? One possible solution (see below) would be to check if each guessed number is present anywhere in the solution key (even though it might already be a cow).
The solution below includes some of the remarks already mentioned by others (see post by #Bill M.).
Possible solution:
import random
def game(num_digits):
# generate list of random integers of length num_digits
listnum = [random.randint(0,9) for n in range(num_digits)]
print("Solution key = " + str(listnum))
count=0
while True:
count+=1
print("~~~ Guess: " + str(count) + " ~~~")
print("Please guess " + str(num_digits) + "-digit number: ")
# transform input string (e.g. "1234") to list of integers (e.g. [1,2,3,4])
guess = [int(i) for i in str(input())]
if guess == listnum:
print("You won.")
print("It took you "+str(count)+" guess(es).")
break
else:
cow=0
bull=0
for x in range(0,num_digits):
if guess[x]==listnum[x]:
cow += 1
elif guess[x] in listnum: # look if digit is somewhere else in the solution key (might already be a cow)
bull += 1
print("Cows: "+str(cow)+" Bulls: "+str(bull))
print("++++++++++++++++")
game(4)
Example output:
Solution key = [1, 8, 5, 8]
~~~ Guess: 1 ~~~
Please guess 4-digit number:
2288
Cows: 1 Bulls: 1
++++++++++++++++
~~~ Guess: 2 ~~~
Please guess 4-digit number:
8888
Cows: 2 Bulls: 2
++++++++++++++++
~~~ Guess: 3 ~~~
Please guess 4-digit number:
1858
You won.
It took you 3 guess(es).
define input as string not as one elemented list with one string in it
user_guess=input("Please guess 4-digit number: ")
then split the list using a seperator
listnum= user_guess.split(',')
https://www.tutorialspoint.com/python/string_split.htm
plus num is undefined in
if len(set(guess)&set(listnum))>num:
Remove the square-brackets from this line user_guess=[input("Please guess 4-digit number: ")], as is creating a list with one entry, the user string input. which is probably related to IndexError as there is only one entry in the list, e.g. ['1234'].
Another fix is convert the user string input into a list of integers, before the while-loop:
user_guess = input("Please guess 4-digit number: ")
def game():
count=0
listnum = [int(num) for num in user_guess]
# or use `map`
# listnum = list(map(int, user_guess))
The infinite-loop that happens after that is a different problem.

Why can't I compare an input to a random number in Python

So I basically wanna compare "Number" and "Guess" in the if statement, but no matter what it says they don't match (I get the else response, not included here). Even if I copy the random number they don't match.
Thanks in advance!
import time
def the_start():
points = 0
attempt = 1
print("Attempt:",attempt)
print("Your goal is to guess a number between 1 and 10 - Points:",points)
time.sleep(2)
attempt = attempt + 1
number = random.randint(0,10)
print(number)
guess = input("What is your guess? :")
time.sleep(2)
if guess == number:
points = points + 1
print("OMG YOU WERE RIGHT! Here, have some fake cheers! *cheer*")
time.sleep(5)
guess is a string. You need to do conversion of the string and handle error conditions. int() will convert a string to an integer, but it will throw an exception if the string is not purely numbers.

Creating a small program in python

I'm trying to make a program in Python 3.5 that asks the user to enter a number from 1 to 9. The the program will also guess a number from 1 to 9. If the user guesses the same number correctly, then the program will print Correct . Otherwise, the program will print Wrong. I wrote a program. Everything went fine with my code. However, when I guessed a number correctly, the program suddenly wrote Wrong instead of Correct. What am I doing wrong?
Here is my code:
print('Enter a number from 1 to 9')
x = int(input('Enter a number: '))
import random
random = print(random.randint(1,9))
if int(x) != random:
print ('Wrong')
else:
print ('Correct')
You are saving the result of a print() call (and masking random). print() returns None, so it will always be unequal to an integer, and therefore always "wrong."
import random
print('Enter a number from 1 to 9')
x = int(input('Enter a number: '))
r = random.randint(1,9)
if x != r:
print('Wrong')
else:
print('Correct')
Also note that I've moved the import statement to the top, avoided a second int() cast on something you've already done that to, and removed the space between the print reference and its arguments.
Here is the mistake,
random = print(random.randint(1,9))
You need to do something like this.
random = random.randint(1,9)
print(random)
Also, you have already converted the input to int so, you can do just this.
if x != random:
As pointed out your mistake is the line
random = print(random.randint(1,9))
But why?
functions (like print() take something, do something (with it) and give something back.
Example:
sum(3,4) takes 3 and 4, may add them and returns 7.
print("Hello World") on the other hand takes "Hello world", prints it on the screen but has nothing useful to give back, and therefore returns None (Pythons way to say "nothing").
You then assign None to the name random and test if it equals your number, which it (of course) doesn't.

Can someone tell me why this wont loop?

I'm making a number guessing game and can someone tell me why it wont work properly?
import random
import time
time.time()
count=0
a = random.randint(0,100)
b = int(input("What number will you guess?"))
while b != a:
if b > a:
print("TOO BIG")
count = count + 1
elif b < a:
print("TOO SMALL")
count = count + 1
else b == a:
print("YOU WIN")
count = count + 1
time=time.time()
print("You took",count,"tries")
print("It took you",time,"second")
The reason this isn't working properly is because you're calling b = input outside of your while loop. As it stands, the user will be asked a single time what their guess is, then the loop will just move infinitely, because b is never being modified.
This loop will accomplish more what you want:
a = random.randint(0,100)
b = -1
while b != a:
b = int(input("What number will you guess?"))
A few notes, though:
Firstly, as Lee Daniel Crocker points out, the user will actually never see "YOU WIN", because you've structured your if-elif-else statement incorrectly. else by definition cannot have a condition - it exists purely in exclusion to all other conditionals in the same block. Additionally, your else statement is the opposite of your while condition. When that else becomes true, the loop exits. You'll need to handle printing "YOU WIN" somewhere else.
Second, you're not validating the user's input in any way - if they enter 'a', the program will crash, because you can't cast 'a' to an int. Either add an exception handler (for ValueError) or using isdigit() on the string, then casting it.
Third, you're not using time.time() correctly - you need to subtract the time at which the user wins from the time at which they started, then represent that value, which is in seconds, in some meaningful way. As it stands you're telling each player that they took the number of seconds since the beginning of the UNIX epoch to complete the game.
Also, for usability reasons, you should probably provide the user some way to break out - a string like "QUIT" - because as it stands, the only way to restart/quit is to either close the application or KeyboardInterrupt.
You need to accept input in the loop. Move the line b = int(input("What number will you guess?")) within the loop.

python while loop unexpected behavior

I'm relatively new to Python, and I don't understand the following code produces the subsequently unexpected output:
x = input("6 divided by 2 is")
while x != 3:
print("Incorrect. Please try again.")
x = input("6 divided by 2 is")
print(x)
the output of which is:
6 divided by 2 is 3
Incorrect. Please try again.
6 divided by 2 is 3
3
Incorrect. Please try again.
6 divided by 2 is
Why is the while loop still being executed even though x is equal to 3?
input() returns a string, which you are comparing to an integer. This will always return false.
You'll have to wrap input() in a call to int() for a valid comparison.
x = int(input("6 divided by 2 is"))
while x != 3:
print("Incorrect. Please try again.")
x = int(input("6 divided by 2 is"))
print(x)
Read more on int() here.
You are getting this error is because you are not parsing the input like so:
x = int(input("6 divided by 2 is"))
If you replace your inputer statement with that, it'll work.
input method gives the string. So you need to typecast to int as:
x = int(input("6 divided by 2 is"))
Here is my answer to your question
Guesses = 0
while(Guesses < 101):
try:
x = int(input("6 divided by 2 is: "))
if(x == 3):
print("Correct! 6 divide by 2 is", x)
break
else:
print("Incorrect. try again")
Guesses += 1
except ValueError:
print("That is not a number. Try again.")
Guesses += 1
else:
print("Out of guesses.")
I am assuming you wanted the user to input a number so i put your code into a while\else loop containing a try\except loop. The try\except loop ensures that if the users inputs a number, a ValueError will appear and it will inform them that what they inputted was not a number. The while\else loop ensures that the user will be inputted the question if the Guesses limit is no higher than 100. This code will ensure that if the user guesses the answer which is 3, the user will be prompted that they got the answer right and the loop will end; if the users guesses anything besides 3 (Number wise) the answer will be incorrect and the user will be prompted the question again; if the user guesses a string it will be classified as a ValueError and they will be notified that their answer wasn't a number and that the user has to try again.
Considering this was asked a long time ago, I'm assuming your probably forgot about this or you figured out the answer but if not try this and tell me if you like this answer. Thank :)
I actually tried this myself now with python 2.6, and did get an int without converting to int. For example, when I try the following:
x = input("6 divided by 2 is")
print "Your input is %s, %s" % (x, type(x))
I get the following:
6 divided by 2 is 2
Your input is 2, <type 'int'>
So is this a version issue? Or maybe an environment issue (I'm using OS X)?
What I do conclude is that it should be a good practice using previous recommendations using int().

Categories