I'm currently working on a town of salem-esc project for a class but I've ran into an issue. I have been trying to make it so that Suspect_ID is available globally but for some reason it is instead saying ("name 'Suspect_ID' is not defined", I'm tried making it outside of the statement with the rest of my global variables to no avail as well. Any suggestions would be helpful, and if any other information is needed feel free to ask, I hope you have better luck with this program than I am currently having.
def readinSuspects():
#local variables
global Suspect_name
Suspect_name=["","","","","","","","","",""]
global Suspect_age
Suspect_age=[0,0,0,0,0,0,0,0,0,0]
global Suspect_motive
Suspect_motive=["","","","","","","","","",""]
global Suspect_ID
Suspect_ID=[0,0,0,0,0,0,0,0,0,0]
global IsMurderer
IsMurderer=[False,False,False,False,False,False,False,False,False,False]
#subprogram body
file = open("suspects.txt","r")
for i in range(0,9):
Suspect_name[i],Suspect_age[i],Suspect_motive[i],
Suspect_ID[i]=file.readline().split(',')
return Suspect_name,Suspect_age,Suspect_motive,Suspect_ID,IsMurderer
edit: I'm now realising the issue may lie elsewhere so following is gonna be the program in it's entirety, it's far from finished and I am aware there are many other bugs etc.
import random
#Global variable
Guesses=[0]
Murderer=[0]
#Read In Function
def readinSuspects():
#local variables
global Suspect_name
Suspect_name=["","","","","","","","","",""]
global Suspect_age
Suspect_age=[0,0,0,0,0,0,0,0,0,0]
global Suspect_motive
Suspect_motive=["","","","","","","","","",""]
global Suspect_ID
Suspect_ID=[0,0,0,0,0,0,0,0,0,0]
global IsMurderer
IsMurderer=[False,False,False,False,False,False,False,False,False,False]
#subprogram body
file = open("suspects.txt","r")
for i in range(0,9):
Suspect_name[i],Suspect_age[i],Suspect_motive[i],
Suspect_ID[i]=file.readline().split(',')
return Suspect_name,Suspect_age,Suspect_motive,Suspect_ID,IsMurderer
#randomly assign murderer
readinSuspects(Suspect_ID)
Murderer = random.randint(0,9)
for i in range(0,9):
if Murderer == i:
#print Suspect_ID if working
print(Suspect_ID[i])
First of all your method readinSuspects() does not take parameters, but you invoke it with one argument - Suspect_ID which is not defined yet.
I have reworked your code so now it must work:
import random
#Global variable
Suspect_name = []
Suspect_age = []
Suspect_motive = []
Suspect_ID = []
IsMurderer = []
Guesses=[0]
Murderer=[0]
#Read In Function
def readinSuspects():
#local variables
global Suspect_name
Suspect_name=["","","","","","","","","",""]
global Suspect_age
Suspect_age=[0,0,0,0,0,0,0,0,0,0]
global Suspect_motive
Suspect_motive=["","","","","","","","","",""]
global Suspect_ID
Suspect_ID=[0,0,0,0,0,0,0,0,0,0]
global IsMurderer
IsMurderer=[False,False,False,False,False,False,False,False,False,False]
#subprogram body
file = open("suspects.txt","r")
for i in range(0,9):
Suspect_name[i],Suspect_age[i],Suspect_motive[i], Suspect_ID[i]=file.readline().split(',')
return Suspect_name,Suspect_age,Suspect_motive,Suspect_ID,IsMurderer
#randomly assign murderer
readinSuspects()
Murderer = random.randint(0,9)
for i in range(0,9):
if Murderer == i:
#print Suspect_ID if working
print(Suspect_ID[i])
Also read about if __name__ == '__main__': - it is a good python practice, but without it it still works. And here you can read how to define global vars in python How to define global variables in python SO
Your code has much more to be discussed, but I will leave your teacher to do it ;)
Related
I am working on accessing a variable outside of a function. Here is part of my code:
def main():
trigger_gmm() = 0
log = []
def spatter_tracking_cb(ts, clusters):
global trigger_gmm
for cluster in clusters:
log.append([ts, cluster['id'], int(cluster['x']), int(cluster['y']), int(cluster['width']),
int(cluster['height'])])
if cluster['width'] >= 200:
trigger_gmm = 1
else:
trigger_gmm = 0
print(trigger_gmm)
while True:
print(trigger_gmm)
if trigger_gmm == 1:
print("print something")
if __name__ == "__main__":
main()
I get the output like this:
NameError: name 'trigger_gmm' is not defined
Any ideas would be much appreciated!
You have three issues in that code:
trigger_gmm() = 0 - You need to remove the parenthesis
You need to move the global variable definition up to the beginning of the main function
The if __name__ == "__main__": is not reached as it is after the while loop, you need to move it up.
EDIT:
I added a global declaration to the main module (above the main function) and inside the spatter_tracking_cb function. This is because you need to indicate that the variable trigger_gmm is a global variable whenever you use it.
This code seems to work for me:
global trigger_gmm
def main():
global trigger_gmm
trigger_gmm = 0
log = []
def spatter_tracking_cb(ts, clusters):
global trigger_gmm
for cluster in clusters:
log.append([ts, cluster['id'], int(cluster['x']), int(cluster['y']), int(cluster['width']),
int(cluster['height'])])
if cluster['width'] >= 200:
trigger_gmm = 1
else:
trigger_gmm = 0
print(trigger_gmm)
if __name__ == "__main__":
main()
while True:
print(trigger_gmm)
if trigger_gmm == 1:
print("print something")
trigger_gmm = 0
Remove parenthesis.
You also don't need global trigger_gmm as this variable will be available within scope of main function.
https://realpython.com/python-scope-legb-rule/#nested-functions-the-enclosing-scope
I am no Python user, but from it looks like you are calling variables that are not in a "global" scope.
Every variable defined in a function or loop, is not accessible by another function unless stated so.
Try defining your variable outside of the function, or make it global
As stated before.
W3Schools
Hello I am a newbie to Python.
Declaration of variables is frustrating as it should be easy but I have such hard time to make this work..
I've read other stackoverflow questions and apparently there is no such thing as initialization in Python and I need keyword: global before variable to use it in different places..
#app.route('/calculate', methods = ['GET'])
def calculate():
# get value from html by request.args.get()
Option1.
global newWeightForSecondItem
if weightT1 != weightT2:
newWeightForSecondItem = convert(weightT1, weightT2, weight2)
Option 2.
if weightT1 != weightT2:
global newWeightForSecondItem = convert(weightT1, weightT2, weight2)
Neither works..
When I do such calculation below, I get an error: NameError: name 'newWeightForSecondItem' is not defined.
if discountT2 == "percentage":
finalPrice2 = float((float(price2) - (float(price2) * float(discount2))) / newWeightForSecondItem)
elif discountT2 == "dollar":
finalPrice2 = float((float(price2) - float(discount2)) / newWeightForSecondItem)
def convert(weightT1, weightT2, weight2):
# converting calculation here
return weight2
# main method
if __name__ == '__main__':
app.debug = True
app.run()
I spent a lot time to figure out why I got this error.
NameError: name 'newWeightForSecondItem' is not defined.
However, that was not the main issue. I forgot to convert string to float datatype for newWeightForSecondItem. After I changed it to float(newWeightForSecondItem), it works. This was a very easy mistake and I think python's error was not very helpful.
Thank you for all the comments, everyone.
if you want to have newWeightForSecondItem as a global variable perhaps you can try this:
newWeightForSecondItem = None
#app.route('/calculate', methods = ['GET'])
def calculate():
global newWeightForSecondItem
if weightT1 != weightT2:
newWeightForSecondItem = convert(weightT1, weightT2, weight2)
You declare/initialize the global variable, and then you can use it inside the function
I have a method that inside it I scan an excel file in python and in another method I want to check an entry in a list in which I extracted the data from the excel sheet in the first method as follows:
def first():
nodes_sh = xlrd.open_workbook(file_location)
sh_method = nodes_sh.sheet_by_index(0)
global node_data_inter
node_data_inter = [[sh_method.cell_value(rr, co) for co in range(sh_method.ncols)] for rr in range(sh_method.nrows)] #O(rows*cols) # A loop to get all the data in the excel sheet of "Nodes Co-ordinates"
global node_positions_ascending_inter
node_positions_ascending_inter = dc.deepcopy(node_data_inter) #O(rows*cols)
for rowss in range(len(node_positions_ascending_inter)): #O(rows)
del (node_positions_ascending_inter[rowss][0:3])
del (node_positions_ascending_inter[rowss][2])
def using_from_first_method():
global node_positions_ascending_inter
if node_positions_ascending_inter[0][0] == 1.25:
print "Yes"
An error message is outputted when I type using_from_first_method()
NameError: global name 'node_positions_ascending_inter' is not defined
Why is it outputted as I already have defined node_positions_ascending_inter to be a global variable?
You need to declare node_positions_ascending_inter as a global in the using_from_first_method function. I got the below code (simplification) to run just fine.
def first():
global node_positions_ascending_inter
node_positions_ascending_inter = [1.25, 1.5, 1.3, 1.45]
def using_from_first_method():
global node_positions_ascending_inter
if node_positions_ascending_inter[0] == 1.25:
print("Yes")
first()
using_from_first_method()
If you are still having issues maybe the problem lies in the filling of the array. Are you sure the first method is being called and successfully creating the global before the second tries to access it? Also, see the docs on globals here.
Hi I'm a beginner programmer. I don't know how can I call a variable from function.
I have two def calcular() and guardar(). I get some variables from calcular() that I will call later, but when I call variables in guardar(), it tells me that variable is not defined. I tried making global var, but it doesn't work. Hope you can help me
This is a little of my code...
def calcular():
if nClient == "":
texto = ("Inserta Numero de cliente")
ventanaMensaje(texto)
else:
if cl1=="":
texto = ("Inserta Clave")
ventanaMensaje(texto)
else:
if aB1 == "":
texto = ("Inserta Cantidad")
ventanaMensaje(texto)
else:
try:
clt = open("preciosEsp.txt","r+")
lClt = clt.readlines()
rClt = lClt[0]
sClt = rClt.split("'")
nRClt = sClt[0]
if nClient == nRClt:
cReg=sClt[1]
if cl1== cReg:
prc=sClt[2]
else:
k=1
while cl1 != cReg:
cReg=sClt[k]
k=k+2
if cl1== cReg:
ñ=k-1
prc=sClt[ñ]
else:
x = 0
while nClient != nRClt:
rClt = lClt[x]
sClt = rClt.split("'")
nRClt = sClt[0]
x=x+1
if nClient == nRClt:
cReg=sClt[1]
if cl1==cReg:
prc=sClt[2]
else:
k=1
while cl1 != cReg:
cReg=sClt[k]
k=k+2
if cl1== cReg:
ñ=k-1
prc=sClt[ñ]
indice=int(prc)+3
pdcts = open("productos.txt","r+")
lPdcts = pdcts.readlines()
rPdcts = lPdcts[0]
sPdcts= rPdcts.split("'")
nPdcts = sPdcts[0]
t = 0
if cl1 == nPdcts:
precio1=sPdcts[indice]
global txtD1################## MAKE A GLOBAL VAR
txtD1=sPdcts[1] #### THIS IS THE VARIABLE ########
def guardar():
guardarDatos = (n+txtD1) ################# I CALL HERE, BUT TELL ME THAT VARIABLE IS NOT DEFINED
If you really want a global variable, you'd define it outside of any function
txtD1 = None
def calcular():
...
it will then exist at module level. However, globals are rarely (read: never) the solution you should be using, instead you should be returning information from functions rather than modifying global state. You'd then pass that information into another function to use.
The global keyword in python says that you are referencing a global variable, not creating a new one. However, in your code no such name exists, so you're not actually referencing anything.
first create your "database" somewhere global
clt = dict(map(lambda x:x.split(" ",1),open("preciosEsp.txt","r+"))
now you can acess it anywhere with
clt.get(nClient)
next calcular should return the values you want
def calcular():
...
precio = clt.get(nClient)
return [precio,nClient,...]
then you would store the returned values (or do something with them as soon as they are returned )
I have a function, menu() which creates a menu to navigate and call functions. here is the function.
def menu():
x = raw_input("WOOF! What can POODLE fetch for you? ('--nothing' to exit): ")
if x == "--nothing":
sys.exit(0)
elif x == "--build":
populateCrawled(toCrawl)
graph = buildGraph(crawled)
index = buildIndex(graph)
ranks = computeRanks(graph)
menu()
elif x == "--dump":
saveFile(index, "index.txt")
saveFile(graph, "graph.txt")
saveFile(ranks, "ranks.txt")
menu()
elif x == "--restore":
index = loadFile("index.txt")
graph = loadFile("graph.txt")
ranks = loadFile("ranks.txt")
menu()
elif x == "--print":
print graph
print index
print ranks
menu()
elif x == "--help":
print "WOOF! POODLE Help Options"
print "--build Create the POODLE database"
print "--dump Save the POODLE database"
print "--restore Retrieve the POODLE database"
print "--print Show the POODLE database"
print "--help Show this help information"
menu()
elif x == "--search":
search(index, rankablePages)
else:
print "Help option not found"
menu()
seed = raw_input("Please enter the seed URL: ")
testSeed = "https://dunluce.infc.ulst.ac.uk/d11ga2/COM506/AssignmentB/test_index.html"
seed = testSeed
toCrawl=[seed]
crawled, graph, index, rankablePages = [], {}, {}, {}
MAX_DEPTH = 10
menu()
these variables and dictionaries are all declared globally but when I say type "--build" it does successfully build but then if I go to type "--print" it shows me
UnboundLocalError: local variable 'graph' referenced before assignment
However if I print these dictionaries immediatly after building then they print fine. It's when menu() is reloaded it loses these values. Should I use a while loop or do I need to do some parameter passing?
The fact that these variables are declared globally doesn't help (although note that you didn't actually define ranks globally…), because they're also declared locally, and the local names hide the global ones.
Whenever you write spam = eggs in the body of a function, that makes spam into a local variable, and anywhere spam appears in the function, it refers to that local variable.
If you want to make something global, but still be able to assign to it, you need a global statement. So:
def menu():
global graph, index, ranks
# the rest of your code
But as usual, a better solution is to stop using global variables.
One option create a class to hold your state, make menu a method of that class, and make graph and friends attributes of the class's instances.
But there's an even simpler option here. The only reason you need these variables to be global is because menu is calling itself recursively to simulate a loop. That's already a bad thing to do in Python, for other reasons. (For example, if you go through the menu about 999 times, you're going to get a recursion error.) If you just use a loop instead of trying to fake it, you can just use local variables:
def menu(graph, index, ranks):
while True:
# the rest of your code except the menu() calls
# ...
crawled, graph, index, rankablePages = [], {}, {}, {}
menu(graph, index, ranks)
You should declare graph (and any other variable that menu should use externally) as a global:
def menu():
global graph
#rest of the code
you can read more about globals here