| """Tool: calculator — Evaluate a mathematical expression safely.""" |
| 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.Mod: op.mod, ast.USub: op.neg, ast.UAdd: op.pos, ast.FloorDiv: op.floordiv} |
| def calculator(expression: str): |
| """Evaluate a mathematical expression. Returns float.""" |
| def _eval(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)](_eval(node.left), _eval(node.right)) |
| if isinstance(node, ast.UnaryOp): return _OPS[type(node.op)](_eval(node.operand)) |
| raise ValueError(f"Unsupported: {type(node).__name__}") |
| tree = ast.parse(expression, mode="eval") |
| return float(_eval(tree.body)) |
|
|