a third through Step Generator

This commit is contained in:
2026-04-29 06:27:05 -04:00
parent 63f32a51cb
commit 680c59513c
9 changed files with 492 additions and 66 deletions

244
steps_generator.py Normal file
View File

@@ -0,0 +1,244 @@
#All Rights Reserved John Salguero
#Generates steps depending on the problem
import algebraic_steps
from sympy import *
from sympy.parsing.sympy_parser import (
parse_expr,
standard_transformations,
implicit_multiplication_application
)
transformations = standard_transformations + (implicit_multiplication_application,)
STEP_GENERATORS = {}
def register_steps_generator(problem_type):
def decorator(func):
STEP_GENERATORS[problem_type] = func
return func
return decorator
@register_steps_generator("linear")
def generate_linear_steps(problem):
#ax + b = c
steps = []
x = symbols('x')
current = problem["problem"]
left, right = current.split("=")
expr = parse_expr(left)
a = expr.coeff(x)
b = expr.subs(x, 0)
## First Step
if b.is_zero == False:
if b.is_negative:
steps.append(algebraic_steps.add_both_sides(current, -b))
elif b.is_positive:
steps.append(algebraic_steps.subtract_both_sides(current, b))
current = steps[-1]["after"]
## Second Step
if a != 1:
steps.append(algebraic_steps.divide_both_sides(current, a))
return steps
@register_steps_generator("hidden_factor")
def generate_hidden_factor_steps(problem):
#a(x + b) + c(x + b) = d
steps = []
x = symbols('x')
current = problem["problem"]
left, right = current.split("=")
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
right_expr = parse_expr(right)
terms = left_expr.as_ordered_terms()
#factors = [term.as_ordered_factors() for term in terms]
#common = set(factors[0]) & set(factors[1])
#base = list(common)[0]
base = terms[0].args[1]
## First Step
steps.append(algebraic_steps.factor_collect(current))
current = steps[-1]["after"]
## Second Step
div = simplify(left_expr / base)
steps.append(algebraic_steps.divide_both_sides(current, div))
current = steps[-1]["after"]
## Third Step
b = base.subs(x, 0)
if b.is_negative:
steps.append(algebraic_steps.add_both_sides(current, -b))
elif b.is_positive:
steps.append(algebraic_steps.subtract_both_sides(current, b))
current = steps[-1]["after"]
left, right = current.split("=")
left_expr = parse_expr(left, transformations=transformations)
right_expr = parse_expr(right)
steps[-1]["after"] = f"{sstr(left_expr)} = {sstr(right_expr)}"
return steps
@register_steps_generator("distribution")
def generate_distribution_steps (problem):
#a(x + b) = c
steps = []
x = symbols('x')
current = problem["problem"]
left, right = current.split("=")
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
right_expr = parse_expr(right)
terms = left_expr.as_ordered_terms()
base = terms[0].args[1]
div = simplify(left_expr / base)
## First Step
steps.append(algebraic_steps.divide_both_sides(current, div))
current = steps[-1]["after"]
## Second Step
b = base.subs(x, 0)
if b.is_negative:
steps.append(algebraic_steps.add_both_sides(current, -b))
elif b.is_positive:
steps.append(algebraic_steps.subtract_both_sides(current, b))
current = steps[-1]["after"]
left, right = current.split("=")
left_expr = parse_expr(left, transformations=transformations)
right_expr = parse_expr(right)
steps[-1]["after"] = f"{sstr(left_expr)} = {sstr(right_expr)}"
return steps
@register_steps_generator("two_sides")
def generate_two_sides_steps (problem):
#ax + b = dx + e : a != d
steps = []
x = symbols('x')
current = problem["problem"]
left, right = current.split("=")
left_expr = parse_expr(left)
right_expr = parse_expr(right)
a = left_expr.coeff(x)
b = left_expr.subs(x, 0)
d = right_expr.coeff(x)
e = right_expr.subs(x, 0)
## First Step
if d.is_negative:
steps.append(algebraic_steps.add_both_sides(current, -d*x))
elif d.is_positive:
steps.append(algebraic_steps.subtract_both_sides(current, d*x))
current = steps[-1]["after"]
left, right = current.split("=")
left_expr = parse_expr(left)
right_expr = parse_expr(right)
steps[-1]["after"] = f"{sstr(left_expr)} = {sstr(right_expr)}"
current = steps[-1]["after"]
## Second Step
if b.is_negative:
steps.append(algebraic_steps.add_both_sides(current, -b))
elif b.is_positive:
steps.append(algebraic_steps.subtract_both_sides(current, b))
current = steps[-1]["after"]
left, right = current.split("=")
left_expr = parse_expr(left, transformations=transformations)
right_expr = parse_expr(right)
steps[-1]["after"] = f"{sstr(left_expr)} = {sstr(right_expr)}"
current = steps[-1]["after"]
## Third Step
new_left, new_right = current.split("=")
new_left_expr = parse_expr(left, transformations=transformations, evaluate=False)
new_right_expr = parse_expr(right, transformations=transformations, evaluate=False)
div = left_expr.coeff(x)
if div != 1 and div != -1:
steps.append(algebraic_steps.divide_both_sides(current, div))
elif div == -1:
steps.append(algebraic_steps.multiply_both_sides(current, div))
return steps
@register_steps_generator("like_terms")
def generate_like_terms_steps (problem):
#ax + bx + c = d
steps = []
current = problem["problem"]
## First Step
steps.append(algebraic_steps.combine_like_terms(current))
current = steps[-1]["after"]
## Second Step
left, right = current.split("=")
left_expr = parse_expr(left)
b = left_expr.subs(x, 0)
return steps
@register_steps_generator("quadratic")
def generate_quadratic_steps (problem):
#ax² + bx + c = 0
steps = []
return steps
@register_steps_generator("difference_squares")
def generate_difference_squares_steps (problem):
#x² - a² = 0
steps = []
return steps
@register_steps_generator("zero_product")
def generate_zero_product_steps (problem):
#(x + a)(x + b) = 0
steps = []
return steps
@register_steps_generator("radical")
def generate_radical_steps (problem):
#√(x + a) = b
steps = []
return steps
@register_steps_generator("fraction")
def generate_fraction_steps (problem):
#(x/a) + b = c
steps = []
return steps
@register_steps_generator("binomial")
def generate_binomial_steps (problem):
#a(x + b) + c(x + d) = e
steps = []
return steps
@register_steps_generator("tricky")
def generate_tricky_steps (problem):
#(x² - x - a) / (x + b) = c
steps = []
return steps
def generate_steps(problem):
problem_type = problem["type"]
if problem_type not in STEP_GENERATORS:
raise ValueError(f"No step generator for type: {problem_type}")
return STEP_GENERATORS[problem["type"]](problem)