Python: partial that takes three arguments
Asked Answered
V

1

5

I'm trying to learn Python by reading the book Data Science from Scratch by Joel Grus, and on page 94 they describe how to approximate a derivative of f = x^2 using the following code

def difference_quotient(f, x, h):
    return (f(x + h) - f(x)) / h

def square(x):
    return x * x

def derivative(x):
    return 2 * x

derivative_estimate = partial(difference_quotient, square, h=0.00001)

# plot to show they're basically the same
import matplotlib.pyplot as plt
x = range(-10,10)
plt.title("Actual Derivatives vs. Estimates")
plt.plot(x, map(derivative, x), 'rx', label='Actual')
plt.plot(x, map(derivative_estimate, x), 'b+', label='Estimate')
plt.legend(loc=9)
plt.show()

Everything works fine, but when I change the line derivative_estimate = partial(difference_quotient, square, h=0.00001) to derivative_estimate = partial(difference_quotient, f=square, h=0.00001) (because I think that is clearer to read), then I get the following error

Traceback (most recent call last):
  File "page_93.py", line 37, in <module>
    plt.plot(x, map(derivative_estimate, x), 'b+', label='Estimate')
TypeError: difference_quotient() got multiple values for keyword argument 'f'

What is going on here?

Valediction answered 1/5, 2016 at 13:0 Comment(4)
Where the function partial comes from? Some library? I believe it is not built in.Viquelia
@Viquelia coming from functools.Urbana
If you're lucky, Joel himself may answer your question. :)Bourbonism
derivative_estimate = partial(f=difference_quotient, x =square , h=0.00001) is the right way to do it. If the first argument is passed as a keyword argument then the rest of your arguments must be passed as keyword only arguments, otherwise you'll get SyntaxError: non-keyword arg after keyword arg if you run Python 3.XQuaff
U
8

It was answered and perfectly explained in this topic:

Which in your case implies that you should pass x as a keyword argument:

plt.plot(x, [derivative_estimate(x=item) for item in x], 'b+', label='Estimate')
Urbana answered 1/5, 2016 at 13:13 Comment(3)
Thank you, your suggestion works and I understand it, so I have accepted your answer. But I still don't really see why the code that I suggested failed. I have read the link you provided and understand it in that example, but I don't see at what point I use the same argument twice.Valediction
@Valediction sure, when you call map(derivative_estimate, x) - python would actually call derivative_estimate(x[0]), then derivative_estimate(x[1]) etc. x[0], x[1] would be passed as the first positional argument to difference_quotient which is f. And, since you specify f keyword argument, Python complains that f was specified multiple times. Hope that helps.Urbana
Ahhh I see, great. Thank you!!Valediction

© 2022 - 2024 — McMap. All rights reserved.