from random import randint
count = 0
Validation = False
def generateNumber():
Number = randint(1, 10)
return Number
def checkNumber(Guess):
Number = generateNumber()
if int(Guess) == Number and count < 1:
return "First time right! Genius?"
Validation = True
elif int(Guess) == Number and count == 2:
return "Correct. Second time, nice!"
Validation = True
elif int(Guess) == Number and count < 4:
return "Correct. Good job."
Validation = True
elif int(Guess) == Number and count > 3:
return "Correct. Took you long enough."
Validation = True
else:
return "Wrong! Try again "
while Validation == False:
Guess = input("Please guess a number between 1 to 10: ")
print (checkNumber(Guess))
count += 1
else:
TryAgain = input("Would you like to try again? y/n \n")
So the problem is, that when the user guesses the right number. Validation should be turned to True. So the while loop will stop looping. But the variable validation doesn't turn True when the player guesses the right number.
Global variables in Python are a bit tricky, it is not enough to declare a variable at the top of the file.
Also, keep you return the value before you set the Validation value, causing the function to terminate before setting this variable
Last issue is the while logic, see correction for using raw_input instead of input and else indentation
Read only access to global variables work as expected, yet when changing their value in a function requires one extra step, you should declare the global variable as global. In your case:
def generateNumber():
Number = randint(1, 10)
return Number
def checkNumber(Guess):
global Validation #<-- this instructs Python to use the global variable
Number = generateNumber()
if int(Guess) == Number and count < 1:
Validation = True
return "First time right! Genius?"
elif int(Guess) == Number and count == 2:
Validation = True
return "Correct. Second time, nice!"
elif int(Guess) == Number and count < 4:
Validation = True
return "Correct. Good job."
elif int(Guess) == Number and count > 3:
Validation = True
return "Correct. Took you long enough."
else:
return "Wrong! Try again "
while Validation == False:
Guess = input("Please guess a number between 1 to 10: ")
print (checkNumber(Guess))
count += 1
if (Validation):
if (raw_input("Would you like to try again? y/n \n") == "y"):
count = 0
Validation = False
else:
break
You need to set Validation to True before you return from the method, like this:
if int(Guess) == Number and count < 1:
Validation = True
return "First time right! Genius?"
Do this for all if-statements.
I spot two (and a half) problems in your code:
As pointed out by Ishay Peled, you need to make Validation global
Your "return" statements are located before you change the value of "Validation"
"while" has no "else"
Here's the updated code:
from random import randint
count = 0
Validation = False
def generateNumber():
Number = randint(1, 10)
return Number
def checkNumber(Guess):
global Validation
Number = generateNumber()
if int(Guess) == Number and count < 1:
Validation = True
return "First time right! Genius?"
elif int(Guess) == Number and count == 2:
Validation = True
return "Correct. Second time, nice!"
elif int(Guess) == Number and count < 4:
Validation = True
return "Correct. Good job."
elif int(Guess) == Number and count > 3:
Validation = True
return "Correct. Took you long enough."
else:
return "Wrong! Try again "
while Validation == False:
Guess = input("Please guess a number between 1 to 10: ")
print (checkNumber(Guess))
print "validation: %s" % str(Validation)
count += 1
TryAgain = input("Would you like to try again? y/n \n")
Besides the global variable issue, you need to make another set of fixes. All your assignments to Validation = True appear after the "return" statements. The Validation = True will never execute! It will exit the function before executing those. Set 'Validation = True' before you 'return'. You still need to have the global declaration as Ishay stated.
Related
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
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.
Whenever you run the game and start guessing it asks first what is guess #0? I'm trying to get it to display "what is guess #1?" but. at the same time keep the number of guesses equal to the number guessed (if that makes sense). Here's my code so far:
import random
def play_game(name, lower=1, upper=10):
secret = random.randint(lower, upper)
tries = 0
print("-----------------------------\n"
"Welcome, {}!\n"
"I am thinking of a number\n"
"between {} and {}.\n"
"Let's see how many times it\n"
"will take you to guess!\n"
"-----------------------------".format(name, lower, upper))
# Main loop
guessing_numbers = True
while guessing_numbers:
guess = input("What is guess #{}?\n".format(tries))
while not guess.isdigit():
print("[!] Sorry, that isn't a valid input.\n"
"[!] Please only enter numbers.\n")
guess = input("What is guess #{}?\n".format(tries))
guess = int(guess)
tries += 1
if guess < secret:
print("Too low. Try again!")
elif guess > secret:
print("Too high. Try again!")
else:
guessing_numbers = False
if tries == 1:
guess_form = "guess"
else:
guess_form = "guesses"
print("--------------------------\n"
"Congratulations, {}!\n"
"You got it in {} {}!\n"
"--------------------------\n".format(name,tries,guess_form))
if tries < 3:
# Randomly chooses from an item in the list
tries_3 = ["Awesome job!","Bravo!","You rock!"]
print (random.choice(tries_3))
# ---
elif tries < 5:
tries_5 = ["Hmmmmmpff...","Better luck next time.","Ohhh c'mon! You can do better than that."]
print (random.choice(tries_5))
elif tries < 7:
tries_7 = ["You better find something else to do..","You can do better!","Maybe next time..."]
print (random.choice(tries_7))
else:
tries_8 = ["You should be embarrassed!","My dog could do better. Smh...","Even I can do better.."]
print (random.choice(tries_8))
choice = input("Would you like to play again? Y/N?\n")
if "y" in choice.lower():
return True
else:
return False
def main():
name = input("What is your name?\n")
playing = True
while playing:
playing = play_game(name)
if __name__ == "__main__":
main()
I have the number of "tries" set to 0 at the beginning. However, if I set that to 1 then play the game and it only takes me 3 tries it will display that it took me 4 tries. so I'm not sure what to do. Still somewhat new to python so I would love some help
Anywhere that you have input("What is guess #{}?\n".format(tries)), use guess = input("What is guess #{}?\n".format(tries+1)). (adding +1 to tries in the expression, but not changing the variable itself)
Here is my code:
def chose_range():
while True:
choice = int(input("Choose the range 100 or 1000:"))
if choice == 100:
n = 100
break
elif choice == 1000:
n = 1000
break
else:
print('Error, enter the right number')
return n
I want to save result of this command into the variable.
How can I do this in python 3?
Do not return within your while-loop you break (you have one indent to much).
def chose_range():
while True:
choice = int(input("Choose the range 100 or 1000:"))
if choice == 100:
n = 100
break
elif choice == 1000:
n = 1000
break
else:
print('Error, enter the right number')
return n
x = chose_range()
Did you mean something like
res = chose_range()
If you mean "save the result of calling chose_range() into a variable (you didn't say which), then:
theVariable = chose_range()
However, note that your function does not always return a value to be saved; if it hits a break statement, it exits the loop without executing the return statement, at least in how your posted code is indented.
I'm kinda new to programming in general, just started to really get into python.
And I'm working on a number guesser project.
import random
def main(): # main function
print("Welcome to the number guesser game")
range_func()
max_guess_number(lower_range_cut, upper_range_cut)
evaluation(random_number, total_guesses)
def range_func(): # allows user to select a range for the number guess
print("Please select a range in which you would like to guess.")
lower_range_cut = int(input("Lower boundary limit: "))
global lower_range_cut
upper_range_cut = int(input("Upper boundary limit: "))
global upper_range_cut
random_number = random.randint(lower_range_cut,upper_range_cut)
global random_number
return lower_range_cut, upper_range_cut, random_number
def max_guess_number(low,high): # returns the total number of guesses
total_numbers = (high - low) + 1
total_guesses = 0
while (2**total_guesses) < total_numbers:
total_guesses += 1
print ("You have a total of %d guesses\n"
"for your range between %d to %d"
% (total_guesses, low, high))
global total_guesses
return total_guesses
def evaluation(random_number, total_guesses): # evaluates the users input
guess_count = 0
while guess_count < total_guesses:
user_guess = int(input("Your guess: "))
print("Your guess is: %d" % (user_guess))
if (random_number == user_guess):
print("You got it ")
break
elif user_guess > random_number:
print("Guess lower!")
guess_count += 1
else:
print("Guess higher!")
guess_count += 1
if __name__ == "__main__":
main()
One problem I've experienced while writing that, is that I wasn't able to execute this program without redefining each variables as a global variable. Just by returning the values from one function, I was not able to access e.g. the second returned variable upper_range_cut from the range_function
It there a way to handle that somehow shorter?
Also I'm happy about every note on the code itself (readability, function use, length). I know it could have made this code a lot shorter maybe by using list comprehension, but I don't really have the eye for seeing opportunities in this area yet.
So thanks for any help!
KiliBio
You're pretty much there. You can remove all globals, then just store the values returned from each function to local variables, and pass them in to new functions.
The only other changes I've made below are:
Breaking out of the evaluation loop if the answer is guessed correctly.
Printing a message if no guess is found in the given time. See: Else clause on Python while statement
The bottom two lines allow the script to be run from the command line. See: What does if __name__ == "__main__": do?
Otherwise you're looking good.
import random
def main(): # main function
print("Welcome to the number guesser game")
lower, upper, rand = range_func()
total_guesses = max_guess_number(lower, upper)
evaluation(rand, total_guesses)
def range_func(): # allows user to select a range for the number guess
print("Please select a range in which you would like to guess.")
lower_range_cut = int(input("Lower boundary limit: "))
upper_range_cut = int(input("Upper boundary limit: "))
random_number = random.randint(lower_range_cut, upper_range_cut)
return lower_range_cut, upper_range_cut, random_number
def max_guess_number(low,high): # returns the total number of guesses
total_numbers = (high - low) + 1
total_guesses = 0
while (2**total_guesses) < total_numbers:
total_guesses += 1
print ("You have a total of %d guesses\n"
"for your range between %d to %d"
% (total_guesses, low, high))
return total_guesses
def evaluation(random_number, total_guesses): # evaluates the users input
guess_count = 0
while guess_count < total_guesses:
guess_count += 1
user_guess = int(input("Your guess: "))
print("Your guess is: %d" % (user_guess))
if (random_number == user_guess):
print("You got it!")
break
else:
print "Sorry, you didn't guess it in time. The answer was: %d" % random_number
if __name__ == '__main__':
main()
You don't need to define global. You can just assign the values you are returning from a function to variable(s).
A simple example:
def add(a, b):
"""This function returns the sum of two numbers"""
return a + b
Now in your console, you could do following
# print the return
>>> print(add(2, 3))
5
# assign it to a variable
>>> c = add(2, 3)
>>> c
5
In your main function you need to assign the values which are returned by different functions to variables which you can further pass to other functions.
def main(): # main function
print("Welcome to the number guesser game")
lower_range_cut, upper_range_cut, random_number = range_func()
total_guesses = max_guess_number(lower_range_cut, upper_range_cut)
evaluation(random_number, total_guesses)