Level 8 / Project 04 - Filter State Manager¶
Home: README
Learn Your Way¶
| Read | Build | Watch | Test | Review | Visualize | Try |
|---|---|---|---|---|---|---|
| — | This project | — | — | Flashcards | — | — |
Focus¶
- Immutable filter state with
frozen=Truedataclasses - Command pattern for undo/redo state transitions
- Multi-operator filtering (equals, contains, greater-than, in)
- State serialization and search-text filtering
- Page-reset semantics when filters change
Why this project exists¶
Dashboard and search UIs maintain complex filter states: date ranges, multi-select dropdowns,
text queries, sort orders. Users expect to undo a filter change instantly — yet the filter
itself must also apply correctly to data. This project builds a FilterStateManager with
undo/redo, immutable snapshots, and multi-operator filtering — the same state-management
pattern used in every non-trivial React, Vue, or Angular application.
Run (copy/paste)¶
Expected terminal output¶
{
"status": {"current_state": {...}, "undo_depth": 3, "redo_depth": 1},
"filtered_results": [...],
"filtered_count": 2
}
7 passed
Expected artifacts¶
- Console JSON output showing filter state after undo/redo
- Passing tests
- Updated
notes.md
Alter it (required)¶
- Add a
clear_all()method toFilterStatethat returns a blank state while preservingpage_size. - Implement a
max_historyparameter inFilterStateManagerthat caps the undo stack size. - Add a
to_query_string()method that serialises filter state as URL query parameters.
Break it (required)¶
- Call
undo()when the undo stack is empty — does it raiseRuntimeError? - Add a condition, undo, then add a different condition — verify the redo stack was cleared.
- Create two
FilterStateobjects and mutate a list insidevalue— doesfrozen=Trueprotect deep objects?
Fix it (required)¶
- Add deep-copy protection so that list values inside
FilterConditioncannot be mutated externally. - Add a
history_depthlimit that evicts the oldest undo entry when the cap is exceeded. - Add a test proving that
pageresets to 1 whenever a condition is added or removed.
Explain it (teach-back)¶
- Why does
FilterStateusefrozen=Trueand tuples instead of mutable lists? - How does the command pattern (undo/redo stack) differ from event sourcing?
- Why does adding a filter reset the page number to 1?
- What is the difference between shallow and deep immutability, and why does it matter here?
Mastery check¶
You can move on when you can: - explain the command pattern and how undo/redo stacks work, - add a new filter operator end-to-end without breaking existing tests, - describe why immutable state snapshots prevent subtle UI bugs, - implement undo/redo for any state-management scenario from scratch.
Mastery Check¶
- Can you explain the architectural trade-offs in your solution?
- Could you refactor this for a completely different use case?
- Can you identify at least two alternative approaches and explain why you chose yours?
- Could you debug this without print statements, using only breakpoint()?
Related Concepts¶
| ← Prev | Home | Next → |
|---|---|---|