Can't run multiple functions in a main function in Python - python

So a problem I'm facing is this:
I defined 2 functions and one function uses the variable of the other function
Now when I run both of them using the following code, it works properly:
def type_anything():
use = input(">")
return use
def print_it():
print(use)
if __name__ == '__main__':
while True:
use = type_anything()
print_it()
Output:
> abcd
abcd
> efgh
efgh
> anything
anything
But when I decide to make a main function that will run both the above functions and then run the main function under the "if __name__ == ......" line, something like this:
def type_anything():
use = input("> ")
return use
def print_it():
print(use)
def run_it():
while True:
use = type_anything()
print_it()
if __name__ == '__main__':
run_it()
The program doesn't run properly instead shows this error:
> anything
Traceback (most recent call last):
File "C:/<location>/sample.py", line 17, in <module>
run_it()
File "C:/<location>/sample.py", line 13, in run_it
print_it()
File "C:/<location>/sample.py", line 7, in print_it
print(use)
NameError: name 'use' is not defined
Why is this happening? What do I need to do?

This should solve your problem:
def type_anything():
use = input("> ")
return use
def print_it(use):
print(use)
def run_it():
while True:
use = type_anything()
print_it(use)
if __name__ == '__main__':
run_it()
The print_it function is not aware of any variable use hence the error.
Noticed how the type_anything function returns the variable use and the print_it function accepts an argument and then prints that.

Please do not get into the habit of using global variables, in the long run these will break everything you write. This is just an example to help you with your understanding of the problem!
Your problem is variable scope. In the first example your variable use is global because you define it in the main program:
if __name__ == '__main__':
while True:
use = type_anything()
print_it()
It is not defined in type_anything, you could rename this variable to whatever and it would still work:
def type_anything():
x = input(">")
return x
In the second example you define it in a function:
def run_it():
while True:
use = type_anything()
print_it()
You could fix this by making use a global variable:
def run_it():
global use
while True:
use = type_anything()
print_it()
A much better way of doing this
Pass the variable use to the function that uses it:
def print_it(use):
print(use)
def run_it():
while True:
use = type_anything()
print_it(use)

You can't use a variable defined in one function in another function.
Each function needs to receive the arguments it uses.
def type_anything():
use = input(">")
return use
def print_it(use):
print(use)
if __name__ == '__main__':
while True:
use = type_anything()
print_it(use)

Related

How to access a variable outside of a function (access from a loop)?

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

problem about Parameter transfer of jsonpath

I am running a code like below, but it's not what I want. real_path is defined at def check, so it's static.
#code before change
def check(path):
with open(path,'r', encoding="utf-8") as f:
file=json.load(f)
real_path='C:\\Documents and Settings\\Administrator\\Local Settings\\Temp\\5.exe'
call = jsonpath(file,"$.behavior.processes[?(#.process_path==real_path)].calls[?(#.category=='network')]")
print(call)
if __name__ == "__main__":
path="C:/users/hdl/Desktop/2min/2-5.json"
#real_path = 'C:\\Documents and Settings\\Administrator\\Local Settings\\Temp\\5.exe'
check(path)
Then I have changed like below, I have defined the real_path at main, thus it has worked.
def check(path):
with open(path,'r',encoding="utf-8") as f:
file=json.load(f)
#real_path='C:\\Documents and Settings\\Administrator\\Local Settings\\Temp\\5.exe'
call = jsonpath(file,"$.behavior.processes[?(#.process_path==real_path)].calls[?(#.category=='network')]")
print(call)
if __name__ == "__main__":
path="C:/users/hdl/Desktop/2min/2-5.json"
real_path = 'C:\\Documents and Settings\\Administrator\\Local Settings\\Temp\\5.exe'
check(path)
Does somebody know why?
What if I want to define at def check, what should I do?

Declare variable to function without running it

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()

How can i use my function a_c_t_b()

