"""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))