Python number guessing game - python

I have found some practice problems online and I got most of them to work, but this one has stumped me. Its not homework so I'm not getting a grade. However, there isn't a solution provided so the only way to get the answer is by doing it.
The task asks for you to write a problem that plays a number guessing game for numbers 1-100. However, this one tries to guess the users number by interval guessing, such as [1, 100] and generates the next question by using first+last/2.
I have a sample run from the site.
Think of a number between 1 and 100 (inclusive).
Answer the following questions with letters y or Y for yes and n or N for no.
interval: [1,100]. Is your number <= 50? y
interval: [1,50]. Is your number <= 25? y
interval: [1,25]. Is your number <= 13? y
interval: [1,13]. Is your number <= 7? n
interval: [8,13]. Is your number <= 10? n
interval: [11,13]. Is your number <= 12? y
interval: [11,12]. Is your number <= 11? y
Your number is: 11
Here is my code so far, but I don't even quite know where to start because a while-loop constantly gives me an infinite loop. I know the "middle" number needs to be an integer or else it'll be an infinite loop, but I can't seem to figure out how to do that.
x = input("Is your numbr <=50?")
count = 100
while x=="y" or "Y":
count = count/2
x = input("Is your number <=",count,"?")
print(count)
If anyone has any tips it would be greatly appreciated.

The issue is here:
while x=="y" or "Y":
the expression "Y" will always evaluate to true.
You want
while x == "y" or x == "Y":
Even then, this will end the loop when the user types an "N". A working loop would be something like:
finished = False
while not finished:
if x == "y":
upper -= (upper-lower)/2
# prompt for input
elif x == "n":
lower += (upper-lower)/2
# prompt for input
if upper == lower or (upper - 1) == lower:
finished = True
# final output
You should be able to fill in the blanks from there.

The entire idea of the problem is to keep both "bounds" starting at 1 and 100, and each time you make a question "is you number <= X" you discard half of the range according to the answer, you are not doing this in your current solution.
like this.
lower = 1
high = 100
mid = (high + lower)/2 -> at start it will be 50
If the user answers Yes then you take the range from the current lower bound to the mid of the range, otherwise you continue with the range starting on mid+1 to the end, like this:
If user answers Yes:
high = mid
If user answers No:
lower = mid +1
The last part of the idea is to detect when the range lower-high contains only 2 numbers, or are the same number like this [11,12], you use the final answer of the user to choose the correct answer and the program terminates, the full code is here so you can test it:
found = False
range_lower_bound = 1
range_high_bound = 100
print "Think of a number between 1 and 100 (inclusive)."
print "Answer the following questions with letters y or Y for yes and n or N for no."
while not found:
range_mid = (range_high_bound + range_lower_bound) / 2
x = raw_input('interval: [%s,%s]. Is your number <= %s? ' % (range_lower_bound, range_high_bound, range_mid))
if x.lower() == 'y':
# Check if this is the last question we need to guess the number
if range_mid == range_lower_bound:
print "Your number is %s" % (range_lower_bound)
found = True
range_high_bound = range_mid
# here i'm defaulting "anything" no N for simplicity
else:
# Check if this is the last question we need to guess the number
if range_mid == range_lower_bound:
print "Your number is %s" % (range_high_bound)
found = True
range_lower_bound = range_mid + 1
Hope it helps!

One good idea would be to have a simple while True: loop, inside which you maintain a maximum guess and a minimum guess. You then ask the user whether their number is greater than the average of the two. If it is, update your minimum guess to the average. If not, you lower your maximum guess to the average. Repeat until the two guesses are equal, at which point you have found the number, and can break out of the infinite loop.
You'll have to do some simple parity checking of course, to make sure you actually change your guesses in each round. You should really use raw_input() for strings, input() is for python-formatted data.

Related

How to divide variable from input by two

