ooad1-7 Exercise 3: One Trace, Four Levels of Detail ========================================================== ex3.py (needs tracetool.py and library_b.py; run from the chapter folder; it also writes session_depth1.mmd ... session_depth9.mmd next to itself): """Exercise 3: a sequence diagram that is too big. Trace a desk session, then draw it at several levels of detail. Run from the chapter folder: py ex3/ex3.py""" import pathlib import sys from datetime import date HERE = pathlib.Path(__file__).resolve().parent.parent sys.path.insert(0, str(HERE)) import library_b as lib # noqa: E402 from tracetool import to_mermaid, trace # noqa: E402 desk = lib.LoanDesk([lib.Member("M1", date(2027, 1, 1), lib.KINDS["standard"])], [lib.Copy(f"B{i}") for i in range(6)]) def session(): for code in ("B0", "B1", "B2"): desk.borrow("M1", code, date(2026, 10, 10)) return desk.return_book("B0", date(2026, 11, 3)) events, fine, _ = trace("library_b.py", session) print(f"full trace: {len(events)} arrows ({sum(e.kind == 'call' for e in events)} calls)") print("detail kept arrows what a reader sees") for depth, note in ((1, "the desk's four requests only"), (2, "plus what each request asks of the catalogue and member"), (3, "plus the member's own checks and loan lookups"), (9, "everything")): kept = [e for e in events if e.depth <= depth] out = pathlib.Path(__file__).parent / f"session_depth{depth}.mmd" out.write_text(to_mermaid(kept), encoding="utf8") print(f" depth <= {depth} {len(kept):>5} {note}") Run with: py ex3/ex3.py Output: full trace: 73 arrows (41 calls) detail kept arrows what a reader sees depth <= 1 8 the desk's four requests only depth <= 2 32 plus what each request asks of the catalogue and member depth <= 3 45 plus the member's own checks and loan lookups depth <= 9 73 everything session_depth1.mmd, the first level of detail, in full: sequenceDiagram actor Librarian participant LoanDesk Librarian->>LoanDesk: borrow(card, barcode, today) LoanDesk-->>Librarian: Loan Librarian->>LoanDesk: borrow(card, barcode, today) LoanDesk-->>Librarian: Loan Librarian->>LoanDesk: borrow(card, barcode, today) LoanDesk-->>Librarian: Loan Librarian->>LoanDesk: return_book(barcode, today) LoanDesk-->>Librarian: int WHICH LEVEL? Design document: depth 2 (32 arrows). It shows what each request asks of the catalogue and the member, which is the design. Better still, one depth-2 diagram per scenario instead of the whole session: a borrow at depth 2 is 8 arrows (the desk, the catalogue's two lookups and the member's borrow, each with a return). The hand-drawn borrow diagram in the chapter goes one level deeper, to the member's checks and the loan's creation, and leaves out the helper calls beneath those. Overview: depth 1 (8 arrows) is a table of requests in diagram form. It is accurate but says nothing about the design. Never publish: depth 9, everything (73 arrows, over 3,700 pixels tall when rendered). It is useful to a developer debugging a call chain, and it goes out of date with the next refactoring. WHY THIS WORKS AS AN ANSWER --------------------------- The depth is recorded on every event while tracing, so one trace can be drawn at any level without re-running it. The counts show how fast detail grows: each extra level roughly adds the next layer of helper calls. A diagram is useful when it is at the level where the reader's question is answered, and no deeper.