Skip to content

S3Q1 · Workout Data Analytics

⚡ Quick Reference

Function: filter_workouts(data: dict, category: str) -> set

Core idea: For each user, compute avg / min / max of their durations, then test the condition for the requested category.

def filter_workouts(data, category):
    result = set()
    for user, durations in data.items():
        avg = sum(durations) / len(durations)
        mn, mx = min(durations), max(durations)
        if   category == 'fitness_enthusiast'  and avg >= 90:       result.add(user)
        elif category == 'regular_user'        and 45 <= avg < 90:  result.add(user)
        elif category == 'consistent_workout'  and mn >= 30:        result.add(user)
        elif category == 'balanced_routine'    and mx - mn <= 20:   result.add(user)
    return result

Key rules: - fitness_enthusiast: avg >= 90 - regular_user: 45 <= avg < 90 (both bounds include/exclude carefully) - consistent_workout: every session >= 30, so min >= 30 - balanced_routine: max - min <= 20


Problem Statement

Problem

Given a dictionary data mapping user names to lists of workout durations (minutes), return a set of user names matching the given category:

  • 'fitness_enthusiast' -- average duration >= 90
  • 'regular_user' -- average duration in [45, 90) -- 45 inclusive, 90 exclusive
  • 'consistent_workout' -- every duration >= 30
  • 'balanced_routine' -- max duration - min duration <= 20

Example:

data = {
    "Aditi":  [100, 95, 90],
    "Bharat": [50, 60, 55],
    "Chetan": [120, 130, 125],
    "Divya":  [35, 40, 45],
    "Esha":   [20, 55, 25]
}
Call
filter_workouts(data, 'fitness_enthusiast')
Output
{'Aditi', 'Chetan'}
Call
filter_workouts(data, 'consistent_workout')
Output
{'Aditi', 'Bharat', 'Chetan', 'Divya'}

Understanding the problem

Each category maps to a different statistic. Compute all three statistics once per user, then check the relevant one:

Statistic Used by
avg = sum / len fitness_enthusiast, regular_user
min(durations) consistent_workout
max - min balanced_routine

Full trace of all five users:

User Durations Avg Min Max-Min FE RU CW BR
Aditi [100,95,90] 95 90 10 ✅ ✅ ✅
Bharat [50,60,55] 55 50 10 ✅ ✅ ✅
Chetan [120,130,125] 125 120 10 ✅ ✅ ✅
Divya [35,40,45] 40 35 10 ✅ ✅
Esha [20,55,25] 33.3 20 35

consistent_workout uses min(), not avg()

The condition is that every session is >= 30. Checking the minimum is sufficient -- if the shortest session passes, all sessions pass. You don't need an all(d >= 30 for d in durations) loop; min(durations) >= 30 is equivalent and O(n) in one pass.

regular_user boundary: 45 inclusive, 90 exclusive

45 <= avg < 90 -- read the problem carefully. A user with exactly avg 90 is a fitness_enthusiast, not a regular_user. Divya (avg 40) falls into neither category.


Solution approaches

def filter_workouts(data: dict, category: str) -> set:
    result = set()
    for user, durations in data.items():
        avg     = sum(durations) / len(durations)
        minimum = min(durations)
        maximum = max(durations)
        spread  = maximum - minimum

        if category == 'fitness_enthusiast':
            if avg >= 90:
                result.add(user)
        elif category == 'regular_user':
            if 45 <= avg < 90:
                result.add(user)
        elif category == 'consistent_workout':
            if minimum >= 30:          # min >= 30 means all values >= 30
                result.add(user)
        elif category == 'balanced_routine':
            if spread <= 20:
                result.add(user)
    return result
def filter_workouts(data: dict, category: str) -> set:
    conditions = {
        'fitness_enthusiast':  lambda d: sum(d) / len(d) >= 90,
        'regular_user':        lambda d: 45 <= sum(d) / len(d) < 90,
        'consistent_workout':  lambda d: min(d) >= 30,
        'balanced_routine':    lambda d: max(d) - min(d) <= 20,
    }
    test = conditions[category]
    return {user for user, durations in data.items() if test(durations)}
def filter_workouts(data: dict, category: str) -> set:
    avg  = lambda d: sum(d) / len(d)
    test = {
        'fitness_enthusiast':  lambda d: avg(d) >= 90,
        'regular_user':        lambda d: 45 <= avg(d) < 90,
        'consistent_workout':  lambda d: min(d) >= 30,
        'balanced_routine':    lambda d: max(d) - min(d) <= 20,
    }[category]
    return {u for u, d in data.items() if test(d)}

Key takeaways

01

Use min() for "every element" conditions

Checking min(durations) >= 30 is equivalent to all(d >= 30 for d in durations) but more concise. The same pattern applies to any "all values above threshold" check.

02

Dict of lambdas for dispatch

Mapping category strings to lambda functions replaces a chain of if/elif blocks. Look up the right function with conditions[category], then apply it -- clean and easy to extend with new categories.

03

Set comprehension for filtering

{user for user, d in data.items() if condition(d)} builds the result set in one expression. It reads as: "give me the users where the condition holds" -- closer to the problem description than an explicit loop.