On line 7 and 14 I cant figure out how to divide the variable.
import keyboard
import random
def main(Number, Start):
Number = random.randrange(1,100)
Start = False
QA = input('Press "K" key to begin')
if keyboard.is_pressed('K'):
Start = True
input('I"m thinking of a random number and I want that number divisible by two')
print(Number)
input('Please divide this by two. *IF IT IS NOT POSSIBLE RESTART GAME*\n')
if QA == int(Number) / 2:
print('.')
else:
print('.')
main(Number=' ' ,Start=' ')
What you probably want:
Pick a random number
Make user divide this number by two (?)
Do something based on whether the guess is correct
What is wrong with your code:
You are not picking a number divisible by two. The easiest way to ensure that your number is, indeed, divisible by two, is by picking a random number and then multiplying it by two: my_number = 2 * random.randrange(1, 50). Note the change in the range. Also note that the upper limit is not inclusive, which may be not what your meant here. A typical check for divisibility by N is using a modulo operator: my_number % N == 0. If you want users to actually handle odd numbers differently, you would need to write a separate branch for that.
input returns a string. In your case, QA = input('Press "K" key to begin') returns "K" IF user has actually done that or random gibberish otherwise. Then you are checking a completely unrelated state by calling keyboard.is_pressed: what you are meant to do here is to check whether the user has entered K (if QA == "K") or, if you just want to continue as soon as K is pressed, use keyboard.wait('k'). I would recommend sticking to input for now though. Note that lowercase/uppercase letters are not interchangeable in all cases and you probably do not want users to be forced into pressing Shift+k (as far as I can tell, not the case with the keyboard package).
input('I"m thinking of does not return anything. You probably want print there, possibly with f-strings to print that prompt along with your random number.
input('Please divide this by two. does not return anything, either. And you definitely want to store that somewhere or at least immediately evaluate against your expected result.
There is no logic to handle the results any differently.
Your function does not really need any arguments as it is written. Start is not doing anything, either.
Variable naming goes against most of the conventions I've seen. It is not a big problem now, but it will become one should you need help with longer and more complex code.
Amended version:
import random
import keyboard
def my_guessing_game():
my_number = random.randrange(1, 50) * 2
# game_started = False
print('Press "K" to begin')
keyboard.wait('k')
# game_started = True
print(f"I'm thinking of a number and I want you to divide that number by two. My number is {my_number}")
user_guess = input('Please divide it by two: ')
if int(user_guess) == my_number / 2:
# handle a correct guess here
print('Correct!')
pass
else:
# handle an incorrect guess here
pass
Alternatively, you can use the modulo operator % to test whether Number is divisible by 2:
if Number % 2 == 0:
print('.')
else:
print('.')
This will check whether the remainder of Number divided by 2 is equal to 0, which indicates that Number is divisible by 2.

Python: Guessing a number is User's mind

I am stuck on a question from my Introduction to Python course. I have to write a code wherein the user keeps an integer in their mind, and the computer guesses. If the user's number is higher than the computer's guess, the user types "+", and the computer guesses higher. If the user's number is lower, the user types "-", and the computer guesses lower numer. If the computer guesses correctly, the user types "y", and the program ends.
Use the builtin function "input" to get a text from the user. If the user types anything other than "+", "-", or "y", the function should throw an exception.
Your function should take no arguments and return nothing.
I have to write the code in python.
The problem I am facing is that after checking for the input the first time, how to change the range and make the user enter their response again. I have just started coding, so please forgive me if it is a very basic question.
I was having the same problem you have and here is my solution for it:
import random
low = 1
high = 100
int(input("Enter the number for computer to guess: "))
while low != high:
guess = low + (high - low) // 2
high_low = input(f"Computer guess is: {guess} \n "
f"Press (H) for higher, (L) for lower and (C) for correct: ").casefold()
if high_low == "h":
low = guess + 1
elif high_low == "l":
high = guess - 1
elif high_low == "c":
print(f"I got it the number is {guess}")
break
else:
print("Please enter h, l or c")
else:
print(f"Your number is {low}")
Here I was using Binary Search algorithm with formula: guess = low + (high - low) // 2. To be more clear, what this formula does it starts of with guessing the mid point between high and low values. If we are told to guess higher that must mean our answer must be between 50 - 100. So the lowest it can be is 51 and that is our new lowest value for the range the mid point now becomes 51+(100-51)//2 (answer from this calculation is 75.5 integer division rounds down) so the result is 75. And If we are told now to guess lower that means answer must be somewhere between 51 and 75, so we know the answer is less than 75, the mid point now becomes 50+(75-51)//2
which is 62 and so on continues with that pattern. You can change H with +, L with -, and C with y and you will get your solution. I hope you find this useful :).
There are several solutions here, and some are more sophisticated than others.
The simplest solution in my opinion would simply be something like this (without validations):
if user_input == "+":
number = number + 1
elif user_input == "-":
number = number - 1
elif user_input = "y":
print("Number guessed correctly.")
Depending on the user input, the program will simply add or subtract 1 from the number. That way, you don't require range checks or anything the like.
Let me know if this approach is acceptable.

WAP in python script to input a multidigit number and find each of the number's factorial

The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')

Input to check if someone has put something lower then 10 and then loop it until they put an input higher then ten and then move on [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 2 years ago.
I am trying to get this input below to work, I want to if the user puts in a number less then 10 to say you need to put a higher number, then get them to input another number. until they pick a number that is accepted.
However, my code does not pick up the result of the user and does pick the correct response or move on when someone say picks 50.
It just loops forever. Is there any way to fix this?
def weapons_(aaa,numguns,numknifes,numbombs,numswords):
print("Good job!")
while True:
try:
aaa = input("""Enter you're number accordinly to the list above:""")
number = int(aaa)
print("this is a num, thank you")
while number <=10:
print ("You need to pick a number between 50 and 200")
if number <= 50:
print(x)
break
elif number <= 100:
print (y )
break
elif number<= 150:
print (m + p)
break
elif number <= 200:
print (z)
break
except ValueError:
print("this is not a number, please try again")
One thing - please format the code with backticks just before 'def'. The backtick is `, just above escape key on my laptop. Also, its good style to try to only use the three speech marks for multiline comments, you don't need it to designate a string (is what I've been told anyway) :) Finally, most of your number checks in the second code block aren't needed, because no numbers that meet the required conditions will enter the code block - if you want these to be done still then move them away from a conditional that excludes all values of number that can satisfy them (i.e. if you have a number variable with 99, this wont cause y to be printed, because it is above 10, so wont satisfy while number <=10:. This means it wont execute any of the code below while number <=10:).
Anyway, I think the problem is when someone inputs 50 or a good answer, it will print your variable (x if its under 50, y under 100 etc), and then it will ask for user input with """Enter you're number accordinly to the list above:""". Right?
This is happening because your break is only escaping the inner while loop - it will just go back to the outer while loop (i.e. While True) when this happens, and ask everything again. To fix this, try putting:
while True:
try:
aaa = input("""Enter you're number accordinly to the list above:""")
number = int(aaa)
print("this is a num, thank you")
#####this######
if number >10:
#do whatever you want when the user enters a number between 10 and 200. Break will exit all the while loops
print ('ok')
break
###############
while number <=10:
print ("You need to pick a number between 50 and 200")
#this code will only be entered if number is less than or equal to 10. So any value of number above 10 wont cause this code to execute. so all the conditions checking 100-200 are not going to be entered
if number <= 50:
print(x)
break
elif number <= 100:
print (y )
break
elif number<= 150:
print (m + p)
break
elif number <= 200:
print (z)
break
except ValueError:
print("this is not a number, please try again")

Python 'Guess Your Age' Remember Last Integer

I am relatively new to programming with python (actually programming in general). I am making this 'Guess My Age' program that only has one problem:
import random
import time
import sys
print("\tAge Guesser!")
print("\t8 tries only!")
name = input("\nWhat's your name? ")
num = 80
min_num = 6
tries = 1
number = random.randint(min_num, num)
print("\nLet me guess... You are", number, "years old?")
guess = input("'Higher', 'Lower', or was it 'Correct'? ")
guess = guess.lower()
while guess != "correct":
if tries == 8:
print("\n I guess I couldn't guess your age....")
print("Closing...")
time.sleep(5)
sys.exit()
elif guess == "higher":
print("Let me think...")
min_num = number + 1 #### Here is my trouble - Don't know how to limit max number
time.sleep(3) # pause
elif guess == "lower":
print("Let me think...")
num = number - 1
time.sleep(3) # pause
number = random.randint(min_num, num) #<- Picks new random number
print("\nLet me guess... You are", number, "years old?")
guess = input("'Higher', 'Lower', or was it 'Correct'? ")
guess = guess.lower() #<- Lowercases
tries += 1 #<- Ups the tries by one
print("\nPfft. Knew it all along.")
time.sleep(10)
As you can see, I have 'num' as the max number for the random integer getting picked, but with:
elif guess == "higher":
print("Let me think...")
min_num = number + 1
it can go back up to however high it wants.
I want it to remember the last integer that 'num' was.
Say the program guessed 50 and I said 'Lower'. Then it said 30 and I said 'Higher'
I know I am probably sounding confusing, but please bear with me.
You need to define a maximum number as well as a minimum number. If they say their age is lower than a given age, you should set that age minus 1 as the maximum.
Of course, you also need to set an initial maximal age.
You might find it more useful to look into recursive functions for this kind of problem. If you define a function which takes min_age, max_age and tries_left as parameters, which comes up with a random number with between min_age and max_age and queries the user, you can then rerun the function (within itself) with a modified min_age, max_age and tries_left - 1. If tries_left is zero, concede defeat. This way you might get a better understanding of the logical flow.
I have left code out of this answer because, as you are a beginner, you will find it a useful exercise to implement yourself.
Cant you split out your guess into something like
max_num = 0
min_num = 0
elif guess =="lower":
max_num = number
if min_num!=0:
number = min_num+(max_num-min_num)/2
else:
number = max_num-1
elif guess =="higher":
min_num = number
if max_num!=0:
number=min_num+(max_num-min_num)/2
else:
number=min_num+1
Sorry it's not meant to be fully rigorous, and its a slight change on the logic you have there, but splitting out your variables so you have a higher and lower cap, that should help a lot?
Cheers
Please let me know if you need more elaboration, and I can try to write out a fully comprehensive version
It seems as though I was wrong in the fact that it did not remember the older integers. Before when running the program it would guess a number higher than the 'num' had specified. I don't know what I changed between then and now? But thank you for the help! #.#
This seems to work.
The only changes I really made:
-Variable names were confusing me, so I changed a couple.
-Note that if you try to mess with it (lower than 5, higher than 3... "Is it 4?" if you say it's higher or lower, you'll get an error).
The first time you set min and max numbers, you do it outside of the loop, so this script does "remember" the last guess and applies it to the new min, max inside of the loop. Each time it runs, the min will get higher or the max will get lower, based on the feedback from when the user checks the guess. If you had stuck the "min_num=6" and the "num=80" inside of the loop, the guesses would never get better.
import random
import time
import sys
print("\tAge Guesser!")
print("\t8 tries only!")
name = input("\nWhat's your name? ")
max_num = 10
min_num = 1
tries = 1
guess = random.randint(min_num, max_num)
print("\nLet me guess... You are", guess, "years old?")
check = raw_input("'Higher', 'Lower', or was it 'Correct'? ")
check = check.lower()
while check != "correct":
if tries == 8:
print("\n I guess I couldn't guess your age....")
print("Closing...")
time.sleep(5)
sys.exit()
elif check == "higher":
print("Let me think...")
min_num = guess + 1
time.sleep(3) # pause
elif check == "lower":
print("Let me think...")
max_num = guess - 1
time.sleep(3) # pause
guess = random.randint(min_num, max_num) # <- Picks new random number
print("\nLet me guess... You are", guess, "years old?")
check = input("'Higher', 'Lower', or was it 'Correct'? ")
check = check.lower() # <- Lowercases
tries += 1 # <- Ups the tries by one
print("\nPfft. Knew it all along.")
time.sleep(10)

Categories

Resources