Spaces:
Running
Running
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)}") |