I'am using a small program calculating by dichotomy the root of a function (i.e. find x
when f(x)=0
). (I admit I stole this program from some SO
post, but I can't give the reference nor thank the author because I don't remember where it was...)
The output I have is:
Root is: -0.567143
Delta with 0 is: 0.000000000166
I would like to also output the expression of the function I am working on, just as written in def f(x)
so as to have:
Function is: x np.exp(x)
Root is: -0.567143
Delta with 0 is: 0.000000000166
I wonder how to do that...? Can def f(x)
be modified to store the function writing somewhere? Or is it necessary to do another type of manipulation elsewhere?
My program is:
def samesign(a, b):
return a * b > 0
def dichotomy(func, low, high, tolerance=None):
# func(low) and func(high) must have opposite signs
assert not samesign(func(low), func(high)), ("\n"
"Assertion failed!\n"
"Replace low or high")
condition = True
while condition:
midpoint = (low high) / 2.0
if samesign(func(low), func(midpoint)):
low = midpoint
else:
high = midpoint
if tolerance is not None and abs(high - low) < tolerance:
break
condition = abs(high - low) > tolerance
return midpoint
def f(x):
# Define function
return x np.exp(x)
x = dichotomy(f, -1, 0, 1E-9)
import inspect
line_return = inspect.getsourcelines(f)[0][-1]
llr = len(line_return)
name = line_return[11 : llr-1]
print(f'Function is: {name}')
print(f'Root is: {x: .6f}')
print(f'Delta with 0 is: {f(x): .12f}')
CodePudding user response:
As shown in How can I get the source code of a Python function?, you can get the full definition of the function with the inspect
module.
>>> import inspect
>>> print(inspect.getsource(f))
def f(x):
# Define function
return x np.exp(x)
Note that function f
must be defined in a source file.
If you are only interested in the content of the return statement, you must explore the ast of the function to extract the return statement using of the ast
module.
import ast
def get_return_statement(fct):
root = ast.parse(inspect.getsource(f))
try:
return_node = next(
node for node in ast.walk(root) if isinstance(node, ast.Return)
)
return ast.unparse(return_node.value)
except StopIteration:
return "None"
get_return_statement(f)
will give you x np.exp(x)
.
Edit for python prior to 3.9:
ast.unparse
is only available since python 3.9. It can be replace by the astor
third party library, by replacing ast.unparse
with astor.to_source
.
The result is slightly different with more parentheses: (x np.exp(x))
.