I am writing a "you think of a number and the computer has to guess it" type program. My code is here: http://pastebin.com/6Ny01PJV, and whenever it calls a function from another function it either ends the program or errors out.
def guess():
global guess
guess = choice(list)
if guess in cache:
guess()
else:
pass
print (guess)
cache.append(guess)
def check(guess):
global check
check = input("Was " + str(guess) + " the number? (y, n) ").lower()
if check == "n":
global wrong
wrong = input("Lower or higher? ").lower
elif check == "y":
playAgain = input ("I guessed the number! Play again? (y, n)")
if playAgain == "y":
#Right here it will error out with a TypeError
main()
if playAgain == "n":
exit()
else:
print("Please answer in the format 'y' or 'n'"
def reguess():
if wrong == "lower":
reguess = choice(list < guess)
#Here it will end the program, no crash, just no error given
check(reguess)
elif wrong == "higher":
#The same happens here
check(reguess)
reguess = choice(list > guess)
Whenever I type either 'higher' or 'lower', it ends the program.
Am I doing it wrong or is there an error in my code that I am not seeing?
You keep doing the same error over and over. I'll try to explain.
global list # already is globally defined on next line
list = list(range(0,11)) # list() is a function, you overwrite it here
print (list)
global cache # not necessary, again already global
cache = []
print ("Write down a number anywhere from 1-10.\nThe computer will try to guess your number.")
def guess(): # this defines a global function 'guess'
global guess # probably gets resolved to the function
guess = choice(list) # you overwrite the 'guess' function
Now, as I said, you keep having the same problem. You're making your variables overwrite the functions. You're then calling those variables as functions, as if you didn't overwrite anything.
So, TypeError: 'int' object is not callable. or something isn't callable.
Suggestion: remove global in favor of return the value from each function
Another problem I see
reguess = choice(list < guess)
Not clear what you expect that to do... list < guess is a boolean and you can't random.choice that.
TypeError: 'int' object is not callable means that you've done the equivalent of this:
def a(x):
return x+1
a = 1
a(2)
Here, we've defined a function with the name 'a', then redefined 'a' to be an int, then tried to call our function. This doesn't work because the name 'a' no longer refers to the function, but now refers to the integer 1.
Look at your code and I'm betting you'll see something similar to the above.
Related
i wanted to make a game where you guess the letter. and add a function that will show you all you incorrect guesses, so i made the list:
incorrectguesses = []
and then i made it so it asks the user to guess the letter:
while True:
guess = input("what do you think the letter is?? ")
if guess == secret_letter:
print("you guessed it!")
break
else:
incorrectguesses += [guess]
and you can see that i added the guess to the list if it was wrong.
then, i added a function to print out every item in the given list:
def print_all_items(list_):
for x in list_:
print(x)
and then i ran the function at the end of the loop:
print(print_all_items(incorrectguesses))
but this was the result:
what do you think the letter is?? a
a
None
what do you think the letter is?? b
a
b
None
as you can see, it adds "None" to the end of the list.
thanks if you could help me
print(print_all_items(incorrectguesses))
You're printing the result of the print_all_items() function.
However, that function has no return statement, so it returns None by default.
So, the result of the function is None, and that gets printed.
Since the function itself prints the results, I think you actually just want to call the function, not print its result.
As someone else pointed earlier (beat me to it), it's because you are printing a function that has no return. (In depth explanation a the end).
while True:
guess = input("what do you think the letter is?? ")
if guess == secret_letter:
print("you guessed it!")
break
else:
incorrectguesses += [guess]
print_all_items(incorrectguesses) # ←
You want to call the function, not print it.
That way the function is being run, and prints the elements of incorrectguesses.
Explanation
When you do print(<something>), the print() function is waiting for a value to be returned.
In this case because the <something> is a function, Python runs that function "inside" the print(). When your function print_all_items() is being run, it prints all the elements of the list. Once print_all_items() has finished running, and printed everything, the function doesn't return a value, so it defaults to None. Therefore, the value of the <something> the print(<something>) was waiting for is gets assigned a None value.
I hope I could help!
I have worked on many projects (school projects, I'm not too advanced), and have found that in many programs where I require the user to input a value that is an integer, or decimal(float), I need to use a "try-except" statement, within a while loop, in order to make certain that the user inputs the required value type.
For example:
def main():
userValue = input("Please enter an integer: ")
while(True):
try:
userValue = int(userValue)
break
except:
userValue = input("That is not an integer, try again: ")
print("The integer you entered is: " + str(userValue))
main()
# Input: SADASD (A non-integer value)
# Output: "That is not an integer, try again: "
# Second-Input: 3
# Second-Output: "The integer you entered is: 3"
Understandably, typing out this entire section of code repeatedly, in a program that requires user input multiple times, is not really efficient. So understanding, that user-defined functions help when I need to perform one action, multiple times. With this in mind, I defined my own function with that same try-except statement in a while loop. However, now, when I use the function, instead of printing the same output previously, rather, it prints out the first value the user had input.
For example:
def valueCheck_Integer(userInput):
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
def main():
userValue = input("Please enter an integer: ")
valueCheck_Integer(userValue)
print("The integer you entered is: " + str(userValue))
main()
# Input: SADASD (A non-integer value)
# Output: "That is not an integer, try again: "
# Second-Input: SASASD
# Second-Output: "That is not an integer, try again: "
# Third-Input: 3
# Third-Output: SADASD (The first value that the user Input, instead of 3)
Can someone please explain to me why this happens, and some suggestions on how to fix it?
Thank you!
It's probably going to be easier to expect the function to get/check/return the integer rather than check input you already have. You can pass it the string to use for asking for the value (you could also pass the error string). It will keep asking until it's successful and then return the number you want:
def get_integer(question):
while(True):
try:
return int(input(question))
except ValueError:
question = "That is not an integer, try again:"
def main():
userValue = get_integer("Please enter an integer: ")
print("The integer you entered is: " + str(userValue))
main()
It is because of you are printing userValue instead of userInput.
I used return make it easier. So the code will be like this
def valueCheck_Integer(userInput):
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
return userInput
def main():
userValue = input("Please enter an integer: ")
print("The integer you entered is: " + str(valueCheck_Integer(userValue)))
main()
You can make your code smaller like this:
def valueCheck_Integer(userInput):
while not(userInput.isdigit()):
userInput = input("That is not an integer, try again: ")
return userInput
def main():
userValue = input("Please enter an integer: ")
print("The integer you entered is: " + str(valueCheck_Integer(userValue)))
main()
First off, Good Question.
To understand what is going on, we first have to talk about scope of a variable.
When you define a variable outside a function, it becomes something called a global variable. This basically means that you can access it from anywhere in your code. When you define the variable within a function, it becomes a local variable. This means that it is only accessible from within your function. Finally, when a function gets passed in a variable, it gets its own local copy of the variable to work with.
Now let's look at your code.
when you call valueCheck_Integer(userInput): the function gets its own copy of userInput to work with. thus all the changes that the function does modifies the local userInput while the global userInput stays the same. As such, when the user enters a correct answer, the global userInput is the one that gets printed and the changes the function makes to local userInput is lost.
So, how can we fix this?
There are two main methods:
1)Using the global keyword
def valueCheck_Integer(userInput):
global userInput
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
This keyword asks the function to modify the global userInput
2)Returning a value
def valueCheck_Integer(userInput):
while(True):
try:
userInput= int(userInput)
break
except:
userInput = input("That is not an integer, try again: ")
return userInput
def main():
userValue = input("Please enter an integer: ")
print("The integer you entered is: " + str(valueCheck_Integer(userValue)))
main()
This works by returning the local copy of userInput and modifying global userInput to equal local userInput
The second code I used was from
Osadhi Virochana Jayasinghe Si's answer.
It's because, if you see your line of code where you print the final output -:
print("The integer you entered is: " + str(userValue))
you will realise that the value you are printing is the one you take the first time from the input function. But this is not the value you have been working on to achieve in your other function.
So for you to rather get that value, the function in some way has to return it back to you.
For this you should allow the function to return the value in the last line.
like so -:
return userInput
and then change the line where you call function so it saves the value returned.
like so -:
userValue = valueCheck_Integer(userValue)
Also as mentioned by others using the global keyword you can define the variable in global scope.
But this is really not a good practice until really needed as it can increase the amount of space that the var is taking, before the variable only took the space for a limited time for when the function is called, but now the variable takes space throughout the time the program runs.
While return will not do so as it will only return the value and once assigned to the already defined variable it will remove the returned value from space.
This should hopefully fix your problem.
I hope this helps.
And also hope that you're safe during the time of this ongoing pandemic.
I am new to python and trying to write a program that requires the user to guess a number, 1 - 6 and then they are told if they guessed right or not. However, even when the user guesses right the else statement is still returned.
I apologise for the beginner question, although this really has me stuck because the 'guess' variable is being assigned correctly, I tested this by moving the print("Your guess was: ",guess) outside of the function and executed after the function was called which always returned with the same value that the user inputs.
#Function to take guess
def userGuess (guess):
guess = input("Take a guess.\n")
print("Your guess was: ",guess)
return guess
#Define Variables
diceNum = random.randint(1,6)
guess = 0
#Call Function
guess = userGuess(guess)
#Check answer
if guess == diceNum:
print("You guessed right!, the number was: ",diceNum)
else:
print("You did not guess it right, the number was: ",diceNum)
You need to convert the user input to an integer prior to comparing:
guess = int(input("Take a guess.\n"))
If you want an explanation as to why your if statement returned false for a comparison between an integer and a string, take a look at this question.
The assignment was to make a guessing game where the parameter is the answer. At the end if the person gets it right, it prints a congratulatory statement and returns the number of tries it took, if they type in quit, it displays the answer and tries == -1. other than that, it keeps looping until they get the answer correct.
def guessNumber(num):
tries = 1
while tries > 0:
guess = input("What is your guess? ")
if guess == num:
print ("Correct! It took you" + str(tries)+ "tries. ")
return tries
elif guess == "quit":
tries == -1
print ("The correct answer was " + str(num) + ".")
return tries
else:
tries += 1
When i run it, no matter what i put in it just keeps asking me for my guess.
Since you called your variable num so I'm guessing it's a integer, you were checking equality between an integer and a string so it's never True. Try changing the num to str(num) when comparing, so:
def guessNumber(num):
tries = 1
while tries > 0:
guess = input("What is your guess? ")
if guess == str(num):
print ("Correct! It took you {0} tries. ".format(tries))
return tries
elif guess == "quit":
tries = -1
print ("The correct answer was {0}.".format(num))
return tries
else:
tries += 1
Is the code properly indented?
The body of the function you are defining is determined by the level of indentation.
In the example you pastes, as the line right after the def has less indentation, the body of the function is 'empty'.
Indenting code is important in python
Additionally, for assigning one value to a variable you have to use a single '=', so the:
tries == -1
should be
tries = -1
if you want to assign the -1 value to that variable.
I started learning to code this week so I'm playing around with small programs that I'm creating to try to get a better understanding of how it work.
One of the programs I made is a Pig Latin translator that loops until the user exits. The program works but the logic isn't making any sense to me.
pyg = "ay" #Pig Latin words end with ay.
def translate(): #Creating a function.
original = input("Enter a word: ").lower() #Ask for input then convert to lower.
if len(original) > 0 and original.isalpha() : #isalpha() verifies only abc's and more than one letter.
first = original[0] #Assigns the first letter of the string to first.
latin = original[1:] + first + pyg #Adds original starting at 2nd letter with first and pyg.
print(latin)
else:
print("You did not enter a valid word, please try again.")
translate() #If you did not enter valid word, then call function again until you do.
translate() #Don't forget to actually call the function after you define it.
#Set run to False.
#Can be set to True if while (run != True) is set to while (run == True).
run = False
#Defining cont(). Ask for imput and error handling.
def cont():
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y" :
run = True
elif loop == "n" :
run = False
print("Thank you for using this program, have a nice day!")
exit()
else :
print("You did not enter a valid response, please try again.")
cont()
cont()
#Infinite loop as long as run is not equal to True.
while (run != True) :
translate()
cont()
My question is, why does this program work? I set run to False and I set the loop to run as long as run != True. No problem there, however when I defined cont(), I set run to take on the value True if the user inputs "y". True != True should be False (if I understand correctly) and the loop should end, but instead it is working as I wanted it to.
Is this a coding mistake that I've made or am I just thinking about this the wrong way? Thank you in advance.
Edit: Thank you very much to everyone that answered. I hadn't learned about local and global variables yet.
To expand on what others have already stated, run on these lines
if loop == "y" :
run = True
elif loop == "n" :
run = False
are not referring to the same run defined by
#Can be set to True if while (run != True) is set to while (run == True).
run = False
run in the cont function is a local variable to your function, not the globaly defined run.
There are a couple (at least) ways to fix this. The preferred (imo) way to do it is have cont return a new value to be assigned to run. That would look like
#Defining cont(). Ask for imput and error handling.
def cont(_run):
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y" :
return _run
elif loop == "n" :
return not _run
else :
print("You did not enter a valid response, please try again.")
return cont(_run)
...
#Infinite loop as long as run is not equal to True.
while (run != True) :
translate()
run = cont(run)
The other (less preferred) way would be to use the global run variable inside of your cont function. This is achieved using the global keyword.
That would look like this:
#Defining cont(). Ask for imput and error handling.
def cont():
global run
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y" :
run = True
elif loop == "n" :
run = False
print("Thank you for using this program, have a nice day!")
exit()
else :
print("You did not enter a valid response, please try again.")
cont()
** Couple side notes
In my first example I return _run when the value is y and not _run when the value is n. This allows you to change you initial run value to be True, and change the while condition without having to change the cont function itself.
You don't need to actually change the run value at all if you use the global and the user enters n since you exit before the function returns.
You might be better off changing your if conditional checks to
if loop in ("yes", "y"):
if loop in ("no", "n"):
since lots of people don't read full instructions :)
The run inside the cont function is a local variable. Changing its value has no effect on the global variable that the while loop refers to.
I think this is probably because of the scope of your run variable; because you're not returning run from your cont function. I believe what your != True check sees is always going to be False outside of that function, though obviously you can successfully end the program within the function.
The problem is that the run variable defined in cont() is not the same as the run variable defined in the global scope. (If you aren't sure what I mean by that you might want to look at https://docs.python.org/3.4/tutorial/classes.html#python-scopes-and-namespaces. Perhaps a better approach for your code would be to have cont() return True or False. It is also more intuitive and readable to use True for when you want to continue. Here's how I would rewrite it.
pyg = "ay" #Pig Latin words end with ay.
def translate(): #Creating a function.
original = input("Enter a word: ").lower() #Ask for input then convert to lower.
if len(original) > 0 and original.isalpha() : #isalpha() verifies only abc's and more than one letter.
first = original[0] #Assigns the first letter of the string to first.
latin = original[1:] + first + pyg #Adds original starting at 2nd letter with first and pyg.
print(latin)
else:
print("You did not enter a valid word, please try again.")
translate() #If you did not enter valid word, then call function again until you do.
#Defining cont(). Ask for imput and error handling.
def cont():
while True:
loop = input("Would you like to convert another word? (y/n): ").lower()
if loop == "y":
return True
elif loop == "n":
print("Thank you for using this program, have a nice day!")
return False
else :
print("You did not enter a valid response, please try again.")
translate()
while cont():
translate()