Practice Workspace¶
Status: Canonical Reference
Scope:src/practice_workspace/- Practice file history management
Related: Package README
Practice Workspace provides stateful management of practice file history and restore operations, enabling users to track their practice attempts over time.
Table of Contents¶
- Overview
- Scope
- Interfaces
- How It Fits in the System
- Typical Workflows
- Key Design Decisions
- File Naming Convention
- Failure Modes and Constraints
- Related Documentation
Overview¶
Practice Workspace is the state management layer for practice files. Unlike codegen (stateless generation), this module:
- Tracks practice file versions over time
- Provides history listing with relative timestamps
- Enables restore to any previous version
Goals¶
| Goal | Description |
|---|---|
| Version Tracking | Save practice files to _history/ directory |
| History Browsing | List versions with timestamps and relative time |
| Easy Restore | Restore specific or latest version |
| Minimal Footprint | Filesystem-only, no external dependencies |
Non-Goals¶
| Non-Goal | Reason |
|---|---|
| β Generate file content | Handled by codegen |
| β Execute tests | Handled by runner/ |
| β Complex version control | Simple timestamp-based backup |
| β Diff/merge functionality | Out of scope |
Scope¶
What this module handles¶
- β
Saving practice files to
_history/directory - β Listing historical versions with timestamps
- β Formatting relative time display ("2 hours ago")
- β Restoring specific or latest version
- β Path utilities for practice files
What this module explicitly avoids¶
- β File content generation (handled by
codegen) - β Test execution (handled by
runner/) - β Network operations (filesystem-only)
- β Problem data fetching (handled by
leetcode_datasource)
Interfaces¶
High-level summary of public APIs. For complete API reference, see Package README.
| Interface | Purpose |
|---|---|
save_to_history() | Save current practice to history |
list_history() | List all history versions (formatted output) |
get_history_entries() | Get history entries as objects |
restore_from_history() | Restore specific version |
restore_latest() | Restore most recent version |
HistoryEntry | History entry data class |
How It Fits in the System¶
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Workflow β
β β
β codegen practice <id> β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β 1. Check if practices/<id>.py exists β β
β β βββ If yes, call practice_workspace.save_to_history β
β β β β
β β 2. Generate new skeleton β β
β β β β
β β 3. Write to practices/<id>.py β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β User commands: practice history / practice restore β
β β β
β βΌ β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β practice_workspace handles listing/restore β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Directory Structure¶
practices/
βββ 0001_two_sum.py # Active practice file
βββ 0003_longest_substring.py # Active practice file
β
βββ _history/ # Version history
βββ 0001_two_sum.py.20251225_200000.bak
βββ 0001_two_sum.py.20251230_091500.bak
βββ 0001_two_sum.py.20251231_143022.bak
βββ 0003_longest_substring.py.20251231_100000.bak
Module Relationships¶
| Module | Relationship |
|---|---|
codegen | Used by - Calls save_to_history() before regenerating |
leetcode_datasource | No direct dependency |
runner | No direct dependency |
Related Packages¶
| Package | Relationship |
|---|---|
codegen | Generates practice skeletons, calls save_to_history() |
leetcode_datasource | No direct dependency |
Dependency Direction¶
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β β
codegen β practice_workspace β
β β practice_workspace β codegen (FORBIDDEN) β
β β practice_workspace β runner (FORBIDDEN) β
β β
β practice_workspace is filesystem-only β
β (stdlib dependencies only) β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Typical Workflows¶
Workflow: Save to History¶
When codegen practice <id> finds an existing practice file:
save_to_history(Path("practices/0001_two_sum.py"))
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Read current practice file content β
β 2. Generate timestamp: 20251231_143022 β
β 3. Create backup filename: 0001_two_sum.py.20251231_143022.bak β
β 4. Write to practices/_history/ β
β 5. Return backup path β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Workflow: List History¶
list_history(problem_id=1)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Find all .bak files for problem 1 in _history/ β
β 2. Parse timestamps from filenames β
β 3. Sort by timestamp (oldest first) β
β 4. Format relative times ("2 hours ago") β
β 5. Print formatted list with index numbers β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Output Example:
Practice history for 0001_two_sum:
[1] 20251225_200000 (6 days ago)
[2] 20251230_091500 (1 day ago)
[3] 20251231_143022 (2 hours ago) β latest
Total: 3 versions
Workflow: Restore Version¶
restore_from_history(problem_id=1, timestamp="20251230_091500")
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Find backup file matching timestamp β
β 2. Read backup content β
β 3. Write to practices/0001_two_sum.py β
β 4. Return success message β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Design Decisions¶
| Decision | Rationale |
|---|---|
| Stateful design | History requires persistent state by nature |
| Filesystem-only | No database needed; simple backup files |
| Timestamp-based naming | Simple, sortable, unique identifiers |
| Oldest-first display | Natural chronological order; latest at bottom |
| No automatic cleanup | User controls when to delete old versions |
| Separate from codegen | Clear responsibility separation |
Design Philosophy¶
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β codegen = stateless β
β practice_workspace = stateful β
β β
β This separation allows: β
β - codegen to focus purely on generation β
β - workspace to manage state independently β
β - Clear boundaries and testability β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
File Naming Convention¶
Backup Filename Format¶
Timestamp Format¶
Examples:
| Original | Timestamp | Backup |
|---|---|---|
0001_two_sum.py | 20251231_143022 | 0001_two_sum.py.20251231_143022.bak |
0003_longest_substring.py | 20251225_200000 | 0003_longest_substring.py.20251225_200000.bak |
Failure Modes and Constraints¶
| Constraint | Behavior |
|---|---|
| Practice file not found | Returns error message |
| No history exists | Returns "No history found" |
| Invalid timestamp | Returns "Version not found" |
_history/ doesn't exist | Creates directory automatically |
| File permission error | Raises standard Python exception |
Related Documentation¶
| Document | Content |
|---|---|
| Package README | Quick reference, API details |
| CodeGen Spec | How codegen integrates with workspace |
| Solution Contract | File format requirements |
Appendix: CLI Commands¶
practice history¶
List practice history versions:
Output:
Practice history for 0001_two_sum:
[1] 20251225_200000 (6 days ago)
[2] 20251230_091500 (1 day ago)
[3] 20251231_143022 (2 hours ago) β latest
Total: 3 versions
practice restore¶
Restore a specific version:
# Interactive mode (default)
practice restore <problem_id>
# Restore latest
practice restore <problem_id> --latest
# Restore specific timestamp
practice restore <problem_id> --at 20251230_091500
Interactive Example: