Skip to content

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]
}
Call
filter_houses(data, 'high_usage')
Output
{'House_C'}
Call
filter_houses(data, 'stable_usage')
Output
{'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

01

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.

02

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.

03

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."