Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a formula as a function parameter in 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

like image 400
Simon Avatar asked Dec 19 '22 14:12

Simon


2 Answers

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
like image 59
unutbu Avatar answered Dec 29 '22 16:12

unutbu


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)
like image 45
chepner Avatar answered Dec 29 '22 17:12

chepner