A nested function has access to the local names in the parent function. When you define f
outside, it can't access the locals w1
and w2
, so it'll have to assume those are globals instead.
And if you don't define w1
and w2
at the global level, your second version actually raises a NameError
:
>>> import sympy as sy
>>> def f(x):
... return w1 * x**3 + w2 * x - 1
...
>>> def derivative(w1, w2, pt):
... x = sy.Symbol('x')
... def df(x):
... return sy.diff(f(x),x)
... return df(x).subs(x,pt)
...
>>> derivative(5, 8, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in derivative
File "<stdin>", line 4, in df
File "<stdin>", line 2, in f
NameError: name 'w1' is not defined
That you didn't get an exception means you already defined w1
and w2
before, and it is those values that are being used to provide your incorrect answer.
You can 'fix' your second example by setting w1
and w2
as globals instead. It doesn't actually matter what you pass in as the first and second arguments to the derivative()
call, because those w1
and w2
argument values are entirely ignored:
>>> w1 = 5
>>> w2 = 8
>>> derivative('This value is ignored', 'And so is this one', 2)
68
In your local setup, you probably set w1
and w2
to 4
and 5
, respectively, because it is those values for which x
is 53
:
>>> w1 = 4
>>> w2 = 5
>>> derivative('This value is ignored', 'And so is this one', 2)
53
For your first example, w1
and w2
are provided by the locals in derivative()
; it doesn't matter what global names you may have defined, those are not going to be used instead.
If you want to define f
outside of derivative()
, and still pass in w1
and w2
to derivative()
first, then you also need to pass those same values on to the f()
function:
def f(x, w1, w2):
return w1 * x**3 + w2 * x - 1
def derivative(w1, w2, pt):
x = sy.Symbol('x')
# Get derivative of f(x, w1, w2)
def df(x):
return sy.diff(f(x, w1, w2), x)
# Evaluate at point x
return df(x).subs(x,pt)
Now f()
explicitly receives w1
and w2
from the nested df()
function, and not from globals.