Pass a formula as a function parameter in python - python

I want to pass a formula within a function parameter in Python where the formula is a combination of the other function parameters. In principle this would look like this:
myfunction(x=2,y=2,z=1,formula="x+2*y/z")
6
or more generaly:
def myformula(x,y,z,formula):
return formula(x,y,z)
This would allow the user to choose any arithmetic expression in terms of x, y, and z without having to create a new function.
One of the possibility I foresee is to convert the string in line of code within the function. Anything possible like that in Python? Or any other ideas?
Thanks

Using sympy, you could evaluate mathematical expressions:
import sympy as sy
def myformula(formula, **kwargs):
expr = sy.sympify(formula)
return expr.evalf(subs=kwargs)
print(myformula(x=2,y=2,z=1,formula="x+2*y/z"))
# 6.00000000000000
print(myformula(x=2,y=2,z=1,formula="sin(x+y-z)"))
# 0.141120008059867
But note that sympy.sympify does use eval which makes it unsafe to apply to arbitrary user input
since strings can be composed to trick eval into executing arbitrary Python code.
A safer alternative is to build a parser to parse a strictly limited mathematical expressions.
Here are a few examples
Parsing expressions using ast
Using Paul McGuire's pyparsing

Your "myFormula" isn't much different than a regular lambda expression, except with the added baggage of having to parse a string into executable Python.
(lambda x,y,z: x + 2*y/z)(5, 2, 10)
As such, you could simply define myFormula as
def myFormula(*args, formula):
formula(*args)
and call it as
myFormula(5, 2, 10, lambda x, y, z: x + 2*y/z)

You could try using a lambda function. Something like this might suit you:
def myFormula(x,y,z):
return lambda x,y,z: x+2*y/z
This way you don't have to define a new function and you don't have to pass anything extra as an argument.
Extra info about lambda functions: http://www.diveintopython.net/power_of_introspection/lambda_functions.html
http://pythonconquerstheuniverse.wordpress.com/2011/08/29/lambda_tutorial/
https://docs.python.org/2/reference/expressions.html#lambda

Related

Making way for continuations from an apparent limitation of python reduce

Let us consider a list with numbers like the following :
a_lst = [1,2,3,2,3,4,5,6,2,2]
Now I need to write a program in python which counts the number of occurrences of let's say "2" using only "reduce" .
I went through the following question as well :
using Python reduce Count the number of occurrence of character in string
It has got a great answer , however I wanted to see if there is any way where
I could replace the "if" condition inside the lambda function with like (x == 2) . I mean getting the same thing done by not using the "if"condition explicitly .
I thought of reaching up to a solution by passing a lambda function,which takes another lambda function as an argument to the reduce function .
But it turned out to be just a day-dream and nothing else as after passing a lambda function as an argument , calling it inside the outer lambda function body will defeat the purpose of making it a lambda function .
One more fiasco was about wishing for a construct where a lambda function could call itself at the end of its body . (I understand the above line sounds completely meaningless , but what I meant a construct which had the equivalent power of a lambda calling itself )
I have been through the concept of continuation passing style ,where in pythonic terms , a function returns a lambda function which takes the arguments that the function had received .But I am not sure if by definition of continuation is technically accurate . Can it be brought to use to solve this problem ?
Theres nothing stopping you from writing
the lambda function with like (x == 2)
from functools import reduce
a_lst = [1,2,3,2,3,4,5,6,2,2]
reduce(lambda x, y: x + (y == 2), a_lst, 0) #Output: 4
The reason this works is because bool is a subclass of int in python, and can be used for mathematical operations.
If that alone however does not satisfy you, you can get really involved with the operator and functools modules. Reference docs.
from functools import reduce, partial
import operator
reduce(operator.add,map(lambda x: operator.eq(x, 2), a_lst), 0) #Output: 4
and, replace the lambda with a partial function
equals_2 = partial(operator.eq, 2)
reduce(operator.add,map(equals_2, a_lst), 0) #Output: 4
A Word of caution
It may not be wise to get stuck with one paradigm of programming (functional) in this case. Python excels in allowing any programming paradigm, but practically beats purity. It is just much simpler and easier to iterate through the list and count the number of 2s yourself, using the .count method. No need to reinvent the wheel where it doesn't make sense. To future readers, this is just a demonstration, not a recommendation on how to count occurrences in a list.

Arbitrary functions

I'm trying to teach myself programming and am currently working my way through 'A Primer on Scientific Programming with Python' by Hans Petter Langtangen.
Right now I'm on Exercise 3.20. Unfortunately I don't have any solutions to the problems..
I know I can use an arbitrary (mathematical) function f in the definition of a method:
def diff(f,x,h=0.001):
return (f(x+h)-f(x-h))/2*h
And when I call it i can use whatever function I wish:
print diff(math.exp,0)
print diff(math.cos,2*math.pi)
So here's my question:
Is There a way to accomodate more complex functions in this way?
Say for example I would like to approximate the derivative of a function like
x(t) = e^(-(t-4)^2)
like I did above for cos(x) and e^(x).
Edit: maybe I should be more clear. I'm not specifically trying to differentiate this one function e^(-(t-4)^2) but would like to define a method that takes ANY function of x as an argument and approximates a derivative at point x.
I was impressed when I learned that you could do it for simple functions like cos(x), sin(x) and exp(x) at all. So I thought if that works there must be a way to make it more general..
Sure, just define it first:
def x(t):
return math.exp(-(t-4)**2)
print diff(x, 0)
Instead of using def, it's often possible to use lambda if the function consists of a single expression that is returned:
print diff(lambda t: math.exp(-(t-4)**2), 0)
sure:
def x(t):
return diff(math.exp(-(t-4)**2))

