Statecharts · Problem 2
P2 · The Media Player
Shallow history against deep history, in the same chart, so the difference is something you observe rather than something you are told. Eleven tests.
The system
A media player. It can be empty or loaded; loaded means playing or paused; playing means normal speed or fast-forward. Separately — and the word is doing work — the output is on or muted, with a volume.
A phone call interrupts playback. When the call ends the player goes back to what it was doing. Which is the interesting requirement, because “what it was doing” has two reasonable readings, and this problem makes you implement both so you can see the difference rather than read about it.
Step 1 — draw it
playing with no media loaded is not a thing. playing and paused are children of loaded, which is a sibling of empty. Two facts that look independent, where one only exists inside a value of the other.loaded: one shallow, one deep. They are pseudo-states inside the compound, and two different events target them. That is the only way to make the difference observable in the same chart.loaded itself, not a history state. Loading a new file should start at the beginning even if the last one was paused. One compound, two kinds of entrance — which is exactly why Harel put history on the arrowhead rather than on the box.Step 2 — build it
exercises/p2_media_player/machine.py —
the skeleton. Its docstring is the contract: exact state ids, event names, and context attributes.exercises/p2_media_player/test_machine.py —
11 acceptance tests. Do not edit them.exercises/p2_media_player/_solution.py —
a reference solution with commentary. Open it after yours is green, not before.cd statecharts/exercises/p2_media_player pytest -q
When it is green
Two tests are worth rereading:
test_shallow_history_forgets_the_leaf and
test_deep_history_remembers_the_leaf differ by one character in the event name and land in
different states. And test_mute_survives_an_eject passes without you doing anything for it
— the audio region simply was not in the domain of the transition. That is orthogonality paying
out: the behaviour you did not have to write is the point.
Sources: Harel 1987 §2.4 · statecharts.dev · RESOURCES.md