a third through Step Generator
This commit is contained in:
BIN
__pycache__/algebraic_steps.cpython-313.pyc
Normal file
BIN
__pycache__/algebraic_steps.cpython-313.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
__pycache__/steps.cpython-313.pyc
Normal file
BIN
__pycache__/steps.cpython-313.pyc
Normal file
Binary file not shown.
BIN
__pycache__/steps_generator.cpython-313.pyc
Normal file
BIN
__pycache__/steps_generator.cpython-313.pyc
Normal file
Binary file not shown.
197
algebraic_steps.py
Normal file
197
algebraic_steps.py
Normal file
@@ -0,0 +1,197 @@
|
||||
#All Rights Reserved John Salguero
|
||||
#Steps that are generated
|
||||
|
||||
from sympy import *
|
||||
from sympy.parsing.sympy_parser import (
|
||||
parse_expr,
|
||||
standard_transformations,
|
||||
implicit_multiplication_application
|
||||
)
|
||||
transformations = standard_transformations + (implicit_multiplication_application,)
|
||||
|
||||
def move_all_to_one_side(equation):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
new_expr = left_expr - right_expr
|
||||
step["after"] = f"{sstr(new_expr)} = 0"
|
||||
|
||||
step["step"] = f"Subtract both sides by {sstr(right_expr)}"
|
||||
step["rule"] = "Subtraction Property of Equality"
|
||||
return step
|
||||
|
||||
def add_both_sides(equation, value):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = left_expr + value
|
||||
new_right_expr = right_expr + value
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Add both sides by {sstr(value)}"
|
||||
step["rule"] = "Addition Property of Equality"
|
||||
return step
|
||||
|
||||
def subtract_both_sides(equation, value):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = left_expr - value
|
||||
new_right_expr = right_expr - value
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Subtract both sides by {sstr(value)}"
|
||||
step["rule"] = "Subtraction Property of Equality"
|
||||
return step
|
||||
|
||||
def divide_both_sides(equation, value):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = clean(left_expr / value)
|
||||
new_right_expr = clean(right_expr / value)
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Divide both sides by {sstr(value)}"
|
||||
step["rule"] = "Division Property of Equality"
|
||||
return step
|
||||
|
||||
def multiply_both_sides(equation, value):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = left_expr * value
|
||||
new_right_expr = right_expr * value
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Multiply both sides by {sstr(value)}"
|
||||
step["rule"] = "Multiplication Property of Equality"
|
||||
return step
|
||||
|
||||
def factor_collect(equation):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = factor(left_expr)
|
||||
new_right_expr = factor(right_expr)
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Collect the factors"
|
||||
step["rule"] = "Factoring by grouping"
|
||||
return step
|
||||
|
||||
def factor_form_collection(equation, factor):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = collect(left_expr, factor)
|
||||
new_right_expr = collect(right_expr, factor)
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Collect the factors using factor {sstr(factor)}"
|
||||
step["rule"] = "Factor by grouping"
|
||||
return step
|
||||
|
||||
def combine_like_terms(equation):
|
||||
step = {}
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
## Combine Left Terms
|
||||
left_terms = left_expr.as_ordered_terms()
|
||||
# group by base
|
||||
left_groups = {}
|
||||
for t in left_terms:
|
||||
coeff, rest = t.as_coeff_Mul()
|
||||
left_groups.setdefault(rest, 0)
|
||||
left_groups[rest] += coeff
|
||||
# rebuild manually
|
||||
new_left_terms = []
|
||||
for base, coeff in left_groups.items():
|
||||
if coeff != 0:
|
||||
new_left_terms.append(coeff * base)
|
||||
new_left_expr = sum(new_left_terms)
|
||||
|
||||
## Comnine Right Terms
|
||||
right_terms = right_expr.as_ordered_terms()
|
||||
# group by base
|
||||
right_groups = {}
|
||||
for t in right_terms:
|
||||
coeff, rest = t.as_coeff_Mul()
|
||||
right_groups.setdefault(rest, 0)
|
||||
right_groups[rest] += coeff
|
||||
# rebuild manually
|
||||
new_right_terms = []
|
||||
for base, coeff in right_groups.items():
|
||||
if coeff != 0:
|
||||
new_right_terms.append(coeff * base)
|
||||
new_right_expr = sum(new_right_terms)
|
||||
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
step["step"] = "Collect Like Terms"
|
||||
step["rule"] = "Combine the like terms"
|
||||
return step
|
||||
|
||||
def clean(expr):
|
||||
|
||||
# remove explicit 1 multipliers
|
||||
expr = expr.replace(
|
||||
lambda e: isinstance(e, Mul),
|
||||
lambda e: Mul(*[arg for arg in e.args if arg != 1])
|
||||
)
|
||||
|
||||
return expr
|
||||
35
main.py
35
main.py
@@ -1,44 +1,19 @@
|
||||
#All Rights Reserved John Salguero
|
||||
#Starts the backend to my Youtube stream
|
||||
|
||||
from problem_generator import generate_problem, normalize
|
||||
from mathhook import parse, solve
|
||||
from sympy import sympify
|
||||
from problem_generator import generate_problem
|
||||
from steps_generator import generate_steps
|
||||
|
||||
#define the entry point to the programs
|
||||
def main():
|
||||
problem = generate_problem()
|
||||
|
||||
steps = generate_steps(problem);
|
||||
|
||||
print("Generated Problem:")
|
||||
print(problem)
|
||||
print("Solve:")
|
||||
equation = apply_strategy(problem)
|
||||
|
||||
expr = parse(equation)
|
||||
result = solve(expr, "x")
|
||||
print(result)
|
||||
|
||||
def square_both_sides(problem):
|
||||
lhs, rhs = problem["problem"].split("=")
|
||||
|
||||
lhs = sympify(lhs.strip())
|
||||
rhs = sympify(rhs.strip())
|
||||
|
||||
lhs = lhs ** 2
|
||||
rhs = rhs ** 2
|
||||
|
||||
return f"{normalize(lhs)} = {normalize(rhs)}"
|
||||
|
||||
def factor_or_formula(problem) :
|
||||
return problem["problem"]
|
||||
|
||||
def apply_strategy(problem):
|
||||
if problem["type"] == "radical":
|
||||
return square_both_sides(problem)
|
||||
if problem["type"] == "quadratics":
|
||||
return factor_or_formula(problem)
|
||||
return problem["problem"]
|
||||
print("Steps:")
|
||||
print(steps)
|
||||
|
||||
#Starts the program
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -4,17 +4,26 @@
|
||||
import random
|
||||
from sympy import *
|
||||
|
||||
TEMPLATES = {}
|
||||
|
||||
def register_problem_generator(problem_type):
|
||||
def decorator(func):
|
||||
TEMPLATES[problem_type] = func
|
||||
return func
|
||||
return decorator
|
||||
|
||||
@register_problem_generator("linear")
|
||||
def generate_linear():
|
||||
#ax + b = c
|
||||
a = random.choice([i for i in range(-10, 16) if i != 0])
|
||||
ans = random.choice([i for i in range(-10, 11)])
|
||||
b = random.choice([i for i in range(-10, 11)])
|
||||
b = random.choice([i for i in range(-10, 11) if a != 1 or i != 0])
|
||||
|
||||
c = a * ans + b
|
||||
x = symbols('x')
|
||||
expr = a * x + b
|
||||
# expanded = n
|
||||
s = normalize(expr)
|
||||
s = sstr(expr)
|
||||
|
||||
return {
|
||||
"type": "linear",
|
||||
@@ -22,20 +31,21 @@ def generate_linear():
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("hidden_factor")
|
||||
def generate_hidden_factor():
|
||||
#a(x + b) + c(x + b) = d
|
||||
ans = random.choice([i for i in range(-10, 16)])
|
||||
b = random.choice([i for i in range(-5, 6) if i != 0])
|
||||
|
||||
a = random.choice([i for i in range(-5, 6) if i != 0])
|
||||
c = random.choice([i for i in range(-5, 6) if i != 0])
|
||||
c = random.choice([i for i in range(-5, 6) if i != 0 and i != -a])
|
||||
|
||||
x = symbols('x')
|
||||
inner_expr = x + b
|
||||
inner_value = ans + b
|
||||
right_side = a * inner_value + c * inner_value
|
||||
|
||||
problem = f"{a}({normalize(inner_expr)}) + {c}({normalize(inner_expr)}) = {right_side}"
|
||||
problem = f"{a}({sstr(inner_expr)}) + {c}({sstr(inner_expr)}) = {right_side}"
|
||||
|
||||
return {
|
||||
"type": "hidden_factor",
|
||||
@@ -43,6 +53,7 @@ def generate_hidden_factor():
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("distribution")
|
||||
def generate_distribution ():
|
||||
#a(x + b) = c
|
||||
ans = random.choice([i for i in range(-10, 16)])
|
||||
@@ -55,10 +66,11 @@ def generate_distribution ():
|
||||
|
||||
return {
|
||||
"type": "distribution",
|
||||
"problem": f"{a}({normalize(inner_expr)}) = {c}",
|
||||
"problem": f"{a}({sstr(inner_expr)}) = {c}",
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("two_sides")
|
||||
def generate_two_sides ():
|
||||
#ax + b = dx + e : a != d
|
||||
ans = random.choice([i for i in range(-10, 16)])
|
||||
@@ -73,10 +85,11 @@ def generate_two_sides ():
|
||||
|
||||
return {
|
||||
"type": "two_sides",
|
||||
"problem": f"{normalize(left_exp)} = {normalize(right_exp)}",
|
||||
"problem": f"{sstr(left_exp)} = {sstr(right_exp)}",
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("like_terms")
|
||||
def generate_like_terms ():
|
||||
#ax + bx + c = d
|
||||
ans = random.choice([i for i in range(-10, 16)])
|
||||
@@ -90,10 +103,11 @@ def generate_like_terms ():
|
||||
|
||||
return {
|
||||
"type": "like_terms",
|
||||
"problem": f"{normalize(expr)} = {d}",
|
||||
"problem": f"{sstr(expr)} = {d}",
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("quadratic")
|
||||
def generate_quadratic ():
|
||||
#ax² + bx + c = 0
|
||||
r1 = random.choice([i for i in range(-10, 16)])
|
||||
@@ -103,7 +117,7 @@ def generate_quadratic ():
|
||||
|
||||
x = symbols('x')
|
||||
expr = n *(x - r1) * (x - r2)
|
||||
expr = simplify(expr)
|
||||
expr = expand(expr)
|
||||
if r1 == r2:
|
||||
solution = r1
|
||||
else:
|
||||
@@ -111,10 +125,11 @@ def generate_quadratic ():
|
||||
|
||||
return {
|
||||
"type": "quadratic",
|
||||
"problem": f"{normalize(expr)} = 0",
|
||||
"problem": f"{sstr(expr)} = 0",
|
||||
"solution": solution
|
||||
}
|
||||
|
||||
@register_problem_generator("difference_squares")
|
||||
def generate_difference_squares ():
|
||||
#x² - a² = 0
|
||||
ans = random.choice([i for i in range(0, 13)])
|
||||
@@ -130,10 +145,11 @@ def generate_difference_squares ():
|
||||
|
||||
return {
|
||||
"type": "difference_squares",
|
||||
"problem": f"{normalize(expr)} = 0",
|
||||
"problem": f"{sstr(expr)} = 0",
|
||||
"solution": solution
|
||||
}
|
||||
|
||||
@register_problem_generator("zero_product")
|
||||
def generate_zero_product ():
|
||||
#(x + a)(x + b) = 0
|
||||
a = random.choice([i for i in range(-5, 6)])
|
||||
@@ -144,10 +160,11 @@ def generate_zero_product ():
|
||||
|
||||
return {
|
||||
"type": "zero_product",
|
||||
"problem": f"{normalize(expr)} = 0",
|
||||
"problem": f"{sstr(expr)} = 0",
|
||||
"solution": [-a, -b]
|
||||
}
|
||||
|
||||
@register_problem_generator("radical")
|
||||
def generate_radical ():
|
||||
#√(x + a) = b
|
||||
a = random.choice([i for i in range(-10, 16)])
|
||||
@@ -159,10 +176,11 @@ def generate_radical ():
|
||||
|
||||
return {
|
||||
"type": "radical",
|
||||
"problem": f"{normalize(expr)} = {b}",
|
||||
"problem": f"{sstr(expr)} = {b}",
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("fraction")
|
||||
def generate_fraction ():
|
||||
#(x/a) + b = c
|
||||
a = random.choice([i for i in range(-7, 8) if i != 0 and i != 1])
|
||||
@@ -175,10 +193,11 @@ def generate_fraction ():
|
||||
|
||||
return {
|
||||
"type": "fraction",
|
||||
"problem": f"{normalize(expr)} = {c}",
|
||||
"problem": f"{sstr(expr)} = {c}",
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("binomial")
|
||||
def generate_binomial ():
|
||||
#a(x + b) + c(x + d) = e
|
||||
ans = random.choice([i for i in range(-15, 16)])
|
||||
@@ -197,12 +216,13 @@ def generate_binomial ():
|
||||
|
||||
return {
|
||||
"type": "binomial",
|
||||
"problem": f"{normalize(expr)} = {e}",
|
||||
"problem": f"{sstr(expr)} = {e}",
|
||||
"solution": ans
|
||||
}
|
||||
|
||||
@register_problem_generator("tricky")
|
||||
def generate_tricky ():
|
||||
#generate random numbers
|
||||
#(x² - x - a) / (x + b) = c
|
||||
n = random.choice([i for i in range(-5, 6) if i != 0])
|
||||
r1 = random.choice([i for i in range(-10, 16)])
|
||||
r2 = random.choice([i for i in range(-10, 16) if i != r1])
|
||||
@@ -214,7 +234,7 @@ def generate_tricky ():
|
||||
expanded = expanded - expr
|
||||
expanded = expanded / (x - r1)
|
||||
# expanded = n
|
||||
s = normalize(expanded)
|
||||
s = sstr(expanded)
|
||||
|
||||
return {
|
||||
"type": "tricky",
|
||||
@@ -222,24 +242,15 @@ def generate_tricky ():
|
||||
"solution": r2
|
||||
}
|
||||
|
||||
def normalize(expr):
|
||||
return sstr(expr).replace("**", "^")
|
||||
|
||||
def generate_problem():
|
||||
template = random.choice(TEMPLATES)
|
||||
return template()
|
||||
types = list(TEMPLATES.keys())
|
||||
#print(types)
|
||||
# ['linear', 'hidden_factor', 'distribution', 'two_sides', 'like_terms', 'quadratic', 'difference_squares', 'zero_product', 'radical', 'fraction', 'binomial', 'tricky']
|
||||
weights = [0.80 , 0.90 , 0.70 , 1.00 , 0.9 , 1.0 , 0.80 , 0.70 , 0.70 , 1.00 , 1.00 , 0.65]
|
||||
|
||||
TEMPLATES = [
|
||||
generate_linear,
|
||||
generate_hidden_factor,
|
||||
generate_distribution,
|
||||
generate_two_sides,
|
||||
generate_like_terms,
|
||||
generate_quadratic,
|
||||
generate_difference_squares,
|
||||
generate_zero_product,
|
||||
generate_radical,
|
||||
generate_fraction,
|
||||
generate_binomial,
|
||||
generate_tricky
|
||||
]
|
||||
problem_type = random.choices(types, weights=weights)[0]
|
||||
template = TEMPLATES[problem_type]
|
||||
return generate_like_terms()
|
||||
#return template()
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
sympy
|
||||
mathhook
|
||||
sympy
|
||||
244
steps_generator.py
Normal file
244
steps_generator.py
Normal 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)
|
||||
Reference in New Issue
Block a user