Alternative to 'eval'

I have students who are using Anvil for a class project. Their code requires eval() in order to evaluate mathematical expressions (ex. ‘2*4+(6/2)’), but eval apparently isn’t implemented. Is there an alternative that doesn’t require that they build a custom eval function that can handle this?

sympy is what I’d use for that sort of thing. It’s available on the server side on a paid plan.

Failing that, you could run it locally and use uplink to connect that to anvil.

2 Likes

As you’ve noticed - eval is not available for client side python.

For some security issues I don’ think it’s recommended to do eval for javascript but as a class project to do some maths I can’t see it being a problem.

Here’s two alternatives for eval on the client and both should work for simple maths expressions which don’t rely on variables so

x = eval('1+2') # will work
y = eval('x+1') # won't work

https://anvil.works/build#clone:XWTARROOTTB5EJBS=A76XRDZV7PSJYJ7DQA3OOBGT

The first does the eval on the server

@anvil.server.callable
def eval_expression(expr):
  return eval(expr)

The second does a simple js_call and runs javascripts eval function

function eval_expression(expr) {
  return eval(expr)
}

Then on the client you can do:

eval = lambda expr: anvil.server.call('eval_expression', expr)
# or
eval = lambda expr: js.call_js('eval_expression', expr)

2 Likes

Try this out: it is working for me in the client:

formula = 'x**2 - 2*x -8'
for x in range(-5, 6, 1):
    y = eval(formula, {"x": x})
    # etc
2 Likes

Thanks for the post @gmccarthy and welcome to the forum

Since oct 20, client-side eval and exec were partially implemented.

Why partially?
As your post hints - the dictionary you pass in is required (it shouldn’t be but it is).
The dictionary provides eval with the global context, and
(currently) the client-side implementation of eval doesn’t deal with the global context correctly.

3 Likes