Update explainers/explainer_probability.py
Browse files
explainers/explainer_probability.py
CHANGED
|
@@ -2,10 +2,9 @@ import re
|
|
| 2 |
from .explainer_types import ExplainerResult, ExplainerScaffold
|
| 3 |
|
| 4 |
|
| 5 |
-
def explain_probability_question(text: str)
|
| 6 |
-
|
| 7 |
|
| 8 |
-
# ✅ STRONG detection
|
| 9 |
probability_signals = [
|
| 10 |
"probability",
|
| 11 |
"chance",
|
|
@@ -19,64 +18,103 @@ def explain_probability_question(text: str) -> ExplainerResult | None:
|
|
| 19 |
"with replacement",
|
| 20 |
]
|
| 21 |
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
if not has_probability:
|
| 25 |
return None
|
| 26 |
|
| 27 |
-
|
| 28 |
-
relationships = []
|
| 29 |
-
constraints = []
|
| 30 |
-
trap_notes = []
|
| 31 |
-
|
| 32 |
-
numbers = re.findall(r"\b\d+\b", t)
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
if numbers:
|
| 35 |
-
givens.append(f"Numbers mentioned: {', '.join(numbers[:5])}")
|
| 36 |
else:
|
| 37 |
-
givens.append("A situation involving possible outcomes is described")
|
| 38 |
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
-
if "
|
| 47 |
-
|
|
|
|
| 48 |
|
| 49 |
-
if "
|
| 50 |
-
relationships.append("
|
| 51 |
|
| 52 |
-
if "
|
| 53 |
-
relationships.append("
|
| 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 |
-
strategy_hint="Start by identifying all possible outcomes, then count how many satisfy the condition.",
|
| 81 |
-
plain_english="The question is asking you to work out how likely an event is by comparing favorable outcomes to all possible outcomes.",
|
| 82 |
-
)
|
|
|
|
| 2 |
from .explainer_types import ExplainerResult, ExplainerScaffold
|
| 3 |
|
| 4 |
|
| 5 |
+
def explain_probability_question(text: str):
|
| 6 |
+
low = (text or "").lower()
|
| 7 |
|
|
|
|
| 8 |
probability_signals = [
|
| 9 |
"probability",
|
| 10 |
"chance",
|
|
|
|
| 18 |
"with replacement",
|
| 19 |
]
|
| 20 |
|
| 21 |
+
if not any(signal in low for signal in probability_signals):
|
|
|
|
|
|
|
| 22 |
return None
|
| 23 |
|
| 24 |
+
subtype = "dependent_events" if "without replacement" in low else "independent_events" if "with replacement" in low else "general_probability"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
+
result = ExplainerResult(
|
| 27 |
+
understood=True,
|
| 28 |
+
topic="probability",
|
| 29 |
+
summary="This is a probability problem. The goal is to compare favorable outcomes to total possible outcomes.",
|
| 30 |
+
asks_for="the probability of a specific event or combination of events",
|
| 31 |
+
plain_english="Probability questions become much easier once you define exactly what counts as success and what the full sample space is.",
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
scaffold = ExplainerScaffold(
|
| 35 |
+
concept="Probability compares favorable outcomes to total outcomes.",
|
| 36 |
+
ask="Identify what counts as a successful outcome and what the total possible outcomes are.",
|
| 37 |
+
target="Set up favorable ÷ total before calculating.",
|
| 38 |
+
answer_hidden=True,
|
| 39 |
+
solution_path_type=subtype,
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
numbers = re.findall(r"\b\d+\b", low)
|
| 43 |
if numbers:
|
| 44 |
+
result.givens.append(f"Numbers mentioned: {', '.join(numbers[:5])}")
|
| 45 |
else:
|
| 46 |
+
result.givens.append("A situation involving possible outcomes is described.")
|
| 47 |
|
| 48 |
+
result.relationships = [
|
| 49 |
+
"Probability = favorable outcomes ÷ total possible outcomes",
|
| 50 |
+
]
|
| 51 |
+
result.needed_concepts = [
|
| 52 |
+
"favorable vs total outcomes",
|
| 53 |
+
"independent vs dependent events",
|
| 54 |
+
"complement rule",
|
| 55 |
+
]
|
| 56 |
+
result.trap_notes = [
|
| 57 |
+
"Make sure you correctly identify the total number of possible outcomes.",
|
| 58 |
+
"Check whether events are independent or dependent.",
|
| 59 |
+
"Watch for 'at least' — often easier to use the complement.",
|
| 60 |
+
"Be careful not to double count outcomes.",
|
| 61 |
+
]
|
| 62 |
+
result.strategy_hint = "Start by identifying all possible outcomes, then count how many satisfy the condition."
|
| 63 |
|
| 64 |
+
if "without replacement" in low:
|
| 65 |
+
result.constraints.append("The total number of items decreases after each draw.")
|
| 66 |
+
result.relationships.append("The probabilities change after each selection.")
|
| 67 |
|
| 68 |
+
if "with replacement" in low:
|
| 69 |
+
result.relationships.append("The probabilities stay the same for each selection.")
|
| 70 |
|
| 71 |
+
if "at least" in low:
|
| 72 |
+
result.relationships.append("This may be easier through the complement: 1 − probability of the opposite event.")
|
| 73 |
|
| 74 |
+
if "both" in low or "and" in low:
|
| 75 |
+
result.relationships.append("You may need to combine probabilities of multiple events occurring together.")
|
| 76 |
|
| 77 |
+
if "or" in low:
|
| 78 |
+
result.relationships.append("You may need to consider multiple favorable cases without double counting.")
|
| 79 |
|
| 80 |
+
scaffold.setup_actions = [
|
| 81 |
+
"Define what counts as a favorable outcome.",
|
| 82 |
+
"Count or describe the total possible outcomes.",
|
| 83 |
+
"Check whether the events are independent or dependent.",
|
| 84 |
+
]
|
| 85 |
+
scaffold.intermediate_steps = [
|
| 86 |
+
"If multiple events occur together, decide whether to multiply or add probabilities.",
|
| 87 |
+
"If the wording says 'at least', consider using the complement.",
|
| 88 |
+
"Check whether order matters.",
|
| 89 |
+
]
|
| 90 |
+
scaffold.first_move = "Start by identifying the total number of outcomes."
|
| 91 |
+
scaffold.next_hint = "Then count how many outcomes match the condition."
|
| 92 |
+
scaffold.common_traps = [
|
| 93 |
+
"Forgetting the total outcomes.",
|
| 94 |
+
"Mixing up 'and' vs 'or'.",
|
| 95 |
+
"Ignoring replacement vs no replacement.",
|
| 96 |
+
]
|
| 97 |
+
scaffold.key_operations = [
|
| 98 |
+
"count the sample space",
|
| 99 |
+
"count favorable cases",
|
| 100 |
+
"choose multiply/add/complement appropriately",
|
| 101 |
+
]
|
| 102 |
+
scaffold.hint_ladder = [
|
| 103 |
+
"What counts as success here?",
|
| 104 |
+
"What is the full sample space?",
|
| 105 |
+
"Do you need multiplication, addition, or the complement rule?",
|
| 106 |
+
]
|
| 107 |
|
| 108 |
+
result.teaching_points = [
|
| 109 |
+
"Probability = favorable / total.",
|
| 110 |
+
"Use multiplication for linked 'and' events when appropriate.",
|
| 111 |
+
"Use the complement when 'at least' is easier to solve indirectly.",
|
| 112 |
+
]
|
| 113 |
+
result.scaffold = scaffold
|
| 114 |
+
result.meta = {
|
| 115 |
+
"intent": "explain_question",
|
| 116 |
+
"bridge_ready": True,
|
| 117 |
+
"hint_style": "step_ready",
|
| 118 |
+
"subtype": subtype,
|
| 119 |
+
}
|
| 120 |
+
return result
|
|
|
|
|
|
|
|
|