The Ones That Count
An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- easy
- Seniority
- L5
- Asked in
- W. W. Grainger
Problem
You are given activities, a workout tracker's session log, and targets, a list of activity names. Each record in activities holds an activity name and the session's length in minutes. Return the total minutes spent on the activities named in targets.
Not every minute counts. Add up the ones that do.
Example 1
Input:
activities = [{"name":"run","minutes":30},{"name":"read","minutes":45},{"name":"code","minutes":60},{"name":"run","minutes":20}], targets = ["run","code"]Output:
110
Example 2
Input:
activities = [{"name":"swim","minutes":40}], targets = ["run"]Output:
0
Worked solution and explanation
What this really is
Underneath the ledger costume this is a filter-then-sum: keep only the records whose name is one you care about, then add up their minutes. Everyone gets the arithmetic right. What separates people on a warm-up like this is whether you reach for a set. Check membership against the raw targets list and every one of your 10,000 records pays an O(m) scan; the answer is identical but the runtime quietly goes quadratic. The other way to lose points is subtler: forget the filter and sum everything, which passes the tiny example in your head and fails the moment a non-target record slips in.
Break down the requirements
Step 1: Convert targets to a set
List membership checks are O(n) per lookup. set(targets) gives O(1) average-case, which is what keeps filtering 10K activities against 100 targets linear instead of quadratic.
Step 2: Filter and sum in one pass
With the targets in a set, sum the minutes of every activity whose name is in it. A generator expression fed to sum() filters and accumulates in one readable pass, no manual running total to manage.
Step 3: Let the base case fall out
Empty inputs produce 0 naturally: sum() over an empty generator is 0, so no special-case branch is needed. Same story when targets is empty and nothing matches.
The solution
def activity_time_ledger(activities: list[dict], targets: list[str]) -> int:
target_set = set(targets)
return sum(
activity['minutes']
for activity in activities
if activity['name'] in target_set
)Common follow-up questions
- What if some activity records were missing the 'minutes' key? (Tests defensive dict access: activity.get('minutes', 0) versus a bracket lookup that raises on a missing key.)
- How would you return a per-activity breakdown instead of a single total? (Tests pivoting from a scalar accumulator to a dict accumulator keyed by name.)
- What if the target match needed to be case-insensitive? (Tests string normalization: lower-casing both the names and the targets before comparison.)