🧭 Do not search for the first 15 minutes. When stuck: re-read the requirements → define I/O → choose the data structure → trace a small example by hand → write code.
You are given a log of user actions. Each line records that someone did something, and the same person may do the same thing many times.
Implement count_events(events), which counts how many times each user performed
each event. A warm-up problem for getting your hands back on nested dictionaries.
events = [
("alice", "login"),
("bob", "login"),
("alice", "purchase"),
("alice", "login"),
("bob", "logout"),
]
(user, event) pair.(user, event) pair may appear many times.Return a nested dictionary whose outer key is the user, inner key the event, and value the count.
count_events(events)
# {
# "alice": {"login": 2, "purchase": 1},
# "bob": {"login": 1, "logout": 1},
# }
Following the input one line at a time:
("alice", "login"): alice is new. Create her counter and set login to 1.("bob", "login"): bob is new too. Create his counter and set login to 1.("alice", "purchase"): alice's counter already exists. Add purchase as 1.("alice", "login"): alice's login is already 1, so it becomes 2.("bob", "logout"): add logout as 1 to bob's counter.Keys at both levels keep their order of first appearance.
In the example the outer keys are alice then bob. That is because alice appeared first, not because the names were sorted. The same goes for alice's inner keys being login then purchase.
Python dictionaries remember insertion order. Assigning to a key that already exists does not move it to the back. So inserting in the order things appear is all this rule requires.
purchase key at all.("", "") counts the empty-string
event for the empty-string user.Implement count_events(events).
(user, event) pair appears more than once, accumulate it that many times.