Step Generator Polish, untested
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -18,12 +18,12 @@ def move_all_to_one_side(equation):
|
||||
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"
|
||||
left_expr = clean(parse_expr(left, transformations=transformations, evaluate=False))
|
||||
right_expr = clean(parse_expr(right, transformations=transformations, evaluate=False))
|
||||
new_expr = f"({sstr(left_expr)}) - ({sstr(right_expr)}) = 0"
|
||||
step["after"] = new_expr
|
||||
|
||||
step["step"] = f"Subtract both sides by {sstr(right_expr)}"
|
||||
step["step"] = f"Subtract {sstr(clean(right_expr))} from both sides"
|
||||
step["rule"] = "Subtraction Property of Equality"
|
||||
return step
|
||||
|
||||
@@ -42,7 +42,7 @@ def add_both_sides(equation, value):
|
||||
new_right_expr = clean(right_expr + value)
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Add both sides by {sstr(value)}"
|
||||
step["step"] = f"Add {sstr(value)} to both sides"
|
||||
step["rule"] = "Addition Property of Equality"
|
||||
return step
|
||||
|
||||
@@ -61,7 +61,7 @@ def subtract_both_sides(equation, value):
|
||||
new_right_expr = clean(right_expr - value)
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
|
||||
step["step"] = f"Subtract both sides by {sstr(value)}"
|
||||
step["step"] = f"Subtract {sstr(value)} from both sides"
|
||||
step["rule"] = "Subtraction Property of Equality"
|
||||
return step
|
||||
|
||||
@@ -95,10 +95,21 @@ def multiply_both_sides(equation, value):
|
||||
left_expr = parse_expr(left, transformations=transformations, evaluate=False)
|
||||
right_expr = parse_expr(right, transformations=transformations, evaluate=False)
|
||||
|
||||
new_left_expr = cancel(left_expr * value)
|
||||
new_right_expr = Mul(right_expr, value, evaluate=False)
|
||||
step["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
if left_expr != 1 and left_expr != -1:
|
||||
new_left_expr = cancel(left_expr * value)
|
||||
elif left_expr == 1:
|
||||
new_left_expr = value
|
||||
else:
|
||||
new_left_expr = -value
|
||||
|
||||
if right_expr != 1 and right_expr != -1:
|
||||
new_right_expr = Mul(right_expr, value, evaluate=False)
|
||||
elif right_expr == 1:
|
||||
new_right_expr = value
|
||||
else:
|
||||
new_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
|
||||
@@ -255,11 +266,10 @@ def trinomial_by_grouping(equation, inner):
|
||||
|
||||
steps[-1]["after"] = f"{sstr(new_left_expr)} = {sstr(right_expr)}"
|
||||
steps[-1]["step"] = (
|
||||
f"Seperate the x coefficient to equal the factors of the first times last coefficients"
|
||||
f"({sstr(Abs(a))} x {sstr(Abs(c))} = {sstr(ac)}) that {action} {sstr(Abs(b))}"
|
||||
f"({sstr(factor1)},{sstr(factor2)})"
|
||||
f"Split the x coefficient to two terms that multiply to the first coefficient({sstr(Abs(a))}) "
|
||||
f"times last coefficient({sstr(Abs(c))}) = ({sstr(ac)}) and {action} {sstr(Abs(b))}"
|
||||
)
|
||||
steps[-1]["rule"] = "Split Coefficients"
|
||||
steps[-1]["rule"] = "Factoring by grouping"
|
||||
|
||||
## Factor Out X on left term
|
||||
steps.append({})
|
||||
@@ -267,15 +277,20 @@ def trinomial_by_grouping(equation, inner):
|
||||
|
||||
terms = left_expr.as_ordered_terms()
|
||||
t1, t2, t3, t4 = terms[0], terms[1], terms[2], terms[3]
|
||||
div = gcd(t3, t4)
|
||||
factored_part1 = factor(t1 + t2)
|
||||
factored_part2 = factor(t3 + t4)
|
||||
if t3 != -x:
|
||||
div = gcd(t3, t4)
|
||||
factored_part2 = factor(t3 + t4)
|
||||
else:
|
||||
div = -1
|
||||
factored_part2 = Mul(-1,(-t3 - t4), evaluate=False)
|
||||
rest = sum(terms[2:])
|
||||
new_left_expr = Add(factored_part1, rest, evaluate=False)
|
||||
new_left_expr = Mul(n, new_left_expr, evaluate=False)
|
||||
if n != 1:
|
||||
new_left_expr = Mul(n, new_left_expr, evaluate=False)
|
||||
|
||||
steps[-1]["after"] = f"{sstr(new_left_expr)} = {sstr(right_expr)}"
|
||||
steps[-1]["step"] = f"Factor out the x from the left two terms of the inner polynomial"
|
||||
steps[-1]["step"] = f"Factor out the x from the left two terms of the polynomial"
|
||||
steps[-1]["rule"] = "Reverse Distributive Property"
|
||||
|
||||
## Factor Out GCD on right term
|
||||
@@ -283,27 +298,32 @@ def trinomial_by_grouping(equation, inner):
|
||||
steps[-1]["before"] = steps[-2]["after"]
|
||||
|
||||
left_expr = Add(factored_part1, factored_part2, evaluate=False)
|
||||
new_left_expr = Mul(n, left_expr, evaluate=False)
|
||||
new_left_expr = left_expr
|
||||
if n != 1:
|
||||
new_left_expr = Mul(n, new_left_expr, evaluate=False)
|
||||
|
||||
steps[-1]["after"] = f"{sstr(new_left_expr)} = {sstr(right_expr)}"
|
||||
steps[-1]["step"] = f"Factor out the GCD({sstr(div)}) from the right two terms of the inner polynomial"
|
||||
steps[-1]["step"] = f"Factor out {sstr(div)} to match the common binomial"
|
||||
steps[-1]["rule"] = "Reverse Distributive Property"
|
||||
|
||||
## Add Like Terms
|
||||
## Factor out base
|
||||
if steps[-1]["before"] != steps[-1]["after"]:
|
||||
steps.append({})
|
||||
steps[-1]["before"] = steps[-2]["after"]
|
||||
terms = left_expr.as_ordered_terms()
|
||||
factors = [set(t.as_ordered_factors()) for t in terms]
|
||||
common = set.intersection(*factors)
|
||||
print(f"common:{common}, factors:{factors}, terms:{terms}, left_expr:{sstr(left_expr)}")
|
||||
base = list(common)[0]
|
||||
coeffs = [t.coeff(base) for t in terms]
|
||||
new_expr = sum(coeffs) * base
|
||||
new_left_expr = flatten_mul(Mul(n, new_expr, evaluate=False))
|
||||
new_left_expr = new_expr
|
||||
if n != 1:
|
||||
new_left_expr = flatten_mul(Mul(n, new_left_expr, evaluate=False))
|
||||
|
||||
steps[-1]["after"] = f"{sstr(new_left_expr)} = {sstr(right_expr)}"
|
||||
steps[-1]["step"] = f"Collect the like terms"
|
||||
steps[-1]["rule"] = "Combine the like terms"
|
||||
steps[-1]["step"] = f"Factor out the common factor ({sstr(base)})"
|
||||
steps[-1]["rule"] = "Reverse Distributive Property"
|
||||
|
||||
return steps
|
||||
|
||||
@@ -350,7 +370,7 @@ def solve_roots(equation):
|
||||
steps[-1]["before"] = equation
|
||||
steps[-1]["after"] = f"{sstr(clean_factor)} = 0"
|
||||
steps[-1]["step"] = f"Focus on a root"
|
||||
steps[-1]["rule"] = "Root of a polynomial"
|
||||
steps[-1]["rule"] = "Zero Product Property"
|
||||
|
||||
current = steps[-1]["after"]
|
||||
a = clean_factor.coeff(x)
|
||||
@@ -375,16 +395,17 @@ def solve_roots(equation):
|
||||
steps.append({})
|
||||
steps[-1]["before"] = equation
|
||||
steps[-1]["after"] = solutions
|
||||
steps[-1]["step"] = f"Solved The Roots"
|
||||
steps[-1]["rule"] = "Root of a polynomial"
|
||||
steps[-1]["step"] = f"List the potential solutions"
|
||||
steps[-1]["rule"] = "Zero product property"
|
||||
|
||||
return steps
|
||||
|
||||
def combine_like_terms(equation):
|
||||
step = {}
|
||||
steps = []
|
||||
steps.append({})
|
||||
|
||||
current = equation
|
||||
step["before"] = current
|
||||
steps[-1]["before"] = current
|
||||
left, right = current.split("=")
|
||||
x = symbols('x')
|
||||
|
||||
@@ -421,10 +442,14 @@ def combine_like_terms(equation):
|
||||
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
|
||||
steps[-1]["after"] = f"{sstr(new_left_expr)} = {sstr(new_right_expr)}"
|
||||
steps[-1]["step"] = "Collect Like Terms"
|
||||
steps[-1]["rule"] = "Combine the like terms"
|
||||
|
||||
if steps[-1]["before"] == steps[-1]["after"]:
|
||||
steps = []
|
||||
|
||||
return steps
|
||||
|
||||
def distribute_left_step(equation):
|
||||
steps = []
|
||||
@@ -520,17 +545,17 @@ def check_roots(equation, roots):
|
||||
steps[-1]["before"] = steps[-2]["after"]
|
||||
steps[-1]["after"] = f"{sstr(l_result)} = {sstr(r_result)}"
|
||||
steps[-1]["step"] = f"{value} is correct"
|
||||
steps[-1]["rule"] = "Found Root"
|
||||
steps[-1]["rule"] = "Found a Valid Solution"
|
||||
if len(valid_roots) > 0:
|
||||
valid_roots += ","
|
||||
valid_roots += ", "
|
||||
valid_roots += f"x = {value}"
|
||||
|
||||
|
||||
steps.append({})
|
||||
steps[-1]["before"] = equation
|
||||
steps[-1]["after"] = valid_roots
|
||||
steps[-1]["step"] = f"Found Valid Roots"
|
||||
steps[-1]["rule"] = "Found Solution"
|
||||
steps[-1]["step"] = f"List Valid Solutions"
|
||||
steps[-1]["rule"] = "Problem Solved"
|
||||
|
||||
return steps
|
||||
|
||||
@@ -624,9 +649,8 @@ def distribute_once(expr):
|
||||
# ------------------------------------------------------------
|
||||
return expr, None
|
||||
|
||||
def clean(expr):
|
||||
|
||||
# remove explicit 1 multipliers
|
||||
def clean(expr):
|
||||
expr = expr.replace(
|
||||
lambda e: isinstance(e, Mul),
|
||||
lambda e: Mul(*[arg for arg in e.args if arg != 1])
|
||||
|
||||
@@ -265,6 +265,6 @@ def generate_problem():
|
||||
|
||||
problem_type = random.choices(types, weights=weights)[0]
|
||||
template = TEMPLATES[problem_type]
|
||||
return generate_tricky()
|
||||
return generate_quadratic()
|
||||
#return template()
|
||||
|
||||
@@ -207,7 +207,8 @@ def generate_like_terms_steps (problem):
|
||||
return steps
|
||||
|
||||
@register_steps_generator("quadratic")
|
||||
def generate_quadratic_steps (problem):
|
||||
def generate_quadratic_steps (problem, skip_check=False):
|
||||
print(f"calling generate_quadratic_steps with: {problem["problem"]}")
|
||||
#ax² + bx + c = 0
|
||||
steps = []
|
||||
|
||||
@@ -245,12 +246,13 @@ def generate_quadratic_steps (problem):
|
||||
current = steps[-1]["after"]
|
||||
|
||||
# Check for incorrect answers
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
if not skip_check:
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
|
||||
return steps
|
||||
|
||||
@register_steps_generator("difference_squares")
|
||||
def generate_difference_squares_steps (problem):
|
||||
def generate_difference_squares_steps (problem, skip_check=False):
|
||||
#x² - a² = 0
|
||||
steps = []
|
||||
|
||||
@@ -277,7 +279,8 @@ def generate_difference_squares_steps (problem):
|
||||
current = steps[-1]["after"]
|
||||
|
||||
# Check for incorrect answers
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
if not skip_check:
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
|
||||
return steps
|
||||
|
||||
@@ -292,7 +295,7 @@ def generate_zero_product_steps (problem):
|
||||
return steps
|
||||
|
||||
@register_steps_generator("radical")
|
||||
def generate_radical_steps (problem):
|
||||
def generate_radical_steps (problem, skip_check=False):
|
||||
#√(x + a) = b
|
||||
steps = []
|
||||
x = symbols('x')
|
||||
@@ -321,7 +324,8 @@ def generate_radical_steps (problem):
|
||||
current = steps[-1]["after"]
|
||||
|
||||
# Check for incorrect answers
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
if not skip_check:
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
|
||||
return steps
|
||||
|
||||
@@ -375,7 +379,7 @@ def generate_binomial_steps (problem):
|
||||
init_printing(order='lex')
|
||||
|
||||
## Combine Like Terms
|
||||
steps.append(algebraic_steps.combine_like_terms(current))
|
||||
steps.extend(algebraic_steps.combine_like_terms(current))
|
||||
current = steps[-1]["after"]
|
||||
left, right = current.split("=")
|
||||
left_expr = parse_expr(left, transformations=transformations)
|
||||
@@ -404,7 +408,7 @@ def generate_binomial_steps (problem):
|
||||
return steps
|
||||
|
||||
@register_steps_generator("tricky")
|
||||
def generate_tricky_steps (problem):
|
||||
def generate_tricky_steps (problem, skip_check=False):
|
||||
#(x² - x - a) / (x + b) = c
|
||||
steps = []
|
||||
x = symbols('x')
|
||||
@@ -429,16 +433,16 @@ def generate_tricky_steps (problem):
|
||||
current = steps[-1]["after"]
|
||||
|
||||
# Combine Like Terms
|
||||
steps.append(algebraic_steps.combine_like_terms(current))
|
||||
steps.extend(algebraic_steps.combine_like_terms(current))
|
||||
current = steps[-1]["after"]
|
||||
|
||||
# Solve Quadratic
|
||||
print(f"calling generate_quadratic_steps with: {current}")
|
||||
steps.extend(generate_quadratic_steps({"problem" : current}))
|
||||
steps.extend(generate_quadratic_steps({"problem" : current}, True))
|
||||
current = steps[-1]["after"]
|
||||
|
||||
# Check for incorrect answers
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
if not skip_check:
|
||||
steps.extend(algebraic_steps.check_roots(problem["problem"], current))
|
||||
|
||||
return steps
|
||||
|
||||
|
||||
Reference in New Issue
Block a user