In a nutshell:
At the end of my program, there is a need to compare two integers whose results are inside the function itself. When I execute, I get undefined variable error.
Actually:
I am creating a hand cricket python script which we usually play as a duo. At last both the scores of the opponents are compared and the greatest wins.
The operation with the variables are inside of a function, but when called outside the function, undefined variable error shows up. Help please?
import random
while True:
pc_b_or_b = 0 #PC probability
#User Bowling module
def Bowl():
bat_PC = 0
User_bowl = 0
scoreofpc = 0
ScorePC = 0
while True:
bat_PC = random.randrange(1,11) #Random int gen
User_bowl = int(input("Your turn to bowl: ")) #int from user
if User_bowl<1 or User_bowl>10: #Fool proofing user must not keep less than 1 or gr8 than 10
print("Wrong number")
continue
if User_bowl == bat_PC: # Check if user == pc and out
print()
print("PC Out!")
print("PC Score:",scoreofpc)
break
else: #Continuation
print("Escape for PC. PC kept",bat_PC)
scoreofpc += bat_PC
print("Score:",scoreofpc)
ScorePC = scoreofpc
#User batting module
def User_Batting():
a = 0
score = 0
ManScore = 0
while True:
b = random.randrange(1,11) #Same as above but User is batting and pc randome int gen
a = int(input("Your turn to bat: ")) #But here if user int == pc then out for user
if a<1 or a>10:
print("Wrong number")
continue
if a==b:
print()
print("Out")
print("Score:",score)
break
else:
print("Escape! PC =",b)
score +=a
print("Score:",score)
ManScore = score
Actually Some more code comes here I've reduced to just these as said by StackOverflow
Main problem here, variable not defined, all other modules working perfectly
ScorePC1 = ScorePC
ManScore2 = ManScore
if ScorePC1 > ManScore2:
print("PC won the match by scoring",Score_of_PC)
elif ScorePC1 < ManScore2:
print("You won the match by scoring",User_Score)
else:
print("Your Score and PC score matched!")
quitter = input("Do you wanna Quit? Y/N? ")
if quitter == "yes" or quitter == "y" or quitter == "Y":
print("Thank You for playing!")
print("Script created by ***Techno-Sachin***")
quit()
elif quitter == "n" or quitter == "no" or quitter == "N":
print("Playing again..")
continue
else:
print("It's a wrong input. Try again")
Expectaion:
At last it is expected to print the statements inside if ScorePC1 and ManScore2 comparisons.
Error:
The output is Big, but cut out to focus on the problem itself>
PC Out! PC Score: 38 Traceback (most recent call last): File
"C:\Users\E.sachin\Documents\HTML5\Python Scripts\Hand_cricket20.py",
line 164, in
ScorePC1 = ScorePC NameError: name 'ScorePC' is not defined
Try replacing this - ScorePC1 = ScorePC with global ScorePC1 then use it as normal by referencing it's name ScorePC anywhere.
using global keyword before a varible name makes the variables's scope global and therefore enables the access to it from outside or inside a function.
also put the same inside the function definition like
def Bowl():
global ScorePC1
use it for both of your variables ScorePC1 and ManScore
You should always return values from your function. In this case you could return scoreofpc and score from the two functions. Your code would look like this:
def bowl():
#your code
return scoreofpc
def user_batting():
#your code
return score
Score1 = bowl()
Manscore = user_batting()
Alternatively, you could use Global Variables. But they are not advisable, infact, they're evil.
The variable ScorePC is declared inside the function Bowl() , by doing so the scope of the variable is within the Bowl() meaning it cannot be accessed from outside of the function. If you want to access it outside of the function declare it outside, which is not a good design. The better design is to return the value from the function like #irfanuddin answer.
I did some modifications also.
import random
def Bowl():
global ScorePC
bat_PC = 0
User_bowl = 0
scoreofpc = 0
ScorePC = 0
while True:
bat_PC = random.randrange(1,11) #Random int gen
User_bowl = int(input("Your turn to bowl: ")) #int from user
if User_bowl<1 or User_bowl>10: #Fool proofing user must not keep
less than 1 or gr8 than 10
print("Wrong number")
continue
if User_bowl == bat_PC: # Check if user == pc and out
print()
print("PC Out!")
print("PC Score:",scoreofpc)
break
else: #Continuation
print("Escape for PC. PC kept",bat_PC)
scoreofpc += bat_PC
print("Score:",scoreofpc)
ScorePC = scoreofpc
#User batting module
def User_Batting():
a = 0
score = 0
ManScore = 0
while True:
b = random.randrange(1,11) #Same as above but User is batting
and pc randome int gen
a = int(input("Your turn to bat: ")) #But here if user int == pc then out
for user
if a<1 or a>10:
print("Wrong number")
continue
if a==b:
print()
print("Out")
print("Score:",score)
break
else:
print("Escape! PC =",b)
score +=a
print("Score:",score)
ManScore = score
# Main probem here, variable not defined
# All other modules wotking perfectly
ScorePC1 = ScorePC
ManScore2 = ManScore
if ScorePC1 > ManScore2:
print("PC won the match by scoring",ScorePC1)
elif ScorePC1 < ManScore2:
print("You won the match by scoring", ManScore2)
else:
print("Your Score and PC score matched!")
quitter = input("Do you wanna Quit? Y/N? ")
if quitter == "yes" or quitter == "y" or quitter == "Y":
print("Thank You for playing!")
print("Script created by ***Techno-Sachin***")
exit()
elif quitter == "n" or quitter == "no" or quitter == "N":
print("Playing again..")
play()
else:
print("It's a wrong input. Try again")
def play():
Bowl()
User_Batting()
play()
If the reduced code is inside the main function,then the problem is that ScorePcvariable is not defined because it is a local variable inside the Bowl() function because you initialized it there.You cant access its name in the main() function.
To fix this you can either return it from Bowl() to the ScorePc or set it to be global as Himanshu said.
def Bowl():
#code..
return ScorePc
def main():
ScorePc=Bowl()#this will store the returned value to ScorePc
or
def Bowl():
global ScorePc
You should probably read more about this to understand better how it works.
Here are some links:
geeksforgeeks
python documentation
You have defined ScorePC and ManScore inside functions which turns out they are only usable inside that function unless you do one of the two things.
You can make the variable a function attribute.
Example:
def Bowl():
Bowl.ScorePC = 0
def User_Batting():
User_Batting.ManScore = 0
You can make the variable global.
Example:
def Bowl():
global ScorePC
ScorePC = 0
def User_Batting():
global ManScore
ManScore = 0
If you want to use them in other files. You have to import the file there where you want to use.
Here you will find some good examples:
Using global variables between files?
This can be done by using global keyword in the function. See below for your reference
def Bowl():
global ScorePc
....
def User_Batting():
global ManScore
....
But, I would suggest returning the value from the function. if your function is carrying multiple values, then do return as an array.
Related
import time
global score
score = 0
The score above doesn't work inside or outside the functions.
donea = False
doneb = False
def restart():
print('Do you want to restart?')
restartyn = input().lower()
if restartyn == 'yes' :
main()
else :
print('Ok goodbye.')
time.sleep(2)
quit()
def main():
print('Hello welcome to my quiz!')
time.sleep(1)
print('Would you like subject A, B or C?')
subject = input().lower()
if subject == 'a' :
print('Your choice was \'Maths\'')
time.sleep(1)
print('So what is 5 * 70?')
Aanswer = int(input())
if Aanswer == 350 :
score += score
When I try to add to the score it has an error saying it was referenced before assignment even though I assigned it above outside the function.
print('Well done your score is now ' + str(score) + '!')
donea = True
restart()
else :
print('Sorry that is the wrong answer')
time.sleep(2)
restart()
elif subject == 'b' :
print('Your choice was \'science\'')
time.sleep(1)
print('What is the symbol for the element \'gold\'?')
Banswer = input().lower()
if Banswer == 'au' :
score += score
print('Well done your score is now ' + str(score) + '!')
doneb = True
restart()
else :
print('Sorry that is the wrong answer.')
time.sleep(2)
restart()
main()
You need to specify inside your main() function that the variable score you are using is the global one. As it is, score is a newly created local variable
def main():
global score
Try adding this line to your function.
I'm learning Python and can't get my bool to change from "True" to "False" in my replay function. I've scoured StackOverflow, but can't find an answer.
I've tried canPlay = False and canPlay = not canPlay. But that's not working.
Any suggestions?
import random
from random import randint
# welcome message
print("Welcome to the number guessing game!")
# get the random seed
seedValue = input("Enter random seed: ")
random.seed(seedValue)
canPlay = True
def play():
randomNumber = randint(1, 100)
numberOfGuesses = 1
guessValue = ""
while guessValue != randomNumber:
# prompt the user for a guess
guessValue = int(input("\nPlease enter a guess: "))
# provide higher/lower hint
if guessValue == randomNumber:
print(f"Congratulations. You guessed it!\nIt took you {numberOfGuesses} guesses.")
elif guessValue > randomNumber:
print("Lower")
else:
print("Higher")
# increment the count
numberOfGuesses += 1
def replay():
playAgain = input("\nWould you like to play again (yes/no)? ")
if playAgain == "no":
canPlay = False # not changing values
canPlay = not canPlay # this doesn't work either
print("Thank you. Goodbye.")
while canPlay == True:
play()
replay()
with a global keyword inside the reply() function, you can change the value of the canPlay variable in the global namespace which is then needed in the condition of while statement while canPlay == True::
def replay():
global canPlay # <------------------ Here
playAgain = input("\nWould you like to play again (yes/no)? ")
if playAgain == "no":
canPlay = False # not changing values
canPlay = not canPlay # this doesn't work either
print("Thank you. Goodbye.")
If you do not insert that line, canPlay would be a local variable for reply() function, so it can't change global variables or be accessed by other statements outside the reply function.
I'm currently trying to run a program where the user inputs a word and then after they input the first word, the program will ask if they want to continue putting words. Once the user replies "no", the program will generate the list of words that has been input. I seem to be having trouble calling the array for my code below:
def word():
w1 = input("Please enter a word: ")
group = []
group.append(w1)
decide = input("Do you want to continue? yes/no: ")
if (decide == "yes"):
return -1
elif (decide == "no"):
return 1
while (True):
crit = word()
if (crit == -1):
continue
elif (crit == 1):
print("words are: ", group)
break
How I can make this work properly?
I think you meant to pass the list into the function:
def word(group):
w1 = input("Please enter a word: ")
group.append(w1)
decide = input("Do you want to continue? yes/no: ")
return decide == "yes"
group = []
while True:
crit = word(group)
if crit:
continue
else:
print("words are: ", group)
break
The array ‘group’ is defined inside the function word(). This means if the function is returned, the list ‘group’ disappears also.
You can either
Use global variable
Define group outside the function (in this case, at the top) and use that global list inside the function. I.e. add the line
global group in the first line of the function.
However, using global variable when not needed is not so recommandable.
Define group list outside the function and pass it to the function as an argument
Instead of def word(), use def word(group) and pass the list to the function when calling the function.
group = []
def word():
w1 = input("Please enter a word: ")
group.append(w1)
decide = input("Do you want to continue? yes/no: ")
if (decide == "yes"):
return -1
elif (decide == "no"):
return 1
while (True):
crit = word()
if (crit == -1):
continue
elif (crit == 1):
print("words are: ", group)
break
The variable group is not available outside the function.
A variable created outside of a function is global and can be used by anyone.
I'm having a bit of trouble with changing a variable value (canteen) to make it so that it runs from 3 to 0. I'm not sure why the value of canteen does not go to less than 2 every time I hit the "1" key. How do I make it so that the value of canteen becomes zero when the player hits the "1" key 3 times?
# Global Variables
km_travelled = 0
thirst = 0
camel_tiredness = 0
natives_travelled = -20 # Player always starts 20 km away from player once player reaches checkpoint
def introduction():
print("Welcome to Camel!")
print("You have stolen a camel to make your way across the great Mobi desert")
print("The natives want their camel back and are chasing you down! Survive ")
print("your desert trek and out run the natives \n \n")
def choices():
print("1. Drink from your canteen.")
print("2. Ahead at moderate speed.")
print("3. Ahead at full speed.")
print("4. Stop for the night.")
print("5. Status check.")
print("9. Quit \n")
def questions(answer):
canteen = 3
if "9" in answer:
print("GAME EXIT.")
done = True
elif "1" in answer:
print("You drank from the canteen")
canteen = canteen - 1
print(canteen)
def main():
# Global variables
done = False
# Go through once
introduction()
while not done:
choices()
answer = input("What is your choice? ")
questions(answer)
if __name__ == '__main__':
main()
The canteen variable is locally scoped, to the questions function. And each time you run that function, it is reinitialised to the value 3. Since the if statement is only executed once inside the function, it will never go lower than 2.
One simple way to solve this - even though it's not good practice - is to have canteen as a global variable. Put canteen = 3 outside any function, alongside the rest of your globa variables. Remove that statement from the questions function, and replace it with global canteen so that Python knows you are referring to the global variable when you alter it within the function.
Note that you will have a similar problem with the done variable, and can consider making this global too.
And finally, as I hinted at, global variables are bad to have in any program that isn't extremely simple - because they can be affected by everything in the program, and therefore make it very hard to figure out what is going on. There are a number of alternative ways to approach constructing complex programs which avoid global variables, which I would encourage you to look at. Using classes (which hold state internally, rather than globally) is one such way which is well-supported in Python.
Since while statement evaluates to true, the value 3 is assigned to the variable canteen after every choice. You can replace canteen = 3 with global canteen and assign the variable canteen outside it's function.
If you want to avoid using global, you can use a dictionary like this example:
def questions(answer, canteen):
if "9" in answer:
print("GAME EXIT.")
done = True
elif "1" in answer:
print("You drank from the canteen")
canteen['c'] = canteen['c'] - 1
print(canteen['c'])
def main():
# Global variables
done = False
canteen = {'c': 3}
# Go through once
introduction()
while not done:
choices()
answer = input("What is your choice? ")
questions(answer, canteen)
It is because you're defining canteen = 3 at the beginning of your questions() loop. You should define it once, with your global variables.
# Global Variables
km_travelled = 0
thirst = 0
camel_tiredness = 0
natives_travelled = -20 # Player always starts 20 km away from player once player reaches checkpoint
canteen = 3 # Define it here, as a global variable
### Truncated ###
def questions(answer):
# canteen = 3 # Don't define here
global canteen # but refer to the top one here
if "9" in answer:
print("GAME EXIT.")
done = True
elif "1" in answer:
print("You drank from the canteen")
canteen = canteen - 1
print(canteen)
def main():
# Global variables
done = False
# Go through once
introduction()
while not done:
choices()
answer = input("What is your choice? ")
questions(answer)
if __name__ == '__main__':
main()
the error it returns is:
NameError: name 'lives' is not defined
I know the code isn't as efficient as possible, this is one of my first projects, however whatever i try to do this error pops up, I've tried making a global for it but that didn't help. I would really appreciate some help with this, thanks!
import random
import time
def main():
global guess,rand_num
win = False
rand_num = 45
lives = 10
while lives > 0 and win == False:
guess = int(input("Guess a number!"))
compare()
print("Well done!")
time.sleep(3)
def compare():
global lives,win
if guess == rand_num:
print("You guessed correct!")
win = True
elif guess > rand_num:
print ("Guess lower!")
lives = lives - 1
else:
print ("Guess higher!")
lives = lives - 1
def repeat():
replay = input("would you like to play again? Y/N")
if replay == "Y":
print("enjoy!")
main()
elif replay == "N":
"Goodbye then, hope you enjoyed!"
time.sleep(3)
os._exit
else:
print("please enter Y or N")
repeat()
main()
repeat()
EDIT: putting global lives inside main() returns the error:
UnboundLocalError: local variable 'lives' referenced before assignment
You need to define the variable "lives" outside of the function main, then any function where you want to reference that global variable you say "global lives." When you are in a function and assign a value to a variable, it assumes it is in the local scope. using "global lives" tells that function to look to the global scope as the reference of lives.
import random
import time
lives = 10
win = False
guess = 0
rand_num = 45
def main():
global guess, rand_num, lives, win
win = False
rand_num = 45
lives = 10
while lives > 0 and win == False:
guess = int(input("Guess a number!"))
compare()
print("Well done!")
time.sleep(3)
def compare():
global guess, rand_num, lives, win
if guess == rand_num:
print("You guessed correct!")
win = True
elif guess > rand_num:
print ("Guess lower!")
lives = lives - 1
else:
print ("Guess higher!")
lives = lives - 1
def repeat():
replay = input("would you like to play again? Y/N")
if replay == "Y":
print("enjoy!")
main()
elif replay == "N":
"Goodbye then, hope you enjoyed!"
time.sleep(3)
os._exit
else:
print("please enter Y or N")
repeat()
main()
repeat()
You didn't declare lives to be global inside main(), so it is local to that function.
def main():
global guess, rand_num, lives
...
When you declare it inside function they are only available in that function scope, so declare global variables outside functions and code will work fine.
import random
import time
guess = None
random_num = None
lives = 3
win = False
def main():
global guess,rand_num
win = False
rand_num = 45
lives = 10
while lives > 0 and win == False:
guess = int(input("Guess a number!"))
compare()
print("Well done!")
time.sleep(3)
def compare():
global lives,win
if guess == rand_num:
print("You guessed correct!")
win = True
elif guess > rand_num:
print ("Guess lower!")
lives = lives - 1
else:
print ("Guess higher!")
lives = lives - 1
def repeat():
replay = input("would you like to play again? Y/N")
if replay == "Y":
print("enjoy!")
main()
elif replay == "N":
"Goodbye then, hope you enjoyed!"
time.sleep(3)
os._exit
else:
print("please enter Y or N")
repeat()
main()
repeat()
And now this works fine. For more info about gloval vs local variables you can read: http://www.python-course.eu/global_vs_local_variables.php