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
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 ;)
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 )
Please be kind with me, I'm a Python beginner :-)
Now, I see that the 'best practice' for writing Python programs would be to wrap the main code inside a 'main' function, and do the if "__main__" == __name__: test to invoke the 'main' function.
This of course results in the necessity of using a series of global statements in the 'main' function to access the global variables.
I wonder if it is more proper (or 'Pythonic', if you will) to gather the global variables into a custom class, say _v, and refer to the variables using _v. prefix instead?
Also, as a corollary question, would that have any negative impact to, let's say, performance or exception handling?
EDIT : The following is the general structure of the program:
paramset = {
0: { ...dict of params... }
1: { ...dict of params... }
2: { ...dict of params... }
}
selector = 0
reset_requested = False
selector_change = False
def sighup_handler(signal,frame):
global reset_requested
logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
reset_requested = True
selector = 0
def sigusr1_handler(signal,frame):
global selector
new_selector = (selector + 1) % len(paramset)
logger.info('Caught SIGHUP, changing parameters to set #{0}'.format(new_selector))
selector = new_selector
selector_change = True
signal.signal(signal.SIGHUP, sighup_handler)
signal.signal(signal.SIGUSR1, sigusr1_handler)
def main():
global reset_requested
global selector
global selector_change
keep_running = True
while keep_running
logger.info('Processing selector {0}'.format(selector))
for stage in [process_stage1, process_stage2, process_stage3]
err, result = stage(paramset[selector])
if err is not None:
logger.critical('Stage failure! Err {0} details: {0}'.format(err, result))
raise SystemError('Err {0} details: {0}'.format(err, result))
else:
logger.info('Stage success: {0}'.format(result))
if reset_requested:
stage_cleanup()
reset_requested = False
else:
inter_stage_pause()
if selector_change:
selector_change = False
break
selector = (selector + 1) % len(paramset)
There are enough pieces missing from the example code that reaching any firm conclusions is difficult.
Event-driven approach
The usual approach for this type of problem would be to make it entirely event-driven. As it stands, the code is largely polling. For example, sighup_handler sets reset_requested = True and the while loop in main processes that request. An event-driven approach would handle the reset, meaning the call to stage_cleanup, directly:
def sighup_handler(signal,frame):
logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
stage_cleanup()
Class with shared variables
In the sample code, the purpose of all those process_stages and cycling through the stages is not clear. Can it all be put in an event-driven context? I don't know. If it can't and it does require shared variables, then your suggestion of a class would be a natural choice. The beginnings of such a class might look like:
class Main(object);
def __init__(self):
self.selector = 0
self.selector_change = False
signal.signal(signal.SIGHUP, self.sighup_handler)
signal.signal(signal.SIGUSR1, self.sigusr1_handler)
def sighup_handler(self, signal,frame):
logger.info('Caught SIGHUP, resetting to set #{0}'.format(new_selector))
stage_cleanup()
self.selector = 0
def sigusr1_handler(self, signal,frame):
new_selector = (selector + 1) % len(paramset)
logger.info('Caught SIGHUP, changing parameters to set #{0}'.format(new_selector))
self.selector = new_selector
self.selector_change = True
def mainloop(self):
# Do here whatever polling is actually required.
if __name__ == '__main__':
main = Main()
main.mainloop()
Again, because the true purpose of the polling loop is not clear to me, I didn't try to reproduce its functionality in the class above.
Generally, it is best practice to avoid global variables, and instead just pass variables to classes/methods that need them through method calls. Example: if you are making a calculator, make an addition method that takes 2 ints and returns an int. This is in contrast to making 2 input ints and 1 output int as global variables, and having the add method work on those.