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
A workout tracker logs each session as a record carrying the activity name and its duration in minutes. Given the full log and a short list of activity names you actually care about, return the total minutes spent on just those activities.
Not every minute counts. Add up the ones that do.
Example 1
Input:
targets = ["run","code"], activities = [{"name":"run","minutes":30},{"name":"read","minutes":45},{"name":"code","minutes":60},{"name":"run","minutes":20}]Output:
110
Example 2
Input:
targets = ["run"], activities = [{"name":"swim","minutes":40}]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.)