0

My app allows the user to specify simple python expressions to use as functions of a given variable. For example, the user could write 'x**2 + 2*x + 4' and my app would parse that into a function of x, equivalent to lambda x: x**2 + 2*x + 4. I already know how to do this with:

def _f(expression, template):
    code = parser.expr(expression).compile()
    return template(code)

def function_x(expression):
    return _f(expression, lambda code: lambda x: eval(code))

However, that only makes a function parser for x. If I want to make a different variable work, I would have to define more parsers, like:

def function_xy(expression):
    return _f(expression, lambda code: lambda x, y: eval(code))

def function_n(expression):
    return _f(expression, lambda code: lambda n: eval(code))

def function_A(expression):
    return _f(expression, lambda code: lambda A: eval(code))

Is there any better way to parse user functions of any pre-specified variable? That is to say, I can predefine a certain input field in the UI to accept functions of u, while predefining another input field to accept functions of v, and so forth. Only the letter u would work in the first input field, while only the letter v would work in the second.

Please note that the variable names themselves are predefined; the user does not pick which letters he or she wants to use.

2
  • 1
    Is this just for fun/education? Because sympy is pretty powerful Commented Jul 6, 2016 at 1:45
  • I am creating a parametric function plotter module for my typesetting app , image. Some other parts of the app also use the same user-function framework, but the set of possible variable letters is rather small so the approach I had above worked fine. I know SymPy can do this kind of stuff well, but SymPy feels like an awfully big hammer to use when all I need is a some extra variable names. Commented Jul 6, 2016 at 1:54

1 Answer 1

1

Use the lambdify module from Sympy, full docs here

The package has several possible ways of addressing this problem, since it support full symbolic computation at a powerful level (e.g., 1, 2, 3)

For example

from sympy import sympify
f = sympify('x**2 + y**2')
f.subs({'x':1, 'y':2})

Depending on how you want to use the package, you could apply it at a core level for a modular design, or sub in expressions at the last moment. The original link shows how to convert from sympy to generic python lambda functions in one way

You'll save yourself a lot of time this route. For example, you're existing "working" code crashes if I input "sin(x)", where sympy handles it with ease. That was the first one I tried - symbolic computation is really hard. IMO, the extra package is worth the big headache and hours down the road of debugging

Sign up to request clarification or add additional context in comments.

7 Comments

To get string parsing, would I need the entire SymPy module? I’m trying to avoid bringing in more outside libraries if not absolutely needed.
Yes you would, at least without painful disentanglement of the library. You're going to wind up re-implementing large parts of it anyway, why not take the careful and expert work already done? Any particular reason not to include more libraries? Licensing problems?
As you scale up symoblic analysis, it's only going to get more difficult. Why not use the expert solution from the ground up?
Because I only need the simplest kind of it; I am writing a plotting module, not an algebraic solver.
No licensing problems; the app is GPL; just benefit-vs-added bloat/dependency considerations
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.