When I attempt to print a different message for there being more than one guess I am getting a double print message for when there is it is guessed in one iteration.
if guess >= 2:
print ('Your number is %d. I found it in %d guesses.' % (guess, iteration))
if iteration == 1:
print ('I found your number in 1 guess.')
current output:
Enter two numbers, low then high.
low = 2
high = 8
Think of a number in the range 2 to 8.
Is your number Less than, Greater than, or Equal to 4?
Type 'L', 'G', or 'E'): e
Your number is 4. I found it in 1 guesses.
I found your number in 1 guess.
You didn't defined what is "min_no" and "max_no" at first loop iteration in this line:
guess = guess_number(min_no, max_no)
And the last if is comparing the "guess" number instead of the "iteration" counter:
if guess == 1:
print ('I found your number in 1 guess.')
I can't figure out how to get the program to print a different message for the program guessing the number in 1 guess vs. it guessing it in more than one guess.
You are checking the wrong value. Change this:
if guess == 1:
to:
if iteration == 1:
I need the program to give me a message about input being inconsistent when the user fails to respond to the less than/greater than prompts properly.
You are using an else in a situation where it can never be true, since hint.lower() is already certainly a valid letter, and you already checked all possible values. Adding an else to that is futile and not what you need. An inconsistency is detected when min_no becomes greater than max_no. So change:
else:
raise ValueError('Your answers have not been consistent.')
to this:
if min_no > max_no:
raise ValueError('Your answers have not been consistent.')
Other improvements
For getting a random integer between two integers, including both as possible outcomes, don't use randrange, but randint. Otherwise the second value will never be selected.
Your code will sometimes produce the same number as the previous guess, even if the user answered with L or G. This is because you keep that guess in the new range of possible values. So change:
max_no = guess
to this:
max_no = guess - 1
And also:
min_no = guess
to this:
min_no = guess + 1
Related
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.
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")
I have converted the variable to a string, however Python still does not recognise this and says the integer is not subscriptable.
I've already tried viewing other questions with the same 'integer is not subscriptable' problem but none which answer my question specifically.
I have explicity converted the variable to a string the line before the error occurs.
import random
num = random.randint(1000, 9999)
tot_correct = 0
tot_tries = 0
while tot_correct != 4:
tot_correct = 0
tot_tries += 1
guess = input("Guess the number: ")
guess = str(guess)
#check 1st number
if guess[0] == num[0]:
tot_correct += 1
#check 2nd number
if guess[1] == num[1]:
tot_correct += 1
#check 3rd number
if guess[2] == num[2]:
tot_correct += 1
#check 4th number
if guess[3] == num[3]:
tot_correct += 1
print("You got " + tot_correct + " numbers right.")
print("You have guessed the number correctly! It took you " + tot_tries + " tries.")
I expected the string to become a string array, (but it still does not, and returns the same error) and then identify whether or not the individual number matches the one already
Your code isn't doing what you think it is. Right now you are inputting a number, converting it to a string and comparing the first character of that guess string to the first index of the number num[0] which isnt indexable.
edit:
Your code is doing a number of things wrong actually. One huge problem you have is you are setting tot_correct = 0 inside of your while loop which means it'll run forever and never finish.
But stepping back I think you are making this problem too complicated. Let's talk about the pseudocode for what I believe you are trying to do.
num_guessed = 0
number_to_guess = 4
total_guesses = 0
while num_guessed < number_to_guess:
# each pass we reset their guess to 0 and get a new random number
guess = 0
# get a new random number here
while guess != random:
# have a user guess the number here
total_guesses += 1 # we can increment their total guesses here too
# it would be a good idea to tell them if their guess is higher or lower
# when they guess it right it will end the loop
num_guessed += 1
# down here we can tell them game over or whatever you want
The code should at least give you an idea of how to approach the problem without solving it for you.
I respectfully disagree with the previous comment. It will be possible for the loop to end. I understand why you are setting tot_correct to 0 at the start of each loop. Because tot_correct is incremented up to 4 times, it is possible for tot_correct == 4 to be true.
Edit: The poster is trying to count the correct number of digits provided. So if the number to guess is '1234' and the user inputs '1564', the poster wants the code to return '2' to indicate that the '1' and '4' were correct numbers. It's like the game mastermind, where a player has to guess the correct colors and orientation of the colors. However, this code will not inform the user if a correct number is added in an incorrect position, just if the correct number is in the correct position.
However, he is correct that your error lies in your access of num[<index>]. numis an integer so you cannot index into it, hence 'integer is not subscriptable.' num needs to be a string in order to index the characters.
Edit: guess was already a string without the call to str() because the return from input() is a string
Some things to consider: Do you want your user to know they need a 4 digit number? What if there are whitespaces added? Currently your code does not remove whitespace. If you are looking for '6543' as the magic number and I enter ' 6543' your solution would not recognize my answer as correct.
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)
This is a piece of code that allows the user to choose a number and the computer guesses the number. However, when the computer is guessing it sometimes guesses the same number more than once. How do I stop the computer from guessing a number it has already guessed.
import random
print('This is a game where the user chooses\n' +
'a number for the computer to guess.')
guess = random.randint(1, 50)
number = int(input('\n\nChoose a number between 1 and 50: '))
while guess != number:
if guess > number:
guess = random.randint(number, 50)
else: guess < number
guess = random.randint(1, number)
print(guess)
input('Enter to see the next number')
print('The computer guessed your number:', guess,'!')
input('\n\n\nPress enter to exit!')
without rewriting other aspects of your game...
try this for not choosing the same number twice:
numbers = range(1,51)
ind = random.randint(0, len(numbers)-1)
guess = numbers[ind]
numbers.remove(ind+1)
numbers will contain only the list of unguessed numbers in the range to be guessed
(and won't take forever to find the unguessed number when you have a list of 49 guessed numbers!)
[EDIT] and from the comment below:
numbers = range(1,51)
guess = numbers.pop(random.randint(0,len(numbers)-1))
You can keep a cache of all of the numbers that the computer has guessed. Maybe using a dict or list or something.
However, this doesn't prevent the computer from guessing the same number (it just means it'll pick another number if it's already seen it).
If you want to NEVER guess the same number twice, you need to randomly draw numbers from a fixed set of numbers and then remove the number from the set. This guarantees that you will never pick the same number twice. However, depending on the number of candidates, this may or may not be a feasible solution (for example, if there are infinite number of possibilities).
The problem is you are only keeping the last guess information and guessing between that and the max or min of the total range. This will maintain the same approach but restrict guesses based on already knowing if its higher or lower then numbers already guessed.
max_guess = 50
min_guess = 1
guess = random.randint(min_guess, max_guess)
while guess != number:
if guess > number:
max_guess = guess - 1
else:
min_guess = guess + 1
guess = random.randint(min_guess, max_guess)
Do you want real random numbers and you are connected to Internet? https://pypi.python.org/pypi/randomdotorg/
I suggest also playing with random.seed or/and random.choice(range(min,max))
You could try this:
#!/usr/bin/env python
import random
print('This is a game where the user chooses a number for the computer to guess.')
guesses = range(1,51)
random.shuffle(guesses)
number = int(input('\n\nChoose a number between 1 and 50: '))
while True:
guess=guesses[0]
print "The computer guessed %d" % (guess)
if guess > number:
guesses=[x for x in guesses if x<guess]
elif guess < number:
guesses=[x for x in guesses if x>guess]
else:
break
print('The computer guessed your number!')
We'll store all possible guesses and randomize their order. Then we'll use information from the user to progressively eliminate potential guesses. We don't have to reshuffle or choose random numbers as we go because removing elements from a randomly ordered array maintains the "randomness" of the next element we'll pull from it.
While fixing the range on your random.randint() call would also resolve the problem (and in a cleaner fashion), the method I describe offers an alternative approach which is more general (say, for instance, if the user suddenly tells you that their number is odd).
Since this appears to be the "greater than, less than" game, I propose that the issue can be resolved by fixing the logic used for the range supplied to the random generator.
The computer should never guess from the same range twice as any choice the computer makes will always be "higher" or "lower" or "equal" to the number being sought - this information should be used to update the range of the next random number chosen. The updated range excludes the previous random guess.
Using number in the random range selection is wrong because it is independent of the guess made; it is simply what is being sought. You probably want two additional variables, minGuess and maxGuess, that are updated each loop and are used to limit the range of the random values.
Try to play the game against another person - how do you quickly "guess" the right number? If you're playing for minimum "guesses", you'll always divide the range directly in half, but you can pick randomly from the remaining range like the computer does (or should).