Katkat

User Activity Analytics: Unique Users per Activity and Average Time on Site

GoogleData Engineer · Technical Screen

Last updated

This question evaluates a candidate's ability to process semi-structured event data using grouping, deduplication, and timestamp arithmetic in Python. It falls under coding and algorithms, commonly asked to assess practical data-wrangling skills such as aggregating per-key counts and computing time-based metrics while handling edge cases like unordered records and single-event users.

User Activity Analytics

You are given a collection of records, where each record captures a single user's action on a website. Each record is a dictionary with the following fields:

  • user_id (int): the id of the user who performed the action.
  • timestamp (str): the moment the action occurred, formatted as 'YYYY-MM-DD HH:MM:SS' (24-hour clock, a single naive local time zone — no offsets).
  • activity (str): a short description of the action, e.g. 'login', 'view', 'purchase', 'logout'.

The input is a Python list of these record dictionaries:

user_activity = [
 {'user_id': 1, 'timestamp': '2024-07-26 10:00:00', 'activity': 'login'},
 {'user_id': 2, 'timestamp': '2024-07-26 10:05:00', 'activity': 'login'},
 {'user_id': 1, 'timestamp': '2024-07-26 10:10:00', 'activity': 'view'},
 {'user_id': 1, 'timestamp': '2024-07-26 10:15:00', 'activity': 'purchase'},
 {'user_id': 2, 'timestamp': '2024-07-26 10:20:00', 'activity': 'view'},
 {'user_id': 3, 'timestamp': '2024-07-26 10:25:00', 'activity': 'login'},
 {'user_id': 1, 'timestamp': '2024-07-26 10:30:00', 'activity': 'logout'},
]

Implement the following two computations.

Task 1 — Unique users per activity

Return a mapping where each key is an activity type and each value is the count of distinct users who performed that activity at least once. If the same user performs the same activity multiple times, that user is counted only once for that activity.

For the example above, Task 1 must return:

{'login': 3, 'view': 2, 'purchase': 1, 'logout': 1}

Task 2 — Average time spent per user (in seconds)

For each user, define time spent on the website as the number of seconds between that user's earliest recorded action and that user's latest recorded action (i.e. last_timestamp - first_timestamp, in seconds). A user with only a single recorded action has a time spent of 0 seconds.

Return the average of these per-user durations across all distinct users, as a number of seconds (a float).

For the example above:

  • User 1: from 10:00:00 to 10:30:00 -> 1800 seconds
  • User 2: from 10:05:00 to 10:20:00 -> 900 seconds
  • User 3: single action -> 0 seconds

Average = (1800 + 900 + 0) / 3 = 900.0 seconds, so Task 2 must return 900.0.

Requirements

  • Parse the timestamp strings yourself; do not assume the records arrive in chronological order.
  • Both computations must run over the same input list.
  • Suggested signatures:
def unique_users_per_activity(user_activity: list[dict]) -> dict:
 ...

def average_time_per_user_seconds(user_activity: list[dict]) -> float:
 ...

Edge cases to handle

  • Records arriving out of timestamp order.
  • A user with exactly one action (duration of 0 seconds, but the user still counts toward Task 1 and toward the Task 2 denominator).
  • The same (user_id, activity) pair appearing multiple times (count the user once for that activity).
  • An empty input list: Task 1 returns an empty mapping {}; Task 2 returns 0.0 (no users to average over — avoid a division-by-zero error).