3

...while still leaving it executable within the function.

The idea behind this is I want to create a summation function. Here's what I have so far:

def summation(n, bound, operation):
    if operation is None and upper != 'inf':
        g = 0
        for num in range(n, limit + 1):
            g += num
        return g
    else:
        pass

But summations are most often about infinite convergent series (for which I use 'inf'), with operations applied to each term. Ideally, I'd like to be able to write print summation(0, 'inf', 1 / factorial(n)) and get the mathematical constant e, or def W(x): return summation(1, 'inf', ((-n) ** (n - 1)) / factorial(n)) to get the Lambert W function.

All that comes to my mind is passing the appropriate arithmetic as a string and then using the exec statement to execute it. But I don't think that would accomplish the whole thing, and it's obviously dangerous to use exec with possibly user-entered code.

Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55
  • Does this post help? http://stackoverflow.com/questions/803616/passing-functions-with-arguments-to-another-function-in-python – Nathan Henkel Jun 22 '13 at 02:53

1 Answers1

6

In Python, functions are first-class, which is to say they can be used and passed around like any other values, so you can take a function:

def example(f):
    return f(1) + f(2)

To run it, you could define a function like this:

def square(n):
    return n * n

And then pass it to your other function:

example(square)  # = square(1) + square(2) = 1 + 4 = 5

You can also use lambda to avoid having to define a new function if it's a simple expression:

example(lambda n: n * n)
icktoofay
  • 126,289
  • 21
  • 250
  • 231
  • That takes care of functions, but how can I also incorporate arithmetic (as in the _e_ example I gave)? –  Jun 22 '13 at 02:58
  • (That is, without defining another function for every single operation I want to use.) –  Jun 22 '13 at 03:05
  • 2
    @Lee: Just use a more complex `lambda` expression, e.g., `summation(0, 'inf', lambda n: 1 / factorial(n))`. – icktoofay Jun 22 '13 at 03:05
  • For infinite summations, is there a simple way to "calculate to available floating point accuracy" as the Python documentation claims _e_ and π are, or should I ask a new question? –  Jun 22 '13 at 03:21
  • 1
    @Lee: You could continue on and on until the previous partial sum `==` the next partial sum. If that's not satisfactory, you should probably ask a new question. – icktoofay Jun 22 '13 at 03:32
  • I suspected that would be the case. –  Jun 22 '13 at 03:35
  • I'm encountering a problem in defining the W function I mentioned. The code is `def W(x, branch=None): return summation(1, 'inf', lambda n: (((-n) ** (n - 1)) / factorial(n)) * (x ** n))`. When called on anything but zero I get `OverflowError: integer division result too large for a float`. –  Jun 22 '13 at 15:40
  • @Lee: That happens when `x` is outside the range of convergence. As the Wikipedia page on the W0 function notes, the radius of convergence is 1/e. Testing with an `x` of 0.1 works for me. – icktoofay Jun 23 '13 at 06:31