Python3.2: Extended sum() function -- compute the "value" of a list, except not with addition

In some code I'm writing, I'd like a function similar to the built in sum() function, except with my own custom two-argument function as opposed to addition. It's easy to write such a function, but I'm wondering if there's one in the standard library somewhere? I took a look through the itertools doc, but didn't find anything. It would also be similar to itertools.accumulate(mylist)[-1], except with functions other than sums.
My own code for such a function:
def accumulate(iterable, func):
it = iter(iterable)
out = func(next(it), next(it))
for i in it:
out = func(out, i) # "out += i"
return out
So sum(mylist) would be equivalent to accumulate(mylist, lambda x, y: x+y). In my use case of course, I have a different function I'd like to use (it is more complicated than a simple arithmetic operation.)
It seems like this would be a fairly common thing, which is why I'm surprised half an hour of searching didn't find anything like this. So: If and where does such a function exist in the standard library? (I'm using my own code above for now.)
The usual name for that function is fold or reduce, and it's actually built into Python 2 under the latter name:
>>> reduce(lambda x,y: x*y, [1,3,5,4])
60
In Python 3 you have to import it from the functools module.

python 3.x: bind arguments to given values

In Python, for a simple function foo(x, y) there are at least 3 ways that i know to bind the argument y to some value
# defining a nested function:
def foobar(x):
return foo(x, y=yval)
# using lambda
foobar = lambda x: foo(x, y=yval)
# using functools
from functools import partial
foobar = partial(foo, y=yval)
while i am doubtful that the list above is exhaustive, i also wonder which one should i go with? are they all equivalent in terms of performance, safety and namespace handling? or are there extra overheads and caveats with each method? why should functools define partial when the other methods are already there?
No, they're not all equivalent -- in particular, a lambda cannot be pickled and a functools.partial can, IIRC, be pickled only in recent Python versions (I can't find which exact version in the docs; it doesn't work in 2.6, but it does in 3.1). Neither can functions defined inside of other functions (neither in 2.6 nor 3.1).
The reason for partial's appearance in the library is that it gives you an explicit idiom to partially apply a function inline. A definition (def) cannot appear in the middle of an expression such as
map(partial(foo, y=yval), xs)
Also, from a definition or lambda, it's not immediately clear that partial application is what's going on, since you can put an arbitrary expression in a lambda and arbitrary statements in a definition.
I suggest you go with partial unless you have a reason not to use it.
[And indeed, the list is not exhaustive. The first alternative that comes to mind is a callable object:
class foobar:
def __init__(self, yval):
self.__yval = yval
def __call__(self, x):
return foo(x, self.__yval)
but those are heavy-weights for such a simple problem.]

What's the difference between a keyword or a statement, and a function call?

I was thinking about this recently since Python 3 is changing print from a statement to a function.
However, Ruby and CoffeeScript take the opposite approach, since you often leave out parentheses from functions, thereby blurring the distinction between keywords/statements and functions. (A function call without parentheses looks a lot like a keyword.)
Generally, what's the difference between a keyword and a function? It seems to me that some keywords are really just functions. For example, return 3 could equally be thought of as return(3) where the return function is implemented natively in the language. Or in JavaScript, typeof is a keyword, but it seems very much like a function, and can be called with parentheses.
Thoughts?
A function is executed within a stack frame, whereas a keyword statement isn't necessarily. A good example is the return statement: If it were a function and would execute in its own stack, there would be no way it could control the execution flow in the way it does.
Keywords and functions are ambiguous. Whether or not parentheses are necessary is completely dependent upon the design of the language syntax.
Consider an integer declaration, for instance:
int my_integer = 4;
vs
my_integer = int(4)
Both of these examples are logically equivalent, but vary by the language syntax.
Programming languages use keywords to reserve their finite number of basic functions. When you write a function, you are extending a language.
Keywords are lower-level building blocks than functions, and can do things that functions can't.
You cite return in your question, which is a good example: In all the languages you mention, there's no way to use a function to provide the same behavior as return x.
In Python, parenthesis are used for function calls, creating tuples or just for defining precedence.
a = (1) #same as a =1
a = (1,) #tuple with one element
print a #prints the value of a
print(a) #same thing, as (a) == a
def foo(x):
return x+1
foo(10) #function call, one element
foo(10,) #function call, also one element
foo 10 #not allowed!
foo(10)*2 #11 times 2 = 22
def foo2(y):
return (y*2)*2 #Not a function call. Same thing as y*4
Also, keywords can't be assigned as values.
def foo(x):
return x**2
foo = 1234 #foo with new value
return = 10 #invalid!
PS: Another use for parenthesis are generators. Just like list comprehensions but they aren't evaluated after creation.
(x**2 for x in range(10))
sum(x+1 for x in [1,2,3]) #Parenthesis used in function call are 'shared' with generator

Categories