This is my code, The computer is supposed to guess a number between 1 and 100. The computer's guesses should either decrease or increase by half of the previous guess. The third time through the loop going only higher it breaks, or if I use higher after saying lower it breaks. Both ways, it will stop adding its guesses and divide the previous guess by two, instead of adding the previous guess divided by two to the previous guess. i.e instead of 50 + (50/2) = 75 my code does 50/2 = 25. So where it breaks on higher is at 87, instead of adding half of the previous guess, which would be six, it divides 87 by 2 equaling 43. (I have now edited this question, and the code and everything should work besides where I need help. Thank you)
pcguess = 50
useranswer = 50
print("Wanna see a magic trick?")
print("Please think of a random number between 1 and 100.")
print("Now that you have written down your number")
print("I will guess it in ten guesses or less.")
a = print("My first guess is", pcguess)
tries = 0
while tries < 100000:
newguess = pcguess//2
b = input("Was that your number?")
if b == "no":
tries += 1
c = input("Is your number higher or lower than my guess?")
if c == "lower":
print("Then my next guess is:")
print(useranswer - newguess )
useranswer = pcguess - newguess
pcguess = newguess
tries += 1
elif c == "higher":
print("Then my next guess is:")
print(useranswer + newguess)
useranswer = pcguess + newguess
pcguess = newguess
tries += 1
if b == "yes":
print("I got it in", tries, "tries!")
break
You need to narrow down the possible range of numbers based on the user's "higher"/"lower" responses. So you should store the lower and upper bounds as variables, and adjust them as you get responses. Something like this:
lower = 0
upper = 100
while lower < upper:
guess = (lower+upper)//2
print("My guess is ", guess)
# Find out if the correct answer is higher or lower than this guess
if the correct answer is higher:
lower = guess + 1 # This gives a new lower bound
if the correct answer is lower:
upper = guess - 1 # This gives a new upper bound
The first thing I would change in your code is your where you increment your tries variable. In your current while loop, you are incrementing once every time you execute your while loop and then again after whichever if statement gets executed. This means that every iteration, your number of tries goes up by 2 instead of 1. So why don't you just increment tries once at the beginning of your loop instead?
Second, the reason your useranswer variable doesn't become what you expect is simply because you are updating it wrong. For example
if c == "lower":
print("Then my next guess is:")
print(useranswer - newguess )
useranswer = pcguess - newguess # WRONG
pcguess = newguess
since you are updating useranswer, it should be useranswer = useranswer + newguess or more succinctly useranswer += newguess
Do this for the other if statement as well (where your guess is higher than what the computer is guessing)
Thirdly. This is more a matter of styling but your while loop condition should be more accurate (i.e. since you are telling the user that you will guess their number in 10 tries or less, does your loop condition really need to have tries < 100000?
Related
I am extremely new to python and this is one of the first things I have tried. There are 3 criteria that I want this game to meet. First is to use the number 0-10 and guess the number 3 which it does correctly. Next is 0-25 when 11 is chosen. This also works correctly.
However this last part has been giving me trouble. When picking from 0-50, it should guess 1 which it does. It should also print the "I'm out of guesses" line when another input is placed as it cannot go higher than one now. What am I doing wrong here?
import random
import math
smaller = int(input("Enter the smaller number: "))
larger = int(input("Enter the larger number: "))
maxTry = math.log(larger - smaller)
count = 0
guess = int((smaller+larger)/2)
while count != maxTry:
count += 1
guess = int((smaller+larger)/2)
print("Your number is ", guess)
help = input("Enter =, <, or >: ")
if help == ">":
smaller = guess +1
elif help == "<":
larger = guess -1
elif help == "=":
print("Hooray, I've got it in", count, "tries")
break
elif count == maxTry:
print("I'm out of guesses, and you cheated")
break
Your maxTry is a log so it is not an integer, therefore it can never be equal to count.
You can either use an int for maxTry (cast it to int maxTry = int(math.log(larger - smaller))) or compute it with something different than log that will return an int.
Alternatively, your condition could be count > maxTry instead of equal. It would actually be a bit better conceptually.
Note: you should not use capital letters in variable names in python but all lowercase with _ max_try. It is only a convention though so won't affect your program directly. You can find more info on conventions in the PEP8 documentation
I created a number guessing game and its code is as follows but the problem is that when I input the number which is warm (look at the code)(for eg 70) and then the warmer number(say 69) and then finally the secret number(i.e. 65) instead of showing 'you won!!:)' it again asks the user to input value but if I directly input the secret number or input the secret number followed in any manner accept this one it works fine. I'm new to python so please help in as easy manner as possible.
guesses = 0
number = 65
while guesses < 30:
guess = int(input())
close = abs(number - guess)
if guess == number:
print("You won!!:)")
break
elif close < 10:
print("Warm")
guesses += 1
guess = int(input())
if abs(guess - number) < close:
print("Warmer")
guess = int(input())
guesses += 1
elif close > 10:
print("Cold")
guesses +=1
if abs(guess - number) < close:
print("Colder")
guesses += 1
Remove the guess = int(input()) from under the if abs(guess-number) < close:. The problem was that after input() is called there, it is called again at the beginning of the loop on its way to be checked for equality.
guesses = 0
number = 65
while guesses<30:
guess = int(input())
close = abs(number - guess)
if guess == number:
print("You won!!:)")
break
elif close<10:
print("Warm")
guesses += 1
guess = int(input())
if abs(guess-number) < close:
print("Warmer")
guesses += 1
elif close>10:
print("Cold")
guesses +=1
guess = int(input())
if abs(guess-number)<close:
print("Colder")
guesses += 1
It's like that because you ask for a number after print("Warmer") and you do nothing with this guess - you do not check if it's correct or not. The iteration of loop finishes and it starts again asking for a new guess.
Remove guess = int(input()) from
print("Warmer")
guess = int(input())
guesses += 1
and it should work just fine.
remove guess = int(input()) . on line number #15
it's a repeated call for input, because you are calling it on line number #4 which makes it ask for input than give you the result.
The others have pointed out the cause for your specific problem.
I would like to recommend that you should try to avoid code duplication in general. Besides calling input() multiple times, you also increment guesses at multiple places.
This is so important, it has a cool acronym: DRY, which stands for "Don't Repeat Yourself".
Code duplication causes your code to be harder to maintain, because you have to apply the same change in multiple places. DRY code, on the other hand, is usually more readable and easier to maintain.
Think about how to rewrite your code to reduce code duplication.
So I'm creating this game where the computer guesses a number, and based on the reply, it splits and re-selects a number. I've had little problems so far, but now I'm quite stuck on the loop. I know what I have to do, I just can't figure out how to do it properly, and have it function.
lowest = int(input( "What is the lowest number you will think of?: "))
highest = int(input( "What is the highest number you will think of?: "))
print("So you're thinking of a number between",lowest,"and",highest)
x=[]
for number in range(lowest,highest):
x.append(number)
middleIndex = (len(x))//2
print ("is it "+str(x[middleIndex])+"?")
answer = input("")
if answer == "lower":
x = (x[:len(x)//2])
else:
x = (x[len(x)//2:])
I know it has to go after the
x.append(number)
but I can't get it to work using for or while loops.
The entire for loop is kind of pointless, with the x.append line especially so. range() gives you a list anyway (in Python 3 it gives you a range object which can be converted to a list using the list function).
You could replace that with:
x=list(range(lowest, highest))
Also, this is more convention than anything technically incorrect, but in Python I think camel case is generally reserved for class names; for this reason, I would rename middleIndex to middle_index.
And finally, you don't have anything for the case when the computer guesses the right number!
What you're looking for is basically an interactive binary search algorithm that runs over a range of numbers. You don't actually need to use range or a list, because you can calculate the average of your min and max values instead of finding the middle_index.
Here is an example implementation:
def main():
print("What range will your guessed number fall within?")
min = int(input("Min: "))
max = int(input("Max: "))
print("Ok; think of a number between {0} and {1}.".format(min, max))
while min <= max:
mid = (min + max) // 2
if input("Is it {0}? (Y/N) ".format(mid)) == "Y":
print("It is!? Well, that was fun.")
return
elif input("Darn. Is it higher than {0}? (Y/N) ".format(mid)) == "Y":
min = mid + 1
else:
max = mid - 1
print("Well, it looks like you were dishonest somewhere along the line.")
print("I've exhausted every possibility!")
main()
I am new to python, sorry about a basic one.
The code works fine but it guesses same number twice or maybe more number of times. I want to guess an unique number every time.
import random
print("Hey human guess a number between 1 to 50 and i will try guessing what it is ! \n ")
input("Press enter when you have done the first step \n")
print("after my guess if its correct then hit y, if i need to guess higher than hit g and if i need to guess lower then hit l\n")
answer = ""
m = 1
n = 50
while(answer!='y'):
guess = random.randint(m,n)
print(guess)
reply = input("Is my guess correct ?")
if reply == 'y':
print("GG")
answer = 'y'
elif reply == 'l':
n = guess
print("\n Okay let me try again")
elif reply == 'g':
m = guess
print("\n aaah let me try again please \n")
else:
print("\n Seriously man what did i tell you before ?")
Thank you in advance.
As stated in the docstring of random.randint, this method "returns a random integer in range [a, b], including both end points". That means that when you assign the guess to either m or n the guess is going to be included for the range of the random.
Thus, to fix your code you could modify the following lines:
m = 0
n = 51
guess = random.randint(m+1,n-1)
In this way, you never include the guess in the range of the random. Hope this helps.
Create a list of guessed numbers guessed_numbers = []
Then whenever save the guess guessed_numbers.append(guess)
And before setting guess, check that guess is not in guessed numbers.
So you wind up with:
n = 50
guessed_numbers = []
while (answer != 'y'):
guess = random.randint(m, n)
while (guess in guessed_numbers):
guess = random.randint(m, n)
guessed_numbers.append(guess)
print(guess)
The problem is likely that random.randint produces a number between m and n inclusive. If the range is 1-50, and the program guesses 50, it sets the upper bound to 50 again, which means it could guess that number twice. It will be more likely to happen as the range narrows.
I think if you change the line
n=guess
to read
n=guess-1
and similarly add one for m when it guesses too low, you'll get the result you're looking for.
I am trying to find the average number of times a user guesses a number. The user is asked how many problems they want to do and then the program will give them that many problems. I am having trouble recording the amount of times they guess and get wrong and guess and get right and finding the average between the two. This is what I have so far
print("Hello!")
from random import randint
def HOOBLAH():
randomA = randint(0,12)
randomB = randint(0,12)
answer = 0
CORRECTanswer = (randomA*randomB)
REALanswer = (randomA*randomB)
AVGcounter = 0
AVGcorrect = 0
AVERAGE = 0
print("What is {0} * {1} ?".format(randomA,randomB))
while answer != REALanswer:
an = input("What's the answer? ")
answer = int(an)
if answer == CORRECTanswer:
AVGcorrect+=1
print("Correct!")
AVERAGE+=((AVGcorrect+AVGcounter)/AVGcorrect)
else:
AVGcounter+=1
if answer > CORRECTanswer:
print("Too high!")
else:
print("Too low!")
def main():
numPROBLEMS = input("How many problems would you like to solve? ")
PROBLEMS = int(numPROBLEMS)
if PROBLEMS in range(1,11):
for PROBLEMS in range(PROBLEMS):
HOOBLAH()
else:
print("Average number of tries: {0}".format(HOOBLAH,AVERAGE))
else:
print("Please input a value between 1 through 10!")
main()
Thanks!
So I tried to change as little as possible as to not cramp your style. So think about it like this, the average number of guesses needed to get the correct answer is just the total number of guesses divided by the number of correct guesses. Because you make sure the user eventually gets the correct answer, the number of correct guesses will just be the number of problems!
So each time you run HOOBLAH(), return the number of guesses it took to get the correct answer. Add all those up together outside the for loop, then at the end of the loop, divide the number of guesses by the number of problems and then you've got your answer! Also, I don't think python supports '+=', so you may need to change AVGcounter+=1 to AVGcounter = AVGcounter +1, but I totally may be mistaken, I switch between languages a bunch!
One note is I cast numGuesses to a float ( float(numGuesses) ), that is to make sure the int data type doesn't truncate your average. For example, you wouldn't want 5/2 to come out to 2, you want it to be 2.5, a float!
Hopefully that helps!
from random import randint
def HOOBLAH():
randomA = randint(0,12)
randomB = randint(0,12)
answer = 0
CORRECTanswer = (randomA*randomB)
REALanswer = (randomA*randomB)
AVGcounter = 0
AVERAGE = 0
print("What is {0} * {1} ?".format(randomA,randomB))
while answer != REALanswer:
an = input("What's the answer? ")
answer = int(an)
if answer == CORRECTanswer:
print("Correct!")
return AVGcounter
else:
AVGcounter+=1
if answer > CORRECTanswer:
print("Too high!")
else:
print("Too low!")
def main():
problemsString = input("How many problems would you like to solve? ")
numProblems = int(problemsString)
numGuesses = 0
if numProblems in range(1,11):
for problem in range(numProblems):
numGuesses = numGuesses + HOOBLAH()
print("Average number of tries: " + str(float(numGuesses)/numProblems)
else:
print("Please input a value between 1 through 10!")
main()
I'm not totally sure what you're trying to do, but if you want to give the user x number of problems, and find the average number of guesses per problem, you'll want your HOOBLAH() function to return the number of guesses for each run. You can keep track of this outside your method call and average it at the end. But right now, your program has no access to AVGcounter, which seems to be the variable you're using to count the number of guesses, outside the HOOBLAH() function call.