Files
Youtube_Math/problem_generator.py
2026-05-01 19:26:08 -04:00

270 lines
7.6 KiB
Python

#All Rights Reserved John Salguero
#Generates Problems from a list of problems
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) if a != 1 or i != 0])
c = a * ans + b
x = symbols('x')
expr = a * x + b
s = sstr(expr)
return {
"type": "linear",
"problem": f"{s} = {c}",
"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 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}({sstr(inner_expr)}) + {c}({sstr(inner_expr)}) = {right_side}"
return {
"type": "hidden_factor",
"problem": problem,
"solution": ans
}
@register_problem_generator("distribution")
def generate_distribution ():
#a(x + b) = c
ans = random.choice([i for i in range(-10, 16)])
a = random.choice([i for i in range(-5, 6) if i not in (0, 1, -1)])
b = random.choice([i for i in range(-5, 6) if i != 0])
c = a * (ans + b)
x = symbols('x')
inner_expr = x + b
return {
"type": "distribution",
"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)])
a = random.choice([i for i in range(-5, 6) if i != 0])
b = random.choice([i for i in range(-5, 6) if i != 0])
d = random.choice([i for i in range(-5, 6) if i != a and i != 0])
e = a * ans + b - d * ans
x = symbols('x')
left_exp = a * x + b
right_exp = d * x + e
return {
"type": "two_sides",
"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)])
a = random.choice([i for i in range(-5, 6) if i != 0])
b = random.choice([i for i in range(-5, 6) if i != 0 and i != -a])
c = random.choice([i for i in range(-10, 16) if i != 0])
d = a * ans + b * ans + c
x = symbols('x')
expr = Add(a*x, b*x, c, evaluate=False)
return {
"type": "like_terms",
"problem": f"{sstr(expr)} = {d}",
"solution": ans
}
@register_problem_generator("quadratic")
def generate_quadratic ():
#ax² + bx + c = 0
r1 = 0
r2 = 0
while r1 == 0 and r2 == 0:
r1 = random.choice(range(-10, 13))
r2 = random.choice(range(-10, 13))
n = random.choice([i for i in range(-5, 6) if i != 0])
s = random.choice([i for i in range(-5, 6) if i != 0])
x = symbols('x')
expr = n *(s * x - r1) * (x - r2)
expr = expand(expr)
root1 = Rational(r1, s)
root2 = Integer(r2)
if root1 == root2:
solution = sstr(root1)
else:
solution = [sstr(root1), sstr(root2)]
return {
"type": "quadratic",
"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) if i != 0])
a = ans
x = symbols('x')
expr = Add(x**2, -a**2)
if ans !=0:
solution = [ans, -ans]
else:
solution = ans
return {
"type": "difference_squares",
"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)])
b = random.choice([i for i in range(-5, 6) if i != a])
x = symbols('x')
expr = Mul(x+a, x+b, evaluate=False)
return {
"type": "zero_product",
"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)])
b = random.choice([i for i in range(1, 12)])
ans = b**2 - a
x = symbols('x')
expr = root(x+a, 2)
return {
"type": "radical",
"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])
b = random.choice([i for i in range(-15, 16)])
c = random.choice([i for i in range(-7, 8)])
ans = (c - b) * a
x = symbols('x')
expr = x / a + b
return {
"type": "fraction",
"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)])
a = random.choice([i for i in range(-5, 6) if i != 0])
b = random.choice([i for i in range(-5, 6)])
c = random.choice([i for i in range(-5, 6) if i != 0 and i != -a])
d = random.choice([i for i in range(-5, 6)])
e = a * (ans + b) + c * (ans + d)
x = symbols('x')
if a != 1:
left_expr = Mul(a, x + b, evaluate=False)
else:
left_expr = x+b
if c != 1:
right_expr = Mul(c, x + d, evaluate=False)
else:
right_expr = x+d
expr = Add(left_expr, right_expr, evaluate=False)
return {
"type": "binomial",
"problem": f"{sstr(expr)} = {e}",
"solution": ans
}
@register_problem_generator("tricky")
def generate_tricky ():
#(x² - x - a) / (x + b) = c
r1 = 0
r2 = 0
while r1 == r2 or r1 == 0 and r2 == 0:
r1 = random.choice(range(-10, 13))
r2 = random.choice(range(-10, 13))
n = random.choice([i for i in range(-5, 6) if i != 0])
x = symbols('x')
expr = (x - r1) * (x - r2)
expanded = expand(expr)
expr = n * (x - r1)
expanded = expanded - expr
expanded = expanded / (x - r1)
# expanded = n
s = sstr(expanded)
return {
"type": "tricky",
"problem": f"{s} = {-n}",
"solution": r2
}
def generate_problem():
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]
problem_type = random.choices(types, weights=weights)[0]
template = TEMPLATES[problem_type]
#return list(TEMPLATES.values())[11]()
#return generate_quadratic()
return template()