print trace of origins of each call to a function [duplicate] - python

This question already has answers here:
python print all function calls to know the script flow
(2 answers)
Closed 1 year ago.
What specific syntax needs to be added to the code below in order to print out the full trace of the chain of function calls that result in each time that four.myFunction() gets called in the code sameple below?
one.py
import two
import three
two.twoFunction()
three.threeFunction()
two.py
import four
def twoFunction():
four.myFunction()
three.py
import four
def threeFunction():
four.myFunction()
four.py
def myFunction():
print("trace of which functions called me, back to original.")
This is important because we have functions that seem to be run more times than the code looks like the functions should be run.
If we can isolate the chain of calling scripts/functions for each call to four.myFunction(), we will be able to more closely diagnose what might be going on.
We are using Python 3.

With each of your functions, you can require an input like def ...(past_calls):and add the current function to it when calling another.
i.e.
def NthFunction(past_calls):
# Call next function, adding current to the trace.
NextFunction(past_calls + [n])
And when you are printing your results, you can use the information given as the parameter (you can also add more details if need be).

Related

How to invoke a function that has a parameter(s) without using parenthesis in Python

I'm building a data visualization app in Python using Tkinter for the GUI and data science libraries Matplotlib, Seaborn, Pandas and NumPy for the backend.
I have the following line of code where button["command"] is the command for a Tkinter Button which is assigned to a function self.create_analytics_dashboard(button_plots) that creates a new Tkinter frame when the button is pressed. The button plots argument is an object responsible for displaying the right plots based on the button pressed.
button["command"] = self.create_analytics_dashboard(button_plots)
There are 3 pertinent Tkinter frames to this problem:
main_dashboard
plots_dashboard
analytics_dashboard
The first 2 frames simply contain buttons that navigate to the next frame and the anaylytics_dashboard frame has buttons which displays the actual visualizations.
The expected order of these frames is as listed above however, due to the line where I assign the button["command"] aforementioned, the program skips the plots_dashboard and goes from the main_dashboard directly to the analytics_dashboard.
There are no error messages however, if I remove the parenthesis and the parameter inside it (button_plots) as shown in the line below the program will display the frames in the right order without skipping the plots_dashboard frame:
button["command"] = self.create_analytics_dashboard
Obviously, I have tried Googling it but all the results just seem to talk about the difference between invoking functions with and without parenthesis or the purposes of each. This article helps explain the difference quite succinctly:
When we call a function with parentheses, the function gets execute and returns the result to the callable.
In another case, when we call a function without parentheses, a function reference is sent to the callable rather than executing the function itself.
So, since the function works as intended when I don't use parenthesis i.e. send a function reference to the callable rather than executing the function itself, I tried using a partial function from the functools library to see if it would work:
from functools import partial
...
button_command = partial(self.create_analytics_dashboard)
button["command"] = button_command(button_plots)
Unfortunately, nothing changed. The plots_dashboard frame was still skipped as before. I need a way to pass button_plots as an argument so it can be used in the self.create_analytics_dashboard function without using parenthesis since this will just execute the function rather than sending a function reference to the callable.
If there is another way of passing a variable from one function in a class to another function in the same class in Python then that could work as well. I simply need the button_plots variable to be available in the self.create_analytics_dashboard function one way or another.
Apologies for the long post but this has been bothering me for a long time so I tried to give as much as detail as possible. If anything in the question does not make sense please let me know. Any help is much appreciated.
Thanks
To use functools.partial you must include the arguments when you create the partial function:
button_command = partial(self.create_analytics_dashboard, button_plots)
button["command"] = button_command
Or, more concisely:
button["command"] = partial(self.create_analytics_dashboard, button_plots)

Python: How to pass a variable from one python script to another [duplicate]

This question already has answers here:
How to get just the return value from a function in Python?
(2 answers)
Closed 3 years ago.
I know this this questions been asked before, but I can't seem to get the answers to work. I'm trying to pass the variable things from one script to another.
test.py
def addstuff(word):
things = word + " good."
return things
test2.py
from test import addstuff
addstuff("random")
stuff = things + "morethings"
Ive also tried importing with
from test import *
things doesn't show up as defined in test2, How can I fix this?
The addstuff("random") does not store the output of your addstuff() function from test.py into any variable, its just discarded.
The things in your test2.py does not mean anything to the program until its not assigned to any variable.
Here's the correct way to do it:
from test import addstuff
things=addstuff("random")
stuff = things + "morethings"
We're assigning the output of addstuff("random") (ie "random good.") to things and then adding "morethings" to it.

Print statement as they are called in a python script automatically when the script runs [duplicate]