My code looks like:
def g_b():
items_in_bag = []
done=False
bugout_bag = 'Bug Out Bag'
while done == False:
item = input('What bags do you have? [Enter x to stop]')
items_in_bag.append(item)
if item == 'x':
done = True
items_in_bag.remove('x')
break
else:
continue
items_in_bag.append(bugout_bag)
print("Your bags\n")
print(items_in_bag)
return items_in_bag
def g_c():
coins_in_bag = []
done=False
while done == False:
coin_item = input('What coins do you have? [Enter x to stop]')
if coin_item == 'x':
done = True
break
else:
coins_in_bag.append(coin_item)
continue
print("Your coins\n")
print(coins_in_bag)
return coins_in_bag
def a_c_t_b(items_in_bag, coins_in_bag):
#print('Here are your coins:\n')
#g_c()
#print('Here are your bags:\n')
#print(items_in_bag)
print (items_in_bag,coins_in_bag)
return (items_in_bag,coins_in_bag)
def main():
g_b()
g_c()
a_c_t_b(items_in_bag,coins_in_bag)
main()
However, when i run this code like: import myfile
It gives me an error of:
File ".\myfile.py", line 51, i
a_c_t_b(items_in_bag,coins_in_bag)
NameError: global name 'items_in_bag' is not defined
I'm simply trying to return the values of items_in_bag,coins_in_bag from their respective functions.
Thank you
Please call your functions more sensible names.
To answer your question, your g_b and g_c functions return values, they don't return names. At the point where you call a_c_t_b, Python has no idea what items_in_bag is, because yo'uve never defined it. Python can't know you mean "the value returned from g_b": you have to tell it.
items_in_bag = g_b()
coins_in_bag = g_c()
a_c_t_b(items_in_bag, coins_in_bag)
You are calling g_b and g_c but never catching their returned values.
You can either do:
def main():
items_in_bag = g_b()
coins_in_bag = g_c()
a_c_t_b(items_in_bag, coins_in_bag)
or:
def main():
a_c_t_b(g_b(), g_c())
When you import the module main function is executed (call in last line). And main function use undefined identifiers items_in_bag and coins_in_bag:
def main():
g_b()
g_c()
a_c_t_b(items_in_bag,coins_in_bag)
Probably you want something like
def main():
items_in_bag = g_b()
coins_in_bag = g_c()
a_c_t_b(items_in_bag,coins_in_bag)

Calling functions from main python

I have some python 3.4 code that works fine:
def run():
m = 0
while m != 1:
p = input('Please choose p: ')
p = makeInt(p)
#Some other code
print(p)
m = makeInt(input('Enter 1 if you would like to quit: '))
def makeInt(i):
try:
i = int(i)
except ValueError:
i = input('Incorrect input! Enter your answer: ')
i = makeInt(i)
return i
#Some other functions
if __name__ == '__main__':
run()
I want to put all this code in a class (Except possibly if __name__ ==...) When I put all the code including if __name__ ==... in a class like so:
class Foo(object):
def run(self):
m = 0
while m != 1:
p1 = input('Please choose p: ')
p1 = self.makeInt(p1)
#Some other code
print(p1)
m = self.makeInt(input('Enter 1 if you would like to quit: '))
def makeInt(self, i):
try:
i = int(i)
except ValueError:
i = input('Incorrect input! Enter your answer: ')
i = self.makeInt(i)
return i
#Some other functions and stuff
if __name__ == '__main__':
run()
I get the following error: TypeError: run() missing 1 required positional argument: 'self'. When I remove the self argument from run() it runs until makeInt() is called and then I get: NameError: name 'makeInt' is not defined. I get the same error if I take the if statement out of the class and call Foo.run(). I have some other code earlier in this program that works when I call functions of a class from another function in that same class. I realize I don't have to put all my code in a class, but in this case I want to. Why am I getting these errors and what can I do to put my working code in a class?
As others mentioned, by putting your functions in a class, you've made them methods, that means they need an instance of this class as first argument. So you can indeed call your run method using Foo().run() as Foo() will create an instance of Foo.
Another way (e.g. if you don't need the class for anything else than encapsulation) is to make them static, using the staticmethod decorator:
class Foo(object):
#staticmethod
def run():
...
#staticmethod
def makeInt(i):
...
if __name__ == '__main__':
Foo.run() # don't need an instance as run is static
In Python, a method can be static, i.e. no need for any special argument, a class method, i.e. first argument is the class itself, or a standard method, i.e. the first argument is an instance of the class.
Since you wrap your code within a class, your run() is a method now. You should remove your main from your class by unindenting it and initialize an instance of your class:
if __name__ == '__main__':
Foo().run()
It thinks the guard is a part of your class due to the indentation: you have your guard indented to the same level as the other class members. Unindent the
if __name__ == '__main__'
Also change it to be
if __name__ == '__main__':
main()
and then instantiate a new object of type Foo in your newly created main() function
def main():
newFoo = Foo()
newFoo.run()

Categories

Resources