#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 # expanded = n 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)]) 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 generate_quadratic() #return template()