This question already has an answer here:
How can I decorate all functions imported from a file?
(1 answer)
Closed 4 years ago.
I'd like to automatically print python statements as they are called in a script while the script runs. Could anybody show a ready-to-use solution?
For example, I may have the following python code.
print "xxx"
myfun()
I'd like print "xxx" and myfun() be printed exactly in the output.
One solution is manually to add a print statement to each function. But this is combersome.
print 'print "xxx"'
print "xxx"
print 'myfun()'
myfun()
The following solutions just can not do so. Please do not mark this question as duplicate.
The solution here will not only print the functions in the current script but also functions in other scripts used in the current scripts. These solutions are not what I need.
How do I print functions as they are called
The following does not do what I need because it does not limit the decoration to the current file. For example, it uses import mymod1; decorate_all_in_module(mymod1, decorator). I don't have a module. I want to print the statements in the current script.
How can I decorate all functions imported from a file?
There is no "ready-to-use" solution to this problem. You are asking for a programming language with different semantics than the Python language: therefore you will either need to write code to get this effect, or use a different language, or both.
That said, for solving your actual problem, I believe simply using a debugger would do what you want: that way you can step over each statement in your program and observe as they are executed.

How to make a python module or function and use it while writing other programs?

There where many instances where I have to write large line of code over and over again in multiple programs. So I was wondering if I could write just one program, save it and then call it in different programs like a function or a module.
An elementary example: I write a program to check if a number is palindromic or not. Then I want to write a program to check if a number is palindromic and a prime, could I just call the first program and do the rest of the code to check if it is prime or not?
It is about writing reusable code. I can suggest you to write reusable code in specific function in separate python file and import that file and function too.
For example you need function called sum in other function called "bodmas" then write function called sum in one python file say suppose "allimports.py":
def sum(a,b):
return a+b
Now suppose your "bodmas" named function is some other python file then just import all the required functions and use is normally by calling it.
from allimports import sum
def bodmas:
print(sum(1,1))
One important thing is be specific while import your module as it will effect performance of your code when length of your code is long.
Suppose you want to use all functions then you can use two option like :
import allimports
print(allimports.sum(1,1))
other option is
from allimports import *
print(sum(1,1))
and for specific imports is as follows:
from allimports import sum
print(sum(1,1))
Yes. Let's say you're writing code in a file called palindrome.py. Then in another file, or in the python shell you want to use that code. You would type
import palindrome
either at the top of the file or just into the shell as a command. Then you can access functions you've written in palindrome.py with statements like
palindrome.is_palindrome('abba')
It's important to note that to do this propery, the code in palindrome.py must be in functions. If you're not sure how to do that, I recommend the official Python tutorial: https://docs.python.org/3/tutorial/index.html
it's easy to write a function in python.
first define a function is_palindromic,
def is_palindromic(num):
#some code here
return True
then define a function is_prime,
def is_prime(num):
#some code here
return True
at last, suppose you have a number 123321, you can call above function,
num = 123321
if is_palindromic(num):
if is_prime(num):
print 'this number is a prime!'
ps, maybe you could try to use some editors like vscode or sublime.

call method without args from argparse [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a method I call from the command line using argparse. I also want to call that method from another method, in this case I get an error saying args is not defined. Is there a way around this, I have tried setting a default but I get the same error.
def change_modem_bank(bank_num=None, modem=None):
if args.sim_bank and args.modem_num:
bank_num = args.sim_bank
modem = args.modem_num
if "1" in bank_num:
print "2"
elif "2" in bank_num:
print "2"
print modem
if __name__=='__main__':
parser_mode = subparsers.add_parser('set_modem_bank')
parser_mode.add_argument('-bank',dest='sim_bank',help='SIM bank number',nargs='?',const=None,default=None)
parser_mode.add_argument('-modem_num',dest='modem_num',help='Modem number',nargs='?',const=None,default=None)
parser_mode.set_defaults(func=change_modem_bank)
args=parser.parse_args()
args.func()
I want to call the method like so from another script:
import cellular_modem
cellular_modem.change_modem_bank("2","0")
Currently I can call it like this:
myscript.py set_modem_bank -bank ${num} -modem ${modem_num}
I would like it to work with either type of call, from CLI and from inside a python script.
When you call it as a script, what happens is:
args=parser.parse_args()
change_modem_bank() # equivalent to args.func()
When you import the module, that main part is skipped, so args is not set. If you want to call change_modem_back as is, then you need to create an args variable that looks like the one that the parser would generate. Here's one way of doing that:
import cellular_modem
import argparse
args = argparse.Namepspace(simbank=xxx, modem_num=xxx)
cellular_modem.change_modem_bank("2","0")
Your function assumes that, in its global argument space there is an object with these 2 attributes:
args.sim_bank, args.modem_num
You change the function to something like:
def change_modem_bank(bank_num=None, modem=None, args=None):
if args and args.sim_bank and args.modem_num:
bank_num = args.sim_bank
modem = args.modem_num
and invoke it in the main as:
args.func(args=args)
This way it is clear where the function is getting its args variable from. It also behaves rationally when args is a simple default value like None.
One way or other you need to initialize an args variable when importing, and then write your function is a way that it will be ok with that default version.
Your change_modem_bank function tries to access args directly, which works when you call it as a command-line script since it's in the module namespace then, but fails when you call it separately. Just fix it to get args passed in instead:
def change_modem_bank(bank_num, modem):
if "1" in bank_num:
print "2"
elif "2" in bank_num:
print "2"
print modem
And call it with:
args.func(args.sim_bank, args.modem_num)
You'll have to figure out what your function is supposed to do if the arguments are None, since that will cause an error now.

Categories

Resources