File size: 8,985 Bytes
1457c41 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | 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 |