I'm working on a guessing game where the user inputs a number until they get it correct. I'm trying to understand why my output creates multiple print functions if I don't guess in the first try. But if I guess the answer correctly on first try, it prints correctly.
ans = 5
def function(guess, ans):
if ans != guess:
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
elif ans == guess:
print("Correct!")
def init():
print("Guess a number between 1 and 10: ")
guess = int(input())
main(guess)
def main(guess):
while function(guess, ans) == False:
init()
function(guess, ans)
break
init()
Outputs:
Correct guess on first attempt:
Guess a number between 1 and 10:
5
Correct!
Correct guess on third attempt:
Guess a number between 1 and 10:
4
Guess higher
Guess a number between 1 and 10:
6
Guess lower
5
Correct!
Guess lower
Guess higher
It is because of this:
The answer is incorrect. So you go to init()
The init() again passes the argument to main() function. So, it has become a sort of recursion where the function is executed again.
Here is what your code is doing.
main()
|__init()
| |
| main()
| |
| function()
|
function()
That is why you are getting that output.
Also, this hierarchy increases 1 level with each incorrect answer.
Instead, here is what you can do:
ans = 5
guess=0
def function(guess, ans):
if ans != guess:
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
elif ans == guess:
print("Correct!")
return True
def init(guess):
while True:
print("Guess a number between 1 and 10: ")
guess = int(input())
if function(guess, ans):
break
init(guess)
The answer to your question is that when your input isn't correct the first time, your code is entering into a recursive call because of the main(guess) line that you've put in the init() function which later is returning those extra lines of output that you don't want to see. (For n incorrect tries, you'll be seeing n such extra lines after your code prints out Correct! depending on whether your previous inputs were higher or lower.)
First, there is no need of ans != guess, you can simply make a conditional with if-elif-else condition like:
def function(guess, ans):
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
else: # This will automatically be ans = guess case
print("Correct!")
return True # You weren't returning any value here and I suppose you wanted to exploit this
You'll need to remove the main(guess) line from your init() function to avoid recursive-call and add a line to return guess i.e. user input so that you can pass it on to the main() function.
def init():
print("Guess a number between 1 and 10: ")
guess = int(input())
return guess
Now, you need to modify your main function like-
def main():
while True:
guess = init()
if function(guess, ans):
break
You can call the main function as shown below and it'll work-
main()
PS- There are many ways to fix your code into the one which does what you wish to do and this is just one of those ways.
All explanations were given by #Sujay.
This is an alternative with local variable.
ans = 5
def guess_my_number(guess, ans): # <- choose a meaning function name
if ans != guess:
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
elif ans == guess:
print("Correct!")
return True # <- It's important to return True
def main():
# If user guessed the answer, this variable is set to True
good_answer = False
# So while the user has not found, continue to ask him a number
while good_answer != True:
print("Guess a number between 1 and 10: ")
guess = int(input())
good_answer = guess_my_number(guess, ans)
main()
Just remove function(guess, ans) in the main() function. you are already using while loop and returning bool values from function()
In the function function () return true when value is satisfied
Related
def set_number():
import random
return random.randint(1,500)
#This function plays the game
def number_guessing_game(number):
guess_counter = 0
guess = int(input("Enter a number between 1 and 500."))
while guess != number:
guess_counter += 1
if guess > number:
print(f"You guessed too high. Try Again!")
guess = int(input("Enter a number between 1 and 500."))
elif guess < number:
print(f"You guessed too low. Try Again!")
guess = int(input("Enter a number between 1 and 500."))
if guess == number:
print(f"You guessed the number! Good Job.!")
again = str(input("would you like to play again? Enter 'y' for yes or 'n' to close the game."))
def main():
print(f"Welcome to the Number Guessing Game!\n" +
f"You will have unlimited guesses. The number is between 1 and 500.\n" +
f"Good Luck!")
number = set_number()
guess_count = number_guessing_game(number)
main()
I am working on a simple game project for my coding class. I am not good at coding at all. I came up with this part of the program, I just cannot figure out how to loop the entire number_guessing_game function until the user enters 'n' to stop it, I can't use a break because we did not learn it in the class and I will receive a 0 if I use a break.
I tried nesting a while loop inside of the function but I know I did it wrong.
Instead of using break use return.
def main():
print(f"Welcome to the Number Guessing Game!\n" +
f"You will have unlimited guesses. The number is between 1 and 500.\n" +
f"Good Luck!")
while True:
number = set_number()
number_guessing_game(number)
again = input("would you like to play again? Enter 'y' for yes or 'n' to close the game.")
if again == 'n':
return
main()
You will probably want to remove the last line of the number_guessing_game function if you use this approach
First, your code is assuming the return of input is an integer that can be converted with int(). If you were to give it 'n' your program will crash.
Instead you could use the string class method isdigit() to see if the input was an integer value and then make a logical decision about it. Also note you do not need to convert the return from input to a str() as it is already a str type. You can confirm this with a print(type(input("give me something")))
guess = input("Enter a number between 1 and 500. 'n' to quit"))
if guess.isdigit():
[your code to check the value]
elif ('n' == guess):
return
else:
print(f"You entered an invalid entry: {guess}. Please re-enter a valid value")
If you dont like the idea of using 'return' you could change your while loop to look something like:
while(('n' != guess) or (guess != number)):
If you want the function body looping continuously you could have some code like:
def number_guessing_game(number):
exit_game = False
guess_counter = 0
while(exit_game != True):
guess = input("Enter a number between 1 and 500.))
guess_counter += 1
if guess.isdigit():
if int(guess) > number:
print("You guessed too high. Try Again!")
elif int(guess) < number:
print("You guessed too low. Try Again!")
elif int(guess) == number:
print("You guessed the number! Good Job.!")
again = input("would you like to play again? Enter 'y' for yes or 'n' to close)
if ('n' == again):
exit_game = True
else:
print("Error, please enter a valid value")
I am trying to create a simple code guessing game where the user can choose the minimum and maximum number the randomly generated code can be. The user has to try and guess the code to win. When I run my code, the get_range() function works and then it proceeds to the get_guess() function as it should. But when the user enters his/her input for their guess, the code loops back to the start of the get_range() function. Please can anyone help? Thanks in advance. Code:
import random
import string
print("Welcome to Code Crunchers!")
def get_range():
Min = str(input("Enter the minimum number that the code can be: "))
Max = str(input("Enter the maximum number that the code can be: "))
Check_Min = Min.isdigit()
Check_Max = Max.isdigit()
if Check_Min != True or Check_Max != True:
print("Input must only contain integers!")
get_range()
elif Min == Max:
print("Minimum and maximum number must not be equivalent!")
get_range()
elif Min > Max:
print("Maximum number must be greater than minimum number!")
get_range()
else:
Random_Number = random.randrange(int(Min), int(Max))
get_guess()
return Random_Number
def get_guess():
Guess = str(input("Enter your guess: "))
Check_Guess = Guess.isdigit()
if Check_Guess != True:
print("Input must only contain integers!")
get_guess()
else:
validate()
return Guess
def validate():
Random_Number = get_range()
Tries = locals()
Guess = get_guess()
Length = len(str(Random_Number))
Digits_Correct = 0
if Guess == Random_Number:
print("Well done! You guessed the number in", Tries, " tries!")
else:
Digits = ["?"] * Length
Tries += 1
for i in range(0, int(Length)):
if Guess[i] == Random_Number[i]:
Digits[i] = Guess[i]
Digits_Correct += 1
else:
continue
if int(Length) > Digits_Correct > 0:
print("Not quite! You got", Digits_Correct, " digits correct.")
print(Digits)
get_guess()
elif Digits_Correct == 0:
print("None of your digits match!")
get_guess()
def play_again():
Choice = input("Do you want to play again (y/n)?")
if Choice != "y" or Choice != "n" or Choice != "Y" or Choice != "N":
print("Please choose a valid option!")
play_again()
elif Choice == "y" or Choice == "Y":
get_range()
elif Choice == "n" or Choice == "N":
exit()
get_range()
Because you're re-calling get_range() in validate():
def validate():
Random_Number = get_range() # <-- Here
...
You might be able to solve this with:
def validate():
Random_Number = random.randrange(int(Min), int(Max))
...
But overall, that will depend on the direction of your code. Hope that helps!
Take a look at this code:
def get_range():
...
else:
...
get_guess()
return Random_Number
def get_guess():
...
else:
validate()
return Guess
def validate():
Random_Number = get_range()
Tries = locals()
Guess = get_guess()
...
Suppose you're in get_guess and get to the else close, so you call validate. Here's what happens:
get_guess calls validate
validate immediately calls get_range
get_range calls get_guess
now we're back in get_guess, see (1)
So your code enters infinite indirect recursion.
Notice how it'll never get past Random_Number = get_range() in validate, and you're calling get_guess in both get_range and validate.
So, before returning the random number to Random_Number = get_range(), get_range will try to get_guess and immediately discard its return value (that's what get_guess() does). Suppose that get_range eventually returns. Now you'll call Guess = get_guess() again, thus asking the user to guess twice. I think there's a logic flaw here.
need help with a higher or lower game I think the problem has something to do with the loop. I have been told been told to add an except but I have no idea where to add it
print('Welcome to higher or lower game')
input('press enter to start.\n')
import random
Max = 10
Min = 0
num = random.randint(1, 10)
print('your starting number is a ' + str(num))
while 'well done.\n' :
guess = input('higher (h) or lower (l).\n')
new_num = random.randint(1, 10)
print('your new number is a ' + str (new_num))
try :
if new_num > num and guess == 'h':
print('well done.\n')
elif new_num < num and guess == 'l':
print('well done.\n')
break
if num and guess == 'l' and new_num > num and guess:
print('game over')
elif num and guess == 'h' and new_num < num and guess:
print('game over')
else:
print('game over you got a score of ' + str(score))
You do not have an except clause in the try statement. That clause is required unless you have a finally clause.
You really shouldn't have a try statement there. You could take it out and just go with some if and elif statements.
Example:
import random
number = random.randint(1,10)
lives = 3
Success = False
while lives > 0:
guess = int(input("What is your guess between 1 and 10? \r\n"))
if guess > number:
print("Too high! Go lower. \r\n")
lives -= 1
elif guess < number:
print("Too low! Go higher. \r\n")
lives -= 1
elif guess == number:
print("Congratulations, you win!")
global Success = True
break
if Success != True:
print("Sorry. Try again! The number was ", number, ".")
As far as I understand, try statements are mainly used for error handling.
With my guess the number program, when I try to run it tells me the the variable "number" is not defined. I would appreciate it and be thankful if someone came to my aid in this!
import random
guesses = 0
def higher(guesses):
print("Lower")
guesses = guesses + 1
def lower(guesses):
print("Higher")
guesses = guesses + 1
def correct(guesses):
print("You got it correct!")
print("It was {0}".format(number))
guesses = guesses + 1
print ("It took you {0} guesses".format(guesses))
def _main_(guesses):
print("Welcome to guess the number")
number = random.randint(1, 100)
while True:
guess = int(input("Guess a number: "))
if guess > number:
higher(guesses)
elif guess < number:
lower(guesses)
elif guess == number:
correct(guesses)
while True:
answer = input("Would you like to play again? Y or N: ")
if answer == "Y":
break
elif answer == "N":
exit()
else:
exit()
_main_(guesses)
Your problem is that number is not defined in the function correct. number is defined in _main_. When you call correct in _main_, it does not get access to number.
This is the fixed version of your code:
import random
guesses = 0
number = random.randint(1, 100)
def higher(guesses):
print("Lower")
guesses = guesses + 1
def lower(guesses):
print("Higher")
guesses = guesses + 1
def correct(guesses):
print("You got it correct!")
print("It was {0}".format(number))
guesses = guesses + 1
print ("It took you {0} guesses".format(guesses))
def _main_(guesses):
print("Welcome to guess the number")
while True:
guess = int(input("Guess a number: "))
if guess > number:
higher(guesses)
elif guess < number:
lower(guesses)
elif guess == number:
correct(guesses)
while True:
answer = input("Would you like to play again? Y or N: ")
if answer == "Y":
break
elif answer == "N":
exit()
else:
exit()
_main_(guesses)
What I changed is I moved the definition of number to the top, which allowed it to be accessed by all functions in the module.
Also, your code style is not very good. Firstly, do not name your main function _main_, instead use main. Additionally, you don't need a function to print out 'lower' and 'higher.' Here is some improved code:
import random
def main():
number = random.randint(1, 100)
guesses = 0
while True:
guessed_num = int(input('Guess the number: '))
guesses += 1
if guessed_num > number:
print('Guess lower!')
elif guessed_num < number:
print('Guess higher!')
else:
print('Correct!')
print('The number was {}'.format(number))
print('It took you {} guesses.'.format(guesses))
break
main()
Your specific problem is that the variable number is not defined in function correct(). It can be solved by passing number as an argument to correct().
But even if you correct that problem, your program has another major issue. You have defined guesses globally, but you still pass guesses as an argument to lower(), higher() and correct(). This creates a duplicate variable guesses inside the scope of these functions and each time you call either of these functions, it is this duplicate variable that is being incremented and not the one you created globally. So no matter how many guesses the user takes, it will always print
You took 1 guesses.
Solution:
Define the functions lower() and higher() with no arguments. Tell those functions thatSo ultimately this code should work:
import random
guesses = 0
def higher():
global guesses
print("Lower")
guesses = guesses + 1
def lower():
global guesses
print("Higher")
guesses = guesses + 1
def correct(number):
global guesses
print("You got it correct!")
print("It was {0}".format(number))
guesses = guesses + 1
print ("It took you {0} guesses".format(guesses))
def _main_():
print("Welcome to guess the number")
guesses = 0
number = random.randint(1, 100)
while True:
guess = int(input("Guess a number: "))
if guess > number:
higher()
elif guess < number:
lower()
elif guess == number:
correct(number)
while True:
answer = input("Would you like to play again? Y or N: ")
if answer == "Y":
_main_()
elif answer == "N":
exit()
else:
exit()
_main_()
I'm doing an assignment for the computer to generate a random number and have the user input their guess. The problem is I'm supposed to give the user an option to input 'Exit' and it will break the While loop. What am I doing wrong? I'm running it and it says there's something wrong with the line guess = int(input("Guess a number from 1 to 9: "))
import random
num = random.randint(1,10)
tries = 1
guess = 0
guess = int(input("Guess a number from 1 to 9: "))
while guess != num:
if guess == num:
tries = tries + 1
break
elif guess == str('Exit'):
break
elif guess > num:
guess = int(input("Too high! Guess again: "))
tries = tries + 1
continue
else:
guess = int(input("Too low! Guess again: "))
tries = tries + 1
continue
print("Exactly right!")
print("You guessed " + str(tries) + " times.")
The easiest solution is probably to create a function that gets the displayed message as an input and returns the user input after testing that it fulfils your criteria:
def guess_input(input_message):
flag = False
#endless loop until we are satisfied with the input
while True:
#asking for user input
guess = input(input_message)
#testing, if input was x or exit no matter if upper or lower case
if guess.lower() == "x" or guess.lower() == "exit":
#return string "x" as a sign that the user wants to quit
return "x"
#try to convert the input into a number
try:
guess = int(guess)
#it was a number, but not between 1 and 9
if guess > 9 or guess < 1:
#flag showing an illegal input
flag = True
else:
#yes input as expected a number, break out of while loop
break
except:
#input is not an integer number
flag = True
#not the input, we would like to see
if flag:
#give feedback
print("Sorry, I didn't get that.")
#and change the message displayed during the input routine
input_message = "I can only accept numbers from 1 to 9 (or X for eXit): "
continue
#give back the guessed number
return guess
You can call this from within your main program like
#the first guess
guess = guess_input("Guess a number from 1 to 9: ")
or
#giving feedback from previous input and asking for the next guess
guess = guess_input("Too high! Guess again (or X to eXit): ")
You are trying the parse the string 'Exit' to an integer.
You can add a try/except around the casting line and handle invalid input.
import random
num = random.randint(1,9)
tries = 1
guess = 0
guess = input("Guess a number from 1 to 9: ")
try:
guess = int(guess) // try to cast the guess to a int
while guess != num:
if guess == num:
tries = tries + 1
break
elif guess > num:
guess = int(input("Too high! Guess again: "))
tries = tries + 1
continue
else:
guess = int(input("Too low! Guess again: "))
tries = tries + 1
continue
print("Exactly right!")
print("You guessed " + str(tries) + " times.")
except ValueError:
if guess == str('Exit'):
print("Good bye")
else:
print("Invalid input")