| import ast, operator as op | |
| _OPS = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv, | |
| ast.Pow: op.pow, ast.USub: op.neg, ast.Mod: op.mod} | |
| def _ev(node): | |
| if isinstance(node, ast.Num): return node.n | |
| if isinstance(node, ast.Constant): return node.value | |
| if isinstance(node, ast.BinOp): return _OPS[type(node.op)](_ev(node.left), _ev(node.right)) | |
| if isinstance(node, ast.UnaryOp): return _OPS[type(node.op)](_ev(node.operand)) | |
| raise ValueError("unsafe expression") | |
| def run(params: dict) -> dict: | |
| expr = params.get("expression", "") | |
| try: | |
| return {"result": _ev(ast.parse(expr, mode="eval").body), "expression": expr} | |
| except Exception as e: | |
| return {"error": str(e), "expression": expr} | |