Algorithms as objects?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Aug 28 10:30:00 EDT 2009


On Thu, 27 Aug 2009 23:05:41 +0000, Kreso wrote:

> I am writing an application that essentially calculates set of numbers,
> say N1, N2, ..., where they can be calculated by several different
> algorithms. (One should be able to choose the algorithm at run time.) In
> each algorithm one starts from a set of functions, say f1, f2, ...,
> which are then transformed into some other functions g1(f1, f2, ..),
> g2(f1, f2, ...), ... , then maybe transformed once more and result is
> obtained by evaluating final functions.

Sounds like you're doing functional programming. There's a rich set of 
functional tools in languages like Haskell, but in Python there's only a 
few, such as partial(). (See the functools module.)

However, you can make your own, using the following general technique. 
Suppose you want to compose two functions, f and g. Then with a helper 
function:

def compose(f, g):
    def composed_function(*args):
        return f(g(*args))
    return composed_function

you can do this:

>>> def add1(x):
...     return x+1
...
>>> def double(y):
...     return 2*y
...
>>> double_plus_one = compose(add1, double)
>>> double_plus_one(3.5)
8.0


Unfortunately, about the only thing you can't do is check the return type 
of functions without actually calling them.




>   I can naturally think about this as a collection of transformation
> blocks, which have functions as input and output, and which can be put
> together to get the final results. However, I am not sure how to program
> this, especially since one cannot subclass function type. To be clear
> let me give simplified example of what is needed:
> 
> f(x) has unknown shape, so one would like to try, say
> 
> f1(x) = ax - b x**2   or    f2(x) = a sin(b*x),
> 
> where a and b are variable parameters.

You need factory functions!

def axbx2_factory(a, b):
    # Return a function that returns a*x-b*x**2
    def inner(x):
        return a*x -b*x**2
    return inner

And in use:

>>> f1 = axbx2_factory(1, 2)
>>> f2 = axbx2_factory(1, 0)
>>> f1(2.5)
-10.0
>>> f1(3.5)
-21.0
>>> f2(2.5)
2.5
>>> f2(3.5)
3.5



Hope this helps.


-- 
Steven



More information about the Python-list mailing list