Pregunta

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

¿Fue útil?

Solución

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

Otros consejos

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top