import sympy as sp from sympy.parsing.sympy_parser import parse_expr, standard_transformations, implicit_multiplication_application from sympy.solvers import solve from sympy import integrate, diff, simplify, expand, log, exp, sin, cos, tan, asin, acos, atan, Symbol, factorial, laplace_transform import re def format_expression(expr): """Format expression to make it more readable.""" # Convert string representation to a more readable format str_expr = str(expr) replacements = { '**': '^', '*x': 'x', 'exp': 'e^', 'sqrt': '√', 'factorial': '!' } for old, new in replacements.items(): str_expr = str_expr.replace(old, new) return str_expr def preprocess_equation(equation_str): """Convert user-friendly equation format to SymPy format.""" try: # Replace common mathematical notations replacements = { '^': '**', 'sin⁻¹': 'asin', 'cos⁻¹': 'acos', 'tan⁻¹': 'atan', 'e^': 'exp', 'ln': 'log', # Convert ln to log (SymPy default) '√': 'sqrt', # Convert square root symbol to sqrt() '!': '.factorial()', # Convert factorial to function call } for old, new in replacements.items(): equation_str = equation_str.replace(old, new) equation_str = re.sub(r'(\d+)!', r'factorial(\1)', equation_str) # Handle exponential expressions if 'exp' in equation_str: parts = equation_str.split('exp') for i in range(1, len(parts)): if parts[i] and parts[i][0] != '(': parts[i] = '(' + parts[i] if '=' in parts[i]: exp_part, rest = parts[i].split('=', 1) parts[i] = exp_part + ')=' + rest else: parts[i] = parts[i] + ')' equation_str = 'exp'.join(parts) # Add multiplication symbol where needed processed = '' i = 0 while i < len(equation_str): if i + 1 < len(equation_str): if equation_str[i].isdigit() and equation_str[i+1] == 'x': processed += equation_str[i] + '*' i += 1 continue processed += equation_str[i] i += 1 return processed except Exception as e: raise Exception(f"Error in equation format: {str(e)}") def process_expression(expr_str): """Process mathematical expressions without equations.""" try: processed_expr = preprocess_equation(expr_str) x = Symbol('x') if expr_str.startswith('∫'): # Integration expr_to_integrate = processed_expr[1:].strip() expr = parse_expr(expr_to_integrate, transformations=(standard_transformations + (implicit_multiplication_application,))) result = integrate(expr, x) return f"∫{format_expression(expr)} = {format_expression(result)}" elif expr_str.startswith('d/dx'): # Differentiation expr_to_diff = processed_expr[4:].strip() if expr_to_diff.startswith('(') and expr_to_diff.endswith(')'): expr_to_diff = expr_to_diff[1:-1] expr = parse_expr(expr_to_diff, transformations=(standard_transformations + (implicit_multiplication_application,))) result = diff(expr, x) return f"d/dx({format_expression(expr)}) = {format_expression(result)}" elif 'factorial' in processed_expr: # Factorial case expr = parse_expr(processed_expr, transformations=(standard_transformations + (implicit_multiplication_application,))) result = expr.doit() # Evaluate factorial properly return f"{format_expression(expr)} = {format_expression(result)}" elif '/' in expr_str: # Handle fractions and return decimal expr = parse_expr(processed_expr, transformations=(standard_transformations + (implicit_multiplication_application,))) simplified = simplify(expr) decimal_value = float(simplified) return f"Simplified: {format_expression(simplified)}\nDecimal: {decimal_value}" else: # Regular expression simplification expr = parse_expr(processed_expr, transformations=(standard_transformations + (implicit_multiplication_application,))) simplified = simplify(expr) expanded = expand(simplified) return f"Simplified: {format_expression(simplified)}\nExpanded: {format_expression(expanded)}" except Exception as e: raise Exception(f"Error processing expression: {str(e)}") except Exception as e: raise Exception(f"Error processing expression: {str(e)}") def solve_equation(equation_str): """Solve the given equation and return the solution.""" try: if '=' not in equation_str: return process_expression(equation_str) # Preprocess equation equation_str = preprocess_equation(equation_str) # Split equation into left and right parts left_side, right_side = [side.strip() for side in equation_str.split('=')] # Parse both sides with implicit multiplication transformations = standard_transformations + (implicit_multiplication_application,) left_expr = parse_expr(left_side, transformations=transformations) right_expr = parse_expr(right_side, transformations=transformations) equation = left_expr - right_expr # Solve the equation x = Symbol('x') solution = solve(equation, x) # Format solution if len(solution) == 0: return "No solution exists" elif len(solution) == 1: return f"x = {format_expression(solution[0])}" else: return "x = " + ", ".join([format_expression(sol) for sol in solution]) except Exception as e: raise Exception(f"Invalid equation format: {str(e)}") def generate_steps(equation_str): """Generate step-by-step solution for the equation or expression.""" steps = [] try: if '=' not in equation_str: steps.append(f"1. Original expression: {equation_str}") result = process_expression(equation_str) steps.append(f"2. Result: {result}") return steps # Preprocess equation processed_eq = preprocess_equation(equation_str) # Split equation into left and right parts left_side, right_side = [side.strip() for side in processed_eq.split('=')] # Parse expressions with implicit multiplication transformations = standard_transformations + (implicit_multiplication_application,) left_expr = parse_expr(left_side, transformations=transformations) right_expr = parse_expr(right_side, transformations=transformations) # Step 1: Show original equation steps.append(f"1. Original equation: {format_expression(left_expr)} = {format_expression(right_expr)}") # Step 2: Move all terms to left side equation = left_expr - right_expr steps.append(f"2. Move all terms to left side: {format_expression(equation)} = 0") # Step 3: Factor if possible factored = sp.factor(equation) if factored != equation: steps.append(f"3. Factor the equation: {format_expression(factored)} = 0") # Step 4: Solve x = Symbol('x') solution = solve(equation, x) steps.append(f"4. Solve for x: x = {', '.join([format_expression(sol) for sol in solution])}") # Step 5: Verify solutions steps.append("5. Verify solutions:") for sol in solution: result = equation.subs(x, sol) steps.append(f" When x = {format_expression(sol)}, equation equals {format_expression(result)}") return steps except Exception as e: raise Exception(f"Error generating steps: {str(e)}")