Unexpected outcomes in if and elif statements - python

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.

Related

Infinite While Loop while making a simple logic game "Bagels"

I am using The Big Book of Small Python projects to increase my skills in python, and on the very first project, which is making a simple logic game, On the first try, the code goes all the way however if you get it wrong you it won't run properly.
Here is the code and a description of the game, the while loop with chances is supposed to run for the whole game, until you run out of chances, the second while loop is supposed to run in case user enters below or more than length three for the number
import re
import random
#In Bagels, a deductive logic game, you
#must guess a secret three-digit number
#based on clues. The game offers one of
#the following hints in response to your guess:
#“Pico” when your guess has a correct digit in the
#wrong place, “Fermi” when your guess has a correct
#digit in the correct place, and “Bagels” if your guess
#has no correct digits. You have 10 tries to guess the
#secret number.
choice_of_nums=['123','345','674','887','356','487','916']
random_three_num=random.choices(choice_of_nums)
count_bagel=0
count_fermi=0
Chances=10
while Chances!=0:
guess = input(f'Guess the three digit number! You have {Chances} to guess! ')
while len(guess)!=3:
guess=input('You must choose a three digit number! Try again! ')
for i in range(0,len(random_three_num)):
if guess==random_three_num:
print('YOU WIN! Well done')
break
elif guess[i] not in random_three_num:
count_bagel+=1
if count_bagel==len(random_three_num):
print('Bagels')
Chances=Chances-1
elif guess[i]==random_three_num[i]:
count_fermi+=1
Chances=Chances-1
print('Fermi')
elif guess in random_three_num:
print('Pico')
import random
choice_of_nums = ['123', '345', '674', '887', '356', '487', '916']
random_three_num = random.choice(choice_of_nums)
count_bagel = 0
count_fermi = 0
chances = 10
while chances > 0:
guess = input(f'Guess the three digit number! You have {chances} to guess! ')
while len(guess) != 3:
guess = input('You must choose a three digit number! Try again! ')
while not guess.isdigit():
guess = input('You must choose integer values! ')
number_is_present = any(number in guess for number in random_three_num)
if guess == random_three_num:
print('YOU WIN! Well done')
chances = 1 # combined w/ the last line, chances will become = 0
elif not number_is_present:
print('Bagel')
else:
index_is_right = False
for i in range(len(guess)):
if guess[i] == random_three_num[i]:
index_is_right = True
if index_is_right:
print('Fermi')
else:
print('Pico')
chances -= 1
(06/28/22) added chances = 1 if the guess is right, so to exit the while loop
random.choices returns a list
you don't need the re module
use snake case as suggested in PEP8
The break after print('YOU WIN! Well done') exits the for loop not the while loop. Put Chances = 0 before the break:
if guess==random_three_num:
print('YOU WIN! Well done')
Chances = 0
break
You should never check a while loop with a condition like x != 0. Always use <= or >=. The reason being, that if somehow the number zero is skipped and you end up at -1 then the loop will still exit.
Couldn't your check if guess==random_three_num: be done before the for loop? Then the break statement would actually break the while loop. Now it's only breaking the for loop. This is one reason that could lead to a infinite loop.
Your second to last line elif guess in random_three_num: should probably be elif guess[1] in random_three_num:.
Chances=Chances-1 could probably be outside the for loop also, as the number of chances should decreasing only one per guess. Currently the number of chances decreases up to 3 times during the for loop (every time you hit 'Fermi'). This could lead to issue described in "1."

Number guessing game will not print the right phrase

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

Why Does my loop not work after the third time

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?

Python code to guess a number produces same number twice or thrice when close

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.

Increasing the difficulty of the guess the number game every time the user wins (python)

So my friends and I are all currently in a python class and we were looking through a book called "Invent Your Own Computer Games with Python". We found an example where the book explains how to create a Guess the Number Game and decided to mess around with it.
We want to create a function that increases the difficulty every time the user successfully guesses the correct number generated by the computer.
I was thinking that perhaps we could need a counter to keep track of how many times the user successfully wins a round and then (if they won) increases range of numbers.
For example:
easy = (1, 5)
medium = (1, 10)
hard = (1, 20)
Here's what I've done:
# This is a guess the number game.
import random
# create function for level difficulty
# The difficulty will be multiplied by 2 each time the user passes a level
def puzzle(difficulty):
while counter <= 3:
return difficulty * 2
counter = 0
guessestaken = 0
while guessestaken < 3:
while counter < 3:
level = puzzle(3)
number = random.randint(1, level)
print("I am thinking of a number between 1 and " + str(level))
print("Take a guess.")
guess = input()
guess = int(guess)
guessestaken += 1
if guess < number:
print("Your guess is too low.")
if guess > number:
print("Your guess is too high.")
if guess == number:
break
counter += 1
if guess == number:
guessestaken = str(guessestaken)
print ("Fantastic! You guessed my number in " + guessestaken + " guesses!")
if guess != number:
number = str(number)
print("Sorry, The number I was thinking of was " + number)
I'm new to python and just barely learned about functions like two days ago. Any kind of help is welcomed.
This could work:
Make a variable called, say, times_won at the beginning. Each time the person wins,
times_won += 1
BONUS: Do the same thing, but with a variable called times_lost and tick that up each time they lose.
Now it is up to you. You could change the difficulty like this:
level = puzzle(times_won+1*2)
This would make it so that it automatically goes up the more the player wins. Or how about this:
curr_dificulty = 5
if #player_won:
curr_dificulty += 4
This and other variations would increase it based on wins as well, but in a different way. You could also make it so that losing eases up the difficulty. This part is really up to you.
P.S. The tag "pygame" you used is actually referring to games made using a down-loadable library that you can import into your code, not games made with python in general. It makes games with actual graphics, you should try it out!
P.P.S. in case you didn't know, the weird syntax I made above with the #player_won and the fact that the assignment of curr_dificulty is out of place is because I used pseudo-code. It basically gives the idea, but you need to do the actual code yourself.

Categories