File size: 12,255 Bytes
7a2d839
37e4b67
7a2d839
 
2660a67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5d5985
7a2d839
a5d5985
2660a67
a5d5985
2660a67
82ffe01
2660a67
a5d5985
 
2660a67
a5d5985
 
2660a67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a2d839
 
2660a67
7a2d839
a5d5985
 
2660a67
 
 
 
a5d5985
7a2d839
a5d5985
2660a67
 
 
a5d5985
82ffe01
a5d5985
7a2d839
2660a67
 
 
 
 
5be6cc2
2660a67
5be6cc2
 
2660a67
5be6cc2
 
2660a67
 
 
5be6cc2
 
2660a67
 
 
a5d5985
2660a67
7a2d839
2660a67
a5d5985
2660a67
 
 
a5d5985
 
2660a67
 
 
a5d5985
2660a67
 
a5d5985
2660a67
 
 
 
a5d5985
2660a67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5d5985
2660a67
a5d5985
82ffe01
2660a67
 
 
a5d5985
82ffe01
2660a67
 
 
a5d5985
7a2d839
2660a67
a5d5985
2660a67
 
 
a5d5985
 
2660a67
 
 
a5d5985
2660a67
 
a5d5985
2660a67
a5d5985
82ffe01
2660a67
 
 
82ffe01
 
2660a67
 
 
a5d5985
7a2d839
2660a67
a5d5985
2660a67
 
 
a5d5985
 
2660a67
 
 
 
 
 
 
 
 
a5d5985
82ffe01
2660a67
 
 
82ffe01
 
2660a67
 
 
a5d5985
7a2d839
2660a67
a5d5985
2660a67
 
 
a5d5985
 
2660a67
 
 
a5d5985
2660a67
 
82ffe01
2660a67
 
 
82ffe01
 
2660a67
 
 
a5d5985
7a2d839
2660a67
a5d5985
2660a67
 
 
a5d5985
 
2660a67
 
 
 
 
 
 
 
 
a5d5985
82ffe01
2660a67
 
 
82ffe01
 
2660a67
 
 
a5d5985
7a2d839
a5d5985
 
2660a67
 
 
a5d5985
 
2660a67
 
 
a5d5985
2660a67
 
82ffe01
2660a67
 
 
82ffe01
 
2660a67
 
 
a5d5985
7a2d839
a5d5985
 
 
 
5be6cc2
a5d5985
 
 
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
import re
from .explainer_types import ExplainerResult, ExplainerScaffold


_PERCENT_PATTERNS = [
    r"\bpercent\b",
    r"\bpercentage\b",
    r"\bwhat percent\b",
    r"\bpercent of\b",
    r"\bpercent greater than\b",
    r"\bpercent less than\b",
    r"\bincrease(?:d)? by \d+ ?%\b",
    r"\bdecrease(?:d)? by \d+ ?%\b",
    r"\bdiscount\b",
    r"\bmarkup\b",
    r"\binterest\b",
    r"\btax\b",
    r"\btip\b",
    r"\bprofit margin\b",
    r"\bcommission\b",
    r"\bpart of\b",
    r"\bof a number\b",
]


def _looks_like_percent_question(text: str) -> bool:
    low = (text or "").lower()
    if "%" in low:
        return True
    return any(re.search(p, low) for p in _PERCENT_PATTERNS)


def _infer_percent_subtype(text: str) -> str:
    low = (text or "").lower()

    if any(k in low for k in ["increase", "decrease", "increased", "decreased", "percent change", "changed by"]):
        return "percent_change"
    if any(k in low for k in ["discount", "sale", "off", "markdown"]):
        return "discount"
    if any(k in low for k in ["interest", "simple interest", "compound interest"]):
        return "interest"
    if any(k in low for k in ["tax", "vat", "tip", "gratuity"]):
        return "tax_tip"
    if any(k in low for k in ["what percent", "is what percent of", "as a percent of"]):
        return "percent_of_percent"
    if any(k in low for k in ["percent of", "of a number", "% of"]):
        return "basic_percent"
    return "generic_percent"


