def user(choose):
if (choose == "1"):
play = game()
elif (choose == "2"):
return stats(play)
else:
return quit()
I want to take the value from function game() and use it in stats(), but I get an error saying that play is not defined. How do I declare game() and use it in another function?
You could "postpone" execution of func1:
def func1():
return 'abc'
def something_else(callable):
callable()
def main():
hello = None
def f():
"""set result of func1 to variable hello"""
nonlocal hello
hello = func1()
# over here func1 is not executed yet, hello have not got its value
# you could pass function f to some other code and when it is executed,
# it would set result for hello
print(str(hello)) # would print "None"
call_something_else(f)
print(str(hello)) # would print "abc"
main()
After question has changed...
Right now, your local variable play is out of scope for stats.
Also, looks like you expect that function would be called twice.
You need to save play in global content
play = None # let's set it to some default value
def user(choose):
global play # let python know, that it is not local variable
if choose == "1": # no need for extra brackets
play = game()
if choose == "2" and play: # double check that play is set
return stats(play)
return quit()
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
I declared 3 functions earlier, this is just a goofy text based cookie clicker-esque game.
dostuff={"" : turn() , "help" : helpf() , "invest" : invest() }
while done != True:<br>
do = input("What do you want to do? ")
do = do.lower()
if do == "" or do == "help" or do == "invest":
dostuff[do]
elif do == "quit":
done = True
So when I use dostuff["turn"] it does nothing (the function is supposed to print some things). I have the same problem with the other options.
Your parentheses must be omitted in the dict, and then put at the end of the dict call. You define a function, which becomes a python object. You reference the object with the dict, and then you call the function with the object reference followed by parentheses:
def one():
print("one")
def two():
print("two")
do_stuff = {
"one": one,
"two": two
}
do_stuff["one"]()
prints:
"one"
You can take this concept of executing calls with string inputs a lot farther by familiarizing yourself with the builtin functions of python.
https://docs.python.org/2/library/functions.html
For example, you can create a class and call its methods or properties using text based input with the getattr method:
class do_stuff():
def __init__(self):
pass
def one(self):
print("one")
def two(self):
print("two")
doer = do_stuff()
inp = "one"
getattr(doer, inp)()
prints->
"one"
If I try to run the following code:
def func():
a = 5
print 'done'
return a
temp = raw_input('')
if temp == '':
func()
print func()
Say temp is '' and the function is run. It prints done and returns variable a. How can I print the returned variable without running the function once more, so done isn't printed again?
You should assign the returned value to a variable (e.g. a).
Update: you could either print inside the function (version1) or use global variable (version2)
def func():
a = 5
print 'done'
return a
# version 1: if print doesn't have to be outside of the function
def main():
temp = raw_input('')
if temp == '':
local_a = func()
else:
# use else to avoid UnboundLocalError: local variable 'a' referenced
# before assignment
local_a = None
print local_a
if __name__ == "__main__":
main()
# # version 2: if print have to be outside of the function, then I can only
# # think of using global variable, but it's bad.
# global_a = None
# def main():
# temp = raw_input('')
# if temp == '':
# global global_a
# global_a = func()
# if __name__ == "__main__":
# main()
# print global_a
You could use #zyxue's answer above and store the return value to a variable or you could also just not return anything from the function and just assign you final value in a function to a global variable if you have need for that.
I should warn you that it isn't good practice to overuse global variables unnecessarily or overly. See: https://stackoverflow.com/a/19158418/4671205
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
I am creating a simple debugger using python and trying to create breakpoint when an expression holds.i am using the eval function to evaluate that expression.but it does not work.
def traceit(frame, event, trace_arg):
if event == 'line':
if(eval('x == 5')):
print 'stop here'
def fn():
#the variable x is defined and used here
sys.settrace(traceit)
fn()
sys.settrace(None)
You need to pass a dictionary as an argument for locals and globals to the eval function (so that it knows what x is! -- Otherwise it's just guessing and it picks up the local context which isn't the context of the function fn)
You can get the locals and globals values from the stack frame object in the f_locals and f_globals attributes respectively.
I think you probably want something like:
eval('x == 5',frame.f_locals,frame.f_globals)
As a side note, you probably don't actually need eval for this (static) case:
if frame.f_locals.get('x') == 5:
print "stop here"
Here's some "working" code (i.e. it prints "stop here" in the right spot):
import sys
def traceit(frame, event, trace_arg):
if event == 'line':
if 'x' in frame.f_locals or 'x' in frame.f_globals:
if(eval('x == 5',frame.f_locals,frame.f_globals)):
print 'stop here'
return traceit
sentinel = object()
def trace_no_eval(frame, event, trace_arg):
if event == 'line':
value = frame.f_locals.get('x',frame.f_globals.get('x',sentinel))
if value is not sentinel and value == 5:
print 'stop here'
return traceit
def fn():
for x in range(10):
print x
sys.settrace(traceit)
fn()
sys.settrace(trace_no_eval)
fn()
sys.settrace(None)
As you said that this is an assignment, please do not blindly copy this. Take the time to understand it and really understand what is going on.