I am making an rpg type thing with python and I made a few functions but I need to call variables that were stated and altered inside of a separate function. How would I be able to call a variable inside a function.
My Code:
import time
def title():
print("Hello Welcome To Elvoria")
time.sleep(1)
print("Choose Your Gender, Name, And Race")
time.sleep(1)
def gnd():
Gender = input("""Male, Female, Or NonBinary?
""")
if Gender == ("Male"):
genderin = 'Male'
elif Gender == ("Female"):
genderin = 'Male'
elif Gender == ("NonBinary"):
genderin = 'Male'
else:
gnd()
def nm():
namein = input("""What Is Your Character's Name?
""")
print("Welcome To Elvoria "+namein+"")
def rac():
print("""The Race Options Are:
Elf-Good With Archery And Light Armor
Kelner-Good With Two Handed Weapons And Heavy Armor
Human-Good With Bows And Stealth
Mageine-Good With Magic And Speed""")
time.sleep(1)
racin = input("""Now Choose A Race
""")
if racin == ("Elf"):
print ("You Are Now A " + genderin + racin +" Named" + namein + "")
elif racin == ("Kelner"):
print ("You Are Now A " + genderin + racin +" Named" + namein + "")
elif racin == ("Human"):
print ("You Are Now A " + genderin + racin +" Named" + namein + "")
elif racin == ("Magein"):
print ("You Are Now A " + genderin + racin +" Named" + namein + "")
else:
print ("You Are Now A " + genderin + racin +" Named" + namein + "")
title()
time.sleep(1)
gnd()
time.sleep(1)
nm()
time.sleep(1)
rac()
And The Error Code:
print ("You Are Now A " + genderin + racin +" Named" + namein + "")
NameError: name 'genderin' is not defined
Change your functions to return the result, and take the values they need as parameters:
def gnd() -> str:
gender = input("""Male, Female, Or NonBinary?
""")
if gender in ("Male", "Female", "NonBinary"):
return gender
return gnd()
def nm() -> str:
name = input("""What Is Your Character's Name?
""")
print(f"Welcome To Elvoria {name}")
return name
def rac(gender: str, name: str) -> str:
print("""The Race Options Are:
Elf-Good With Archery And Light Armor
Kelner-Good With Two Handed Weapons And Heavy Armor
Human-Good With Bows And Stealth
Mageine-Good With Magic And Speed""")
time.sleep(1)
race = input("""Now Choose A Race
""")
print (f"You Are Now A {gender} {race} Named {name}")
return race
When you call them, make sure to assign the values to variables so you can use them again:
title()
time.sleep(1)
gender = gnd()
time.sleep(1)
name = nm()
time.sleep(1)
race = rac(gender, name)
You have 2 options:
You could create a global variable, and define that using the global statement in your function, so you can use the global value afterwards
You could pass a value to the function, and work with it (the better way, using global variables should be avoided)
Related
My function doesn't show the input number for number_served:
class Restaurant():
def __init__(self, name, cuisine):
self.name = name
self.cuisine = cuisine
self.number_served = 0
def describe_rest(self):
print("Welcome to " + self.name.title() + "!")
print("We serve the best " + self.cuisine.title() + " food!")
def open_rest(self):
print(self.name.upper() + " is OPEN now!")
def set_number_served(self, number_served):
print("We have served " + str(self.number_served)
+ " customers today.")
def increment_number_served(self, additional_served):
print("We have served " + str(self.number_served)
+ str(self.additional_served) + " customers today.")
restaurant = Restaurant('gamja', 'korean')
print("\n")
restaurant.describe_rest()
print("\n")
restaurant.open_rest()
restaurant.set_number_served(1000)
At the last line, restaurant.set_number_served(1000), I get "We have served 0 customers today." instead of 1000. What am I doing wrong here?
You forgot to set the instance variable in that routine. Simply add a line to do that.
def set_number_served(self, number_served):
self.number_served = number_served
print("We have served " + str(self.number_served)
+ " customers today.")
I am quite new to Python and I am having some trouble figuring out the following:
import random
import sys
print("Welcome to this Maths quiz.")
playerName = str(input("Please enter your name: "))
playerAge = int(input("Please enter your age: "))
if playerAge < 11:
print("This quiz is not for your age.")
sys.exit(0)
else :
print("Great! Let's begin.\n")
quizQuestions = ["9(3+8)", "7+9*8", "(9+13)(9-5)", "50*25%", "104-4+5*20"]
quizAnswers = ["99", "79", "88", "12.5", "0"]
quizSync = list(zip(quizQuestions, quizAnswers))
random.shuffle(quizSync)
quizQuestions, quizAnswers = zip( * quizSync)
questionNumber = 1
quizScore = 0
def displayQuestion(quizQuestions, quizAnswers, questionNumber, quizScore):
print("Question " + str(questionNumber) + ": " + quizQuestions[questionNumber - 1] + "\n")
questionAnswer = str(input())
if questionAnswer == quizAnswers[questionNumber - 1]:
print("\nCorrect!\n")
quizScore += 1
else :
print("\nIncorrect! The answer is: " + quizAnswers[questionNumber - 1] + "\n")
while questionNumber < 6:
displayQuestion(quizQuestions, quizAnswers, questionNumber, quizScore)
questionNumber += 1
print("You have a total score of: "+str(quizScore))
I would like the variable "quizScore" in the function "displayQuestion" to increase by one if the player gets a question right. However, after the quiz is finished, the print function at the end always prints the score is 0 even if the player gets questions right.
You have to declare it as a global variable inside the function so that it can modify the variable in the global scope
def displayQuestion(quizQuestions, quizAnswers, questionNumber):
global quizScore
...
quizScore += 1
That being said, you should generally avoid global variables if you can and try to redesign your program to either pass the variables along as arguments and return values, or use a class to encapsulate the data.
Although this won't be the shortest answer, which is to use another global variable. It instead will show you how to avoid using global variables (which are considered harmful) by using Object Oriented Programming (OOP). To accomplish this, most of the code in your question can be encapsulated into a single class named MathQuiz below.
Besides getting rid of almost all global variables, it also provides a usable template for you to create any number of independent math quizzes.
import random
import sys
class MathQuiz:
def __init__(self, questions, answers):
quizSync = list(zip(questions, answers))
random.shuffle(quizSync)
self.quizQuestions, self.quizAnswers = zip(*quizSync)
self.quizScore = 0
print("Welcome to this Maths quiz.")
self.playerName = str(input("Please enter your name: "))
self.playerAge = int(input("Please enter your age: "))
if self.playerAge > 10:
print("Great! Let's begin.\n")
else :
print("This quiz is not for your age.")
sys.exit(0)
def run(self):
for questionNumber in range(len(self.quizQuestions)):
self._displayQuestion(questionNumber)
print("You have a total score of: " + str(self.quizScore))
def _displayQuestion(self, questionNumber):
print("Question " + str(questionNumber) + ": "
+ self.quizQuestions[questionNumber-1]
+ "\n")
questionAnswer = str(input())
if questionAnswer == self.quizAnswers[questionNumber-1]:
print("\nCorrect!\n")
self.quizScore += 1
else :
print("\nIncorrect! The answer is: "
+ self.quizAnswers[questionNumber-1]
+ "\n")
quiz = MathQuiz(["9(3+8)", "7+9*8", "(9+13)(9-5)", "50*25%", "104-4+5*20"],
["99", "79", "88", "12.5", "0"])
quiz.run()
This question already has answers here:
UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)
(14 answers)
Closed 7 years ago.
I'm half way through a chance fighting program and I wanted to shorten my work by using functions. But I got the error,
UnboundLocalError: local variable 'Ehealth' referenced before assignment
This is my code so far...
import random
import sys
import time
print ("You encounter a wild boar.")
time.sleep(1)
Weapon = input("Do you use a 'Bow and Arrow' or a 'Sword'.")
Ehealth = (100)
health = (100)
Ealive = (1)
alive = (1)
def attack():
damage = (random.randrange(5,21))
time.sleep(3)
print ("You attack the Boar for " + str(damage) + " attack points.")
time.sleep(3)
Ehealth = (Ehealth - damage)
print ("The Boars health is at " + str(Ehealth) + ".")
time.sleep(3)
if Weapon == ("Bow and Arrow"):
Emiss = (20) #out of 40
miss = (15) #out of 40
Espeed = (random.randrange(1,11))
speed = (random.randrange(1,11))
if Espeed > (speed):
print ("The Boar is faster than you so he attacks first.")
time.sleep(3)
print ("Your health is at " + str(health) + " and the Boars health is at " + str(Ehealth) + ".")
time.sleep(3)
while (alive == 1): #1 = alive, 2 = dead
Emiss = (random.randrange(1,41))
if Emiss < (20):
print ("The Boar missed.")
attack()
if Ehealth > (0):
alive = (1)
continue
else:
alive = (2)
print ("You Won!")
sys.exit()
Edamage = (random.randrange(5,16))
print ("The Boar attacks you with " + str(Edamage) + " attack points.")
time.sleep(4)
health = (health - Edamage)
time.sleep(4)
print ("Your health is at " + str(health) + ".")
time.sleep(4)
if alive <= (0):
print ("You died...")
sys.exit()
attack()
if Ehealth > (0):
alive = (1)
else:
alive = (2)
print ("You Won!")
sys.exit()
I got the error at the line on
Ehealth = (Ehealth - damage)
Any help would be appreciated.
You are trying to use the variable that lies outside of the function. In any case I'd do this:
def attack():
global Ehealth
damage = (random.randrange(5,21))
time.sleep(3)
print ("You attack the Boar for " + str(damage) + " attack points.")
time.sleep(3)
Ehealth = (Ehealth - damage)
print ("The Boars health is at " + str(Ehealth) + ".")
time.sleep(3)
Do note the 'global' keyword is needed if you're changing the value of the variable.
You are assigning to that variable in the attack() function:
Ehealth = (Ehealth - damage)
Assignment in a function makes a name local; you appear to expect it to be a global instead. Because it is a local, and hasn't been assigned to in the function before that line, you get your error.
Tell Python to treat it as a global instead. Add this line to your function (as the first line is probably a good idea):
global Ehealth
This tells the Python compiler to treat Ehealth as a global within your function, even though you assign to it.
Ehealth is global variable, If you just print it then there wont be any error But when you try to modify it, function consider it as local variable.
Solution :-
def attack(Ehealth=Ehealth):
I am trying to get my program to limit what the user can type in. It keeps returning an "Expected an indented block" error from my code below.
deliverydetails = input("Is your order for delivery?\n Press 1 for delivery. Press 2 for pickup")
if deliverydetails == "1":
## def delivery ():
print ("Order for Delivery")
customerfirstname = " "
while len(customerfirstname) <3 or len(customerfirstname)>30 or customerfirstname.isalpha() != True:
customerfirstname = input("Customer First Name: ** must be 4 characters long + " ")
while len(customersurname) < 3 or len(customersurname) > 30 or customerfirstname.isalpha() != True:
customersurname = input("Customer Surname:" + " ")
customerstreet = input("Street name:" + " ")
customerstreetnumber = input("Street number:" + " ")
customercity = input("City:" + " ")
customersuburb = input("Suburb (If none, leave blank):" + " ")
latestOrder.append(customerfirstname)
latestOrder.append(customersurname)
latestOrder.append(customerstreet)
latestOrder.append(customerstreetnumber)
latestOrder.append(customercity)
latestOrder.append(customersuburb)
Python uses indentation to group blocks of code. After the while statements, you want to indent the lines below it that should be executed inside the while loop.
Here are some other tips that may be useful:
- Use pylint to check your syntax. It will uncover a lot of errors that you would otherwise only find out during runtime.
- Use spaces to indent. Don't use tabs. That's a PEP 8 style recommendation
Here is the corrected version of your code:
deliverydetails = input("Is your order for delivery?\n Press 1 for delivery. Press 2 for pickup")
if deliverydetails == "1":
## def delivery ():
print ("Order for Delivery")
customerfirstname = " "
customersurname = " "
while len(customerfirstname) <3 or len(customerfirstname)>30 or customerfirstname.isalpha() != True:
customerfirstname = input("Customer First Name: ** must be 4 characters long + " ")
while len(customersurname) < 3 or len(customersurname) > 30 or customerfirstname.isalpha() != True:
customersurname = input("Customer Surname:" + " ")
customerstreet = input("Street name:" + " ")
customerstreetnumber = input("Street number:" + " ")
customercity = input("City:" + " ")
customersuburb = input("Suburb (If none, leave blank):" + " ")
latestOrder.append(customerfirstname)
latestOrder.append(customersurname)
latestOrder.append(customerstreet)
latestOrder.append(customerstreetnumber)
latestOrder.append(customercity)
latestOrder.append(customersuburb)
Python uses intentation instead of {} or begin/end, so for example this line
while len(customerfirstname) <3 or len(customerfirstname)>30 or customerfirstname.isalpha() != True:
should be followed by an indented block. An indented block can be as short as a single line, usually you should indent it 4 spaces more than the while
Aside: it may be clearer to write that line as
while not (3 <= len(customerfirstname) <= 30 and customerfirstname.isalpha()):
Make sure to indent the lines that are part of the loop. That's the only way Python has to know what part you want to loop.
delivery_details = input("Is your order for delivery?\n Press 1 for delivery. Press 2 for pickup")
if delivery_details == "1":
print "Order for Delivery"
customer_first_name = ""
while len(customer_first_name) < 3 or len(customer_first_name) > 30 or not customer_first_name.isalpha():
customer_first_name = input("First name (must be 4 characters long): ")
customer_surname = input("Surname: ")
customer_street = input("Street name: ")
customer_street_number = input("Street number: ")
customer_city = input("City: ")
customer_suburb = input("Suburb (If none, leave blank): ")
latest_order.append(customer_first_name)
latest_order.append(customer_surname)
latest_order.append(customer_street)
latest_order.append(customer_street_number)
latest_order.append(customer_city)
latest_order.append(customer_suburb)
For what it's worth I've made some stylistic changes for readability. Some extra spacing, blank lines, and underscores in variable names make everything a bit easier on the eyes.
Ok! Basically, I have a variable being declared in one function, and I would like to use that variable in another function. I do not want to pass parameters, because I feel like there would be a simpler way to do this. This is my code:
#!/usr/bin/python
#import os
import time
print ("Hello and welcome to Pygame!")
time.sleep(1)
print ("Would you like to load? (\"Y/N\")")
def LON():
loadOrNew = raw_input()
if loadOrNew == "N":
hp = 100
strhp = str(hp)
lvl = 1
strlvl = str(lvl)
atk = 5
stratk = str(atk)
defn = 2
strdefn = str(defn)
fout = open("pygame.dat", "w")
fout.write (strhp)
fout.write("\n")
fout.write(strlvl)
fout.write("\n")
fout.write(stratk)
fout.write("\n")
fout.write(strdefn)
fout.close()
FIRSTPLAY()
return
if loadOrNew == "Y":
fin = open("pygame.dat", "r")
hpstr = fin.readline()
lvlstr = fin.readline()
atkstr = fin.readline()
defstr = fin.readline()
hp = int(float(hpstr))
lvl = int(float(lvlstr))
atk = int(float(atkstr))
defn = int(float(defnstr))
fin.close()
return
if loadOrNew != "Y" and loadOrNew != "N":
print("Im sorry, what?")
LON()
return
return
def SAVE():
fout = open("pygame.dat", "w")
fout.write(hp)
fout.write(lvl)
fout.write(atk)
fout.close(defn)
return
def FIRSTPLAY():
print("man/woman?")
gender = raw_input()
if gender != "man" and gender != "woman":
print("Not valid gender.")
FIRSTPLAY()
print("KING - ")
print(" Young " + gender + ", you are herby my knight!")
time.sleep(1)
print(" My daughter, princess PYTHON, has been captured!")
time.sleep(1)
print(" You are to find her, and relieve this world of her captor!")
time.sleep(1)
print(" Some say this evil man's name is GAMEMAKER, but we really don't know.")
time.sleep(1)
print(" What do you think it is?")
captor = raw_input()
time.sleep(1)
print(" So you think it is " + captor + "?")
time.sleep(1)
print(" Very well, find " + captor + " ASAP!")
PLAY()
return
def PLAY():
print hp
print lvl
print atk
print defn
greenSlime(hp, lvl, atk, defn)
return
def greenSlime(php, plvl, patk, pdefn):
MHP = 10
MLVL = 1
MATK = 2
MDEF = 2
print "Green Slime - "
print " HP: 10"
print " LVL: 1"
print " ATK: 2"
print " DEF: 2"
print "ATK OR DEF?"
LON()
I would like to use hp, lvl, atk, and defn variables that were declared in the LON function, in the PLAY function. I'm sure there is a simpler way then passing parameters.
Just declaring a variable inside global will not work. The global keyword is to ask the interpreter not to treat something as a local (overriding a global variable with the same name) when assigning a value to it. What you need to do is define the variable at a scope above the functions which are supposed to share it. Note that you don't need to declare a variable global in function for read-only access. When the interpreter does not find the variable in local scope it automatically looks for it at outer scope. But in case of assignment statement, it creates a new local variable.
So what you want to do is :
hp = None
lvl = None
atk = None
defn = None
def LON():
global hp, lvl, atk, defn
# rest of LON
# rest of the functions
But I should warn you that globals are bad programming practice and passing parameters is the right way to do it.
Inside LON(), you can use the global statement:
def LON():
global hp, lvl, atk, defn
Then, assignments to those variables inside LON() will create global variables. Once the global variables are created, you can use them elsewhere (without needing a global statement). Note that anywhere you want to assign a new value to the global variable, you will need a corresponding global statement inside that function.
What you need to do is to move the functions into a python class. That way all functions inside the class can access the variables, without you needing to make them global.
You'd probably structure the code something like this:
#!/usr/bin/python
#import os
import time
print ("Hello and welcome to Pygame!")
time.sleep(1)
print ("Would you like to load? (\"Y/N\")")
class Game:
def InitialiseNewPlayer(self):
self.hp = 100
self.lvl = 1
self.atk = 5
self.defn = 2
def SavePlayer(self):
fout = open("pygame.dat", "w")
fout.write ( str(self.hp) )
fout.write("\n")
fout.write(str(self.lvl) )
fout.write("\n")
fout.write(str(self.atk) )
fout.write("\n")
fout.write(str(self.defn) )
fout.close()
def LoadPlayer(self):
fin = open("pygame.dat", "r")
self.hp = int(float(fin.readline()))
self.lvl = int(float(fin.readline()))
self.atk = int(float(fin.readline()))
self.defn = int(float(fin.readline()))
fin.close()
def LON(self):
while true:
loadOrNew = raw_input()
if loadOrNew == "N":
self.InitialiseNewPlayer()
self.SavePlayer();
self.FIRSTPLAY()
return
if loadOrNew == "Y":
self.LoadPlayer()
return
print("Im sorry, what?")
# Watch out as this is using a different format to the SavePlayer above!
def SAVE(self):
fout = open("pygame.dat", "w")
fout.write(self.hp)
fout.write(self.lvl)
fout.write(self.atk)
fout.close(self.defn)
def FIRSTPLAY(self):
print("man/woman?")
gender = raw_input()
if gender != "man" and gender != "woman":
print("Not valid gender.")
FIRSTPLAY()
print("KING - ")
print(" Young " + gender + ", you are herby my knight!")
time.sleep(1)
print(" My daughter, princess PYTHON, has been captured!")
time.sleep(1)
print(" You are to find her, and relieve this world of her captor!")
time.sleep(1)
print(" Some say this evil man's name is GAMEMAKER, but we really don't know.")
time.sleep(1)
print(" What do you think it is?")
captor = raw_input()
time.sleep(1)
print(" So you think it is " + captor + "?")
time.sleep(1)
print(" Very well, find " + captor + " ASAP!")
self.PLAY()
return
def PLAY(self):
print self.hp
print self.lvl
print self.atk
print self.defn
self.greenSlime()
def greenSlime(self):
MHP = 10
MLVL = 1
MATK = 2
MDEF = 2
print "Green Slime - "
print " HP: 10"
print " LVL: 1"
print " ATK: 2"
print " DEF: 2"
print "ATK OR DEF?"
game = Game()
game.LON()