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) low = (text or "").lower() 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.", asks_for="the value of the variable or the requested expression built from it", plain_english="Algebra questions usually become easier once you write one clean equation and then reverse the operations in order.", ) 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, solution_path_type=subtype, ) result.givens = [ "A symbolic relationship or equation is implied by the wording.", ] if "=" in low: result.givens.append("An equals sign or equation structure is present.") result.relationships = [ "Both sides of an equation must stay balanced.", "Each algebra step should simplify or isolate the target quantity.", ] result.needed_concepts = [ "equation balancing", "inverse operations", "checking what the question actually asks for", ] result.trap_notes = [ "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.", ] result.strategy_hint = "Rewrite the relationship as one clean equation before doing any manipulation." result.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.key_operations = [ "Simplify", "undo addition/subtraction", "undo multiplication/division", ] scaffold.hint_ladder = [ "What operation is attached to the variable?", "What inverse operation would undo it?", "Apply that same operation to both sides.", ] 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.key_operations = [ "substitute", "eliminate", "back-substitute", ] scaffold.hint_ladder = [ "Which variable looks easier to isolate?", "Can you align coefficients for elimination?", "After finding one variable, plug it back into the other equation.", ] 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.key_operations = [ "translate wording to an inequality", "simplify", "watch for sign reversal with negatives", ] scaffold.hint_ladder = [ "What phrase tells you the direction of the inequality?", "Can you simplify both sides first?", "Did you divide or multiply by a negative at any point?", ] 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.key_operations = [ "standardize the expression", "factor or use structure", "check all roots back in context", ] scaffold.hint_ladder = [ "Can you move everything to one side first?", "Does the expression factor neatly?", "Do all candidate solutions actually fit the original question?", ] 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.key_operations = [ "solve or rewrite the relationship", "substitute carefully", "simplify the requested expression", ] scaffold.hint_ladder = [ "What expression does the question actually want?", "Do you already have enough information to rewrite that expression?", "Only substitute after the target expression is clear.", ] 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.key_operations = [ "translate", "simplify", "isolate", ] scaffold.hint_ladder = [ "What is the unknown?", "What relationship connects the quantities?", "What is the cleanest first algebra step?", ] result.scaffold = scaffold result.meta = { "intent": "explain_question", "bridge_ready": True, "hint_style": "step_ready", "subtype": subtype, } return result