S3Q1 · Filter Houses by Electricity Usage¶
⚡ Quick Reference
Function: filter_houses(data: dict, category: str) -> set
Core idea: For each house, compute avg / max / min / spread, then test the condition for the requested category.
def filter_houses(data, category):
result = set()
for house, usage in data.items():
avg = sum(usage) / len(usage)
mn, mx = min(usage), max(usage)
if category == 'high_usage' and avg >= 500: result.add(house)
elif category == 'moderate_usage' and 200 <= avg < 500: result.add(house)
elif category == 'low_consumption_all_months' and mx <= 200: result.add(house)
elif category == 'stable_usage' and mx - mn <= 50: result.add(house)
return result
Key rules:
- high_usage: avg >= 500
- moderate_usage: 200 <= avg < 500
- low_consumption_all_months: every month <= 200, so max <= 200
- stable_usage: max - min <= 50
Problem Statement¶
Problem
Given a dictionary data mapping house names to lists of monthly electricity consumption values (units), return a set of house names matching the given category:
'high_usage'-- average >= 500'moderate_usage'-- average in [200, 500)'low_consumption_all_months'-- every monthly value <= 200'stable_usage'-- max - min <= 50
Similar problem
This question follows the same four-category filter pattern as S3Q1 of 2026 May Set 1 (Workout Data Analytics). The structure, thresholds, and logic differ, but the approach is identical.
Example:
data = {
"House_A": [400, 480, 500],
"House_B": [120, 180, 190],
"House_C": [700, 650, 720],
"House_D": [250, 300, 275, 290],
"House_E": [150, 160, 155]
}
filter_houses(data, 'high_usage')
{'House_C'}
filter_houses(data, 'stable_usage')
{'House_D', 'House_E'}
Understanding the problem¶
Each category maps to a single statistic:
| Statistic | Used by |
|---|---|
avg = sum / len |
high_usage, moderate_usage |
max(usage) |
low_consumption_all_months |
max - min |
stable_usage |
Full trace of all five houses:
| House | Values | Avg | Max | Spread | HU | MU | LCA | SU |
|---|---|---|---|---|---|---|---|---|
| House_A | [400,480,500] | 460 | 500 | 100 | ✅ | |||
| House_B | [120,180,190] | 163 | 190 | 70 | ✅ | |||
| House_C | [700,650,720] | 690 | 720 | 70 | ✅ | |||
| House_D | [250,300,275,290] | 279 | 300 | 50 | ✅ | ✅ | ||
| House_E | [150,160,155] | 155 | 160 | 10 | ✅ | ✅ |
low_consumption_all_months uses max(), not avg()
The condition requires every month to be <= 200. Checking max(usage) <= 200 is sufficient -- if the highest value passes, all values pass. House_A has avg 460 but also max 500 > 200, so it's excluded even though some months are low.
stable_usage: spread = 50 qualifies (<=, not <)
House_D has spread exactly 50, which satisfies <= 50. Watch the boundary -- the condition is inclusive on 50.
Solution approaches¶
def filter_houses(data: dict, category: str) -> set:
result = set()
for house, usage in data.items():
avg = sum(usage) / len(usage)
minimum = min(usage)
maximum = max(usage)
spread = maximum - minimum
if category == 'high_usage':
if avg >= 500:
result.add(house)
elif category == 'moderate_usage':
if 200 <= avg < 500:
result.add(house)
elif category == 'low_consumption_all_months':
if maximum <= 200: # max <= 200 means all values <= 200
result.add(house)
elif category == 'stable_usage':
if spread <= 50:
result.add(house)
return result
def filter_houses(data: dict, category: str) -> set:
conditions = {
'high_usage': lambda u: sum(u)/len(u) >= 500,
'moderate_usage': lambda u: 200 <= sum(u)/len(u) < 500,
'low_consumption_all_months': lambda u: max(u) <= 200,
'stable_usage': lambda u: max(u) - min(u) <= 50,
}
test = conditions[category]
return {house for house, usage in data.items() if test(usage)}
def filter_houses(data: dict, category: str) -> set:
avg = lambda u: sum(u) / len(u)
test = {
'high_usage': lambda u: avg(u) >= 500,
'moderate_usage': lambda u: 200 <= avg(u) < 500,
'low_consumption_all_months': lambda u: max(u) <= 200,
'stable_usage': lambda u: max(u) - min(u) <= 50,
}[category]
return {h for h, u in data.items() if test(u)}
Key takeaways¶
Use max() for "all elements" conditions
Checking max(usage) <= 200 is equivalent to all(x <= 200 for x in usage). If the largest value satisfies the upper bound, every value does. It's more concise and avoids a full iteration.
Dict of lambdas for clean dispatch
Storing each category's rule as a lambda in a dict replaces a long if/elif chain. Look up the right function with conditions[category] and apply it. Adding a new category is just one more dict entry.
Set comprehension for filtering
{house for house, usage in data.items() if test(usage)} expresses the filter in one line that reads almost like the problem statement: "give me all houses where the test holds."