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?

Hunter
  • 357
  • 8
  • 15
  • Where the function `partial` comes from? Some library? I believe it is not built in. – quapka May 01 '16 at 13:03
  • @quapka [coming from `functools`](https://docs.python.org/2/library/functools.html#functools.partial). – alecxe May 01 '16 at 13:05
  • If you're lucky, [Joel himself](http://stackoverflow.com/users/1076346/joel) may answer your question. :) – PM 2Ring May 01 '16 at 13:11
  • `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.X – GIZ May 01 '16 at 13:14

1 Answers1

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')
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • 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. – Hunter May 01 '16 at 14:16
  • 1
    @Hunter 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. – alecxe May 01 '16 at 14:20
  • Ahhh I see, great. Thank you!! – Hunter May 01 '16 at 14:23