import ast import operator import math import sympy as sp import re class Tools: def __init__(self): self.citation = True def calculator(self, equations: str) -> str: """ Calculate the result of a simple equation or comparison. :param equation: The equation to calculate or compare. - For arithmetic operations: Use operators like +, -, *, /, **, //, % - For comparisons: Use operators like >, <, >=, <=, ==, != - For solving systems of equations, separate equations with a semicolon (e.g., 'x + y = 30; 2*x + 4*y = 80') - Evaluating multiple expressions separated by commas (e.g., '-1/27, 19/52') - Example inputs: "3 + 5", "10 / 2", "e ** 2", "pi > 3", "3.11 < 3.8" """ # 预处理:自动添加乘号 modified_equations = re.sub(r"(\d)([a-zA-Z])", r"\1*\2", equations) modified_equations = modified_equations.replace("^", "**") # 检测和解决方程组 if "=" in modified_equations: try: # 分割多个方程(如果有的话) eq_list = modified_equations.split(";") if len(eq_list) > 1: # 检测到多个方程,作为方程组求解 equations_sym = [] symbols = set() for eq in eq_list: left_expr, right_expr = eq.split("=") left_sym = sp.sympify(left_expr) right_sym = sp.sympify(right_expr) symbols |= left_sym.free_symbols | right_sym.free_symbols equations_sym.append(left_sym - right_sym) solution = sp.solve(equations_sym, list(symbols)) # 格式化输出结果为“变量 = 解”的形式 solution_str = ", ".join( f"{str(var)} = {sol}" for var, sol in solution.items() ) return f"The solution to the system of equations '{equations}' is {solution_str}. Provide this solution to the user." else: # 单个方程,正常求解 left_expr, right_expr = eq_list[0].split("=") left_sym = sp.sympify(left_expr) right_sym = sp.sympify(right_expr) symbols = list(left_sym.free_symbols | right_sym.free_symbols) if len(symbols) != 1: return f"The equation '{equations}' contains {len(symbols)} variables. Please provide an equation with only one variable." solution = sp.solve(left_sym - right_sym, symbols[0]) return f"The solution to the equation '{equations}' is {symbols[0]} = {solution[0]}. Provide this solution to the user." except Exception as e: return f"There was an error solving the equation(s) '{equations}': {str(e)}. Notify the user about the issue." ops = { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.Pow: operator.pow, ast.Mod: operator.mod, ast.FloorDiv: operator.floordiv, ast.BitXor: operator.xor, ast.BitAnd: operator.and_, ast.BitOr: operator.or_, } unary_ops = { ast.UAdd: operator.pos, ast.USub: operator.neg, } compare_ops = { ast.Gt: operator.gt, ast.Lt: operator.lt, ast.GtE: operator.ge, ast.LtE: operator.le, ast.Eq: operator.eq, ast.NotEq: operator.ne, } def eval_expr(node): if isinstance(node, ast.Num): return node.n elif isinstance(node, ast.Constant): return node.value elif isinstance(node, ast.Tuple): # 处理元组输入 return tuple(eval_expr(elt) for elt in node.elts) elif isinstance(node, ast.Name): if node.id == "pi": return math.pi elif node.id == "e": return math.e else: raise ValueError(f"Unsupported constant: {node.id}") elif isinstance(node, ast.BinOp): if type(node.op) in ops: return ops[type(node.op)]( eval_expr(node.left), eval_expr(node.right) ) else: raise ValueError(f"Unsupported operation: {type(node.op).__name__}") elif isinstance(node, ast.UnaryOp): if type(node.op) in unary_ops: return unary_ops[type(node.op)](eval_expr(node.operand)) else: raise ValueError( f"Unsupported unary operation: {type(node.op).__name__}" ) elif isinstance(node, ast.Compare): if len(node.ops) == 1: op = node.ops[0] if type(op) in compare_ops: return compare_ops[type(op)]( eval_expr(node.left), eval_expr(node.comparators[0]) ) else: raise ValueError(f"Unsupported comparison: {type(op).__name__}") else: raise ValueError("Unsupported multiple comparisons") else: raise ValueError(f"Unsupported expression type: {type(node).__name__}") try: parsed = ast.parse(modified_equations, mode="eval") result = eval_expr(parsed.body) if isinstance(result, bool): return f"The comparison '{equations}' evaluates to {result}. Respond accordingly." else: return f"The result of the expression '{equations}' is {result}. Provide this information to the user." except (SyntaxError, ValueError) as e: return f"There is an error in the expression '{equations}': {str(e)}. Notify the user about the issue." except ZeroDivisionError: return f"The expression '{equations}' involves a division by zero, which is undefined. Inform the user about this error." except Exception as e: return f"The expression '{equations}' is invalid: {str(e)}. Let the user know that there was a mistake."