import re from .explainer_types import ExplainerResult, ExplainerScaffold _ALGEBRA_PATTERNS = [ r"=", r"\bsolve\b", r"\bequation\b", r"\bexpression\b", r"\bvalue of\b", r"\bwhat is x\b", r"\bwhat is y\b", r"\bvariable\b", ] def _looks_like_algebra_question(text: str) -> bool: low = (text or "").lower() if re.search(r"\b[xyzab]\b", low) and "=" in low: return True if any(re.search(p, low) for p in _ALGEBRA_PATTERNS): return True return False def _infer_algebra_subtype(text: str) -> str: low = (text or "").lower() if any(k in low for k in ["system", "simultaneous", "x and y", "two equations"]): return "system" if any(k in low for k in ["inequality", "<", ">", "at least", "at most", "no more than"]): return "inequality" if any(k in low for k in ["quadratic", "squared", "^2", "x2", "root", "factor"]): return "quadratic" if any(k in low for k in ["expression", "value of 2x", "value of x +", "in terms of"]): return "expression_evaluation" if "=" in low: return "linear_equation" return "generic_algebra" def explain_algebra_question(text: str): if not _looks_like_algebra_question(text): return None subtype = _infer_algebra_subtype(text) result = ExplainerResult( understood=True, topic="algebra", summary="This is an algebra problem. The main goal is to translate the wording into a clean symbolic relationship and isolate the requested quantity step by step." ) scaffold = ExplainerScaffold( concept="Algebra represents unknown quantities symbolically, then uses valid transformations to isolate or compare them.", ask="Identify the unknown, identify the governing relationship, and check whether the question wants the variable itself or an expression built from it.", target="Set up the simplest correct equation or relation before manipulating it.", answer_hidden=True, ) teaching_points = [ "Most algebra errors happen before the solving starts: either the variable is misdefined, or the equation is set up incorrectly.", "A clean equation makes the solving steps much easier.", "You should always check whether the question asks for x itself or for something derived from x." ] if subtype == "linear_equation": scaffold.setup_actions = [ "Identify the unknown and write the equation cleanly.", "Simplify each side if needed.", "Undo operations in a logical order to isolate the variable." ] scaffold.intermediate_steps = [ "Combine like terms first when possible.", "Move variable terms and constant terms carefully.", "Check whether the final result should be the variable or a substituted expression." ] scaffold.first_move = "Rewrite the relationship as one clean equation if it is not already in that form." scaffold.next_hint = "Simplify both sides before isolating the variable." scaffold.variables_to_define = [ "Let the unknown quantity be x if the question has not already named it." ] scaffold.equations_to_form = [ "Build one equation from the stated relationship." ] scaffold.common_traps = [ "Moving terms across the equals sign incorrectly.", "Trying to isolate the variable before simplifying.", "Finding x and forgetting the question asks for something like 2x or x + 3." ] elif subtype == "system": scaffold.setup_actions = [ "Identify the separate equations and unknowns.", "Decide whether substitution or elimination is the cleaner method.", "Reduce the system to one variable before solving completely." ] scaffold.intermediate_steps = [ "Make one variable easy to substitute, or align coefficients for elimination.", "After finding one variable, substitute back carefully.", "Check whether the question asks for one variable, both variables, or a combination of them." ] scaffold.first_move = "Choose one variable to eliminate or substitute." scaffold.next_hint = "Turn the system into a single-variable equation before solving." scaffold.equations_to_form = [ "Use the two given equations together to reduce to one unknown." ] scaffold.common_traps = [ "Mixing substitution and elimination without a clear plan.", "Arithmetic mistakes when substituting back.", "Stopping after finding one variable when the question asks for something else." ] elif subtype == "inequality": scaffold.setup_actions = [ "Translate the condition into an inequality.", "Manipulate it like an equation, but track the inequality direction carefully.", "Reverse the sign only if multiplying or dividing by a negative number." ] scaffold.intermediate_steps = [ "Simplify both sides first if possible.", "Isolate the variable systematically.", "Interpret the final solution set in the form the question wants." ] scaffold.first_move = "Set up the inequality carefully from the wording." scaffold.next_hint = "Solve it step by step, watching for any operation that would reverse the sign." scaffold.common_traps = [ "Forgetting to reverse the inequality when dividing or multiplying by a negative.", "Treating phrase-based conditions like at least or no more than incorrectly.", "Reporting a single number when the solution is actually a range." ] elif subtype == "quadratic": scaffold.setup_actions = [ "Rewrite the equation so one side is zero if needed.", "Look for factoring, structure, or another simplifying method.", "Treat each factor or case carefully once the equation is structured properly." ] scaffold.intermediate_steps = [ "Factor if the form allows it.", "Otherwise identify another clean solving route.", "Check whether all resulting values are allowed in the original context." ] scaffold.first_move = "Put the expression into a standard structured form before solving." scaffold.next_hint = "Then look for a factorable pattern or another clean route." scaffold.common_traps = [ "Trying to factor before the expression is fully simplified.", "Dropping one valid case.", "Giving roots when the question asks for a derived expression instead." ] elif subtype == "expression_evaluation": scaffold.setup_actions = [ "Find the variable or relationship first.", "Only then substitute into the requested expression.", "Simplify the final expression carefully." ] scaffold.intermediate_steps = [ "Do not stop when you find the variable unless that is exactly what the question asks.", "Preserve parentheses during substitution.", "Check whether there is a shortcut using the given relationship directly." ] scaffold.first_move = "Work out whether you need to solve for the variable first or can rewrite the target expression directly." scaffold.next_hint = "Once the relationship is clear, substitute only into the exact expression the question asks for." scaffold.common_traps = [ "Stopping at x when the question asks for something built from x.", "Substituting incorrectly into expressions with multiple terms.", "Ignoring an easier algebraic simplification path." ] else: scaffold.setup_actions = [ "Define the unknown clearly.", "Translate the wording into a symbolic relationship.", "Manipulate the relationship only after the setup is clean." ] scaffold.intermediate_steps = [ "Simplify before isolating.", "Keep track of what the question actually asks for.", "Check the final quantity against the prompt." ] scaffold.first_move = "Start by translating the words into one clean symbolic statement." scaffold.next_hint = "Then simplify the structure before solving." scaffold.common_traps = [ "Poor variable definition.", "Messy setup before solving.", "Answering the wrong final quantity." ] result.teaching_points = teaching_points result.scaffold = scaffold result.meta = { "intent": "explain_question", "bridge_ready": True, "hint_style": "step_ready", "subtype": subtype, } return result