def explain_percent_question(text: str):
    if not _looks_like_percent_question(text):
        return None

    subtype = _infer_percent_subtype(text)

    result = ExplainerResult(
        understood=True,
        topic="percent",
        summary="This is a percent problem. The key is to identify which quantity is the base, which is the compared amount, and what role the percent is playing.",
        asks_for="the missing value, the percent itself, or the final changed total",
        plain_english="Percent means per hundred, so the safest route is to identify the base first and then match the wording to the correct percent template.",
    )

    scaffold = ExplainerScaffold(
        concept="Percent problems are built around a base amount, a compared amount, and a rate per hundred.",
        ask="Decide which quantity is the whole/base, which quantity is the part or changed amount, and whether the question is asking for a percent, a value, or a new total.",
        target="Translate the wording into the correct percent relationship before doing any arithmetic.",
        answer_hidden=True,
        solution_path_type=subtype,
    )

    result.teaching_points = [
        "Percent means per hundred, so it should usually be converted to a decimal or fraction before setting up the relationship.",
        "Most percent questions reduce to one of a small number of templates, so identifying the template matters more than rushing into calculation.",
        "The biggest source of error is choosing the wrong base quantity.",
    ]
    result.givens = [
        "A percent, base, part, or changed amount is implied by the wording.",
    ]
    result.relationships = [
        "Percent relationships depend on correctly matching part, whole, and rate.",
    ]
    result.needed_concepts = [
        "base vs part",
        "percent as a decimal or fraction",
        "choosing the correct percent template",
    ]
    result.trap_notes = [
        "Choosing the wrong base quantity.",
        "Using 40 instead of 0.40.",
        "Confusing a basic percent-of problem with a percent-change problem.",
    ]
    result.strategy_hint = "Start by asking: percent of what?"

    if subtype == "basic_percent":
        scaffold.setup_actions = [
            "Label the known quantities as part, whole, and percent.",
            "Convert the percent to a decimal or fraction.",
            "Match the statement to the relationship: part = percent × whole.",
        ]
        scaffold.intermediate_steps = [
            "If the whole is unknown, assign it a variable.",
            "Substitute the known values into the relationship.",
            "Solve only after the structure is correct.",
        ]
        scaffold.first_move = "Start by identifying the whole and the part."
        scaffold.next_hint = "Once those roles are clear, write one equation connecting part, percent, and whole."
        scaffold.variables_to_define = [
            "Let x represent the unknown quantity if either the part or whole is missing.",
        ]
        scaffold.equations_to_form = [
            "part = percent × whole",
        ]
        scaffold.key_operations = [
            "identify the base",
            "convert percent to decimal",
            "build one equation",
        ]
        scaffold.hint_ladder = [
            "Which quantity is the whole?",
            "What is the percent as a decimal?",
            "Can you write part = percent × whole?",
        ]

    elif subtype == "percent_of_percent":
        scaffold.setup_actions = [
            "Identify the comparison being made.",
            "Place the compared quantity over the base quantity.",
            "Convert the resulting fraction to a percent.",
        ]
        scaffold.intermediate_steps = [
            "Make sure the denominator is the reference/base amount.",
            "Simplify the fraction if helpful.",
            "Only convert to percent at the end.",
        ]
        scaffold.first_move = "Ask: percent of what?"
        scaffold.next_hint = "Use the base quantity as the denominator in the fraction before converting."
        scaffold.equations_to_form = [
            "percent = (part / whole) × 100",
        ]
        scaffold.key_operations = [
            "form the fraction",
            "use the base as denominator",
            "convert to percent",
        ]
        scaffold.hint_ladder = [
            "What is the reference amount?",
            "Which number belongs in the denominator?",
            "Multiply by 100 only after the fraction is correct.",
        ]

    elif subtype == "percent_change":
        scaffold.setup_actions = [
            "Identify the original value and the new value.",
            "Find the amount of change first.",
            "Use the original value as the base in the percent-change formula.",
        ]
        scaffold.intermediate_steps = [
            "Compute change = new − original.",
            "Place that change over the original value.",
            "Convert the result to a percent.",
        ]
        scaffold.first_move = "Find the amount of increase or decrease before thinking about the percent."
        scaffold.next_hint = "After that, divide by the original amount, not the new amount."
        scaffold.equations_to_form = [
            "percent change = (new − original) / original × 100",
        ]
        scaffold.key_operations = [
            "find the change",
            "divide by the original",
            "convert to percent",
        ]
        scaffold.hint_ladder = [
            "Which value is original?",
            "What is the amount of change?",
            "Which quantity belongs in the denominator?",
        ]

    elif subtype == "discount":
        scaffold.setup_actions = [
            "Identify the original price and the discount rate.",
            "Find the discount amount from the original price.",
            "Subtract the discount from the original price if the question asks for the sale price.",
        ]
        scaffold.intermediate_steps = [
            "Treat the listed price as the base.",
            "Compute the discount amount separately from the final price.",
            "Check whether the question asks for discount amount or discounted price.",
        ]
        scaffold.first_move = "Use the original price as the percent base."
        scaffold.next_hint = "Find the discount amount first, then decide whether to stop or subtract."
        scaffold.equations_to_form = [
            "discount = rate × original price",
            "sale price = original price − discount",
        ]
        scaffold.key_operations = [
            "identify the original price",
            "find discount amount",
            "subtract if needed",
        ]
        scaffold.hint_ladder = [
            "What is the original price?",
            "What percent of that price is the discount?",
            "Does the question want the discount or the final price?",
        ]

    elif subtype == "interest":
        scaffold.setup_actions = [
            "Identify principal, rate, and time.",
            "Determine whether the question is simple interest or compound interest.",
            "Set up the matching formula structure.",
        ]
        scaffold.intermediate_steps = [
            "For simple interest, keep the principal fixed.",
            "For compound interest, recognize that the base changes from period to period.",
            "Check whether the question asks for interest earned or final amount.",
        ]
        scaffold.first_move = "Work out whether the interest is simple or compound."
        scaffold.next_hint = "Then identify which quantity stays fixed and which quantity grows."
        scaffold.key_operations = [
            "identify principal, rate, and time",
            "match simple vs compound",
            "check whether the target is interest or total amount",
        ]
        scaffold.hint_ladder = [
            "Is the base changing each period?",
            "Which quantity is the principal?",
            "Does the question want interest earned or the total balance?",
        ]

    elif subtype == "tax_tip":
        scaffold.setup_actions = [
            "Identify the pre-tax or pre-tip amount.",
            "Use that original amount as the base.",
            "Compute the tax or tip amount before adding if a total is required.",
        ]
        scaffold.intermediate_steps = [
            "Separate the added charge from the final amount.",
            "Check whether multiple percentages are applied independently or sequentially.",
            "Make sure the question wants the fee amount or the full total.",
        ]
        scaffold.first_move = "Use the original listed amount as the base unless the wording clearly says otherwise."
        scaffold.next_hint = "Find the added percent amount first, then combine only if the question asks for the total."
        scaffold.equations_to_form = [
            "added amount = rate × base amount",
            "total = base amount + added amount",
        ]
        scaffold.key_operations = [
            "identify the original amount",
            "find the added charge",
            "add only if the question asks for the total",
        ]
        scaffold.hint_ladder = [
            "What is the amount before tax or tip?",
            "How much is the added percent of that base?",
            "Does the question stop at the fee or ask for the total bill?",
        ]

    else:
        scaffold.setup_actions = [
            "Identify the base quantity.",
            "Identify the compared quantity or changed amount.",
            "Match the wording to a standard percent relationship.",
        ]
        scaffold.intermediate_steps = [
            "Convert the percent appropriately.",
            "Build one clear relationship before solving.",
            "Check whether the question asks for a value, a rate, or a final amount.",
        ]
        scaffold.first_move = "Work out what the percent is being taken of."
        scaffold.next_hint = "Once the base quantity is clear, write the relationship before calculating."
        scaffold.key_operations = [
            "identify the base",
            "convert the percent",
            "match the correct template",
        ]
        scaffold.hint_ladder = [
            "What quantity is the base?",
            "What role does the percent play here?",
            "Which standard percent relationship matches this wording?",
        ]

    result.scaffold = scaffold
    result.meta = {
        "intent": "explain_question",
        "bridge_ready": True,
        "hint_style": "step_ready",
        "subtype": subtype,
    }
    return result