Commit
·
30f018f
1
Parent(s):
9434ff2
docs: add CLAUDE.md development guide and schedule.py
Browse filesAdded comprehensive development guide for Claude Code instances and
standalone personal scheduling module with constraint solving.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- CLAUDE.md +91 -0
- schedule.py +70 -0
CLAUDE.md
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# CLAUDE.md
|
2 |
+
|
3 |
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
4 |
+
|
5 |
+
## Project Overview
|
6 |
+
|
7 |
+
This is a constraint satisfaction and scheduling application built with Google OR-Tools and Gradio. The project provides both a web UI and programmatic interfaces for solving task scheduling problems with dependencies and time constraints.
|
8 |
+
|
9 |
+
### Core Architecture
|
10 |
+
|
11 |
+
- **app.py** - Main Gradio web application with constraint solving logic
|
12 |
+
- **schedule.py** - Standalone scheduling solver for personal activities
|
13 |
+
- **test_app.py** - Test suite for the application logic
|
14 |
+
|
15 |
+
The application uses:
|
16 |
+
- Google OR-Tools CP-SAT solver for constraint satisfaction problems
|
17 |
+
- Gradio for the web interface
|
18 |
+
- Mermaid diagrams for schedule visualization
|
19 |
+
- UV for dependency management and Python execution
|
20 |
+
|
21 |
+
## Development Commands
|
22 |
+
|
23 |
+
### Environment Setup
|
24 |
+
```bash
|
25 |
+
uv sync # Install/sync dependencies
|
26 |
+
```
|
27 |
+
|
28 |
+
### Running the Application
|
29 |
+
```bash
|
30 |
+
uv run python app.py # Start Gradio web interface (serves on http://localhost:7860)
|
31 |
+
uv run python schedule.py # Run standalone personal scheduler
|
32 |
+
```
|
33 |
+
|
34 |
+
### Testing
|
35 |
+
```bash
|
36 |
+
uv run pytest # Run all tests
|
37 |
+
uv run pytest test_app.py -v # Run specific test file with verbose output
|
38 |
+
```
|
39 |
+
Note: Some tests are currently failing due to task name normalization changes
|
40 |
+
|
41 |
+
### Code Quality
|
42 |
+
```bash
|
43 |
+
uv run ruff check app.py # Lint specific file
|
44 |
+
uv run ruff format app.py # Format specific file
|
45 |
+
uv run ruff check . # Lint entire project
|
46 |
+
uv run ruff format . # Format entire project
|
47 |
+
```
|
48 |
+
|
49 |
+
### Adding Dependencies
|
50 |
+
```bash
|
51 |
+
uv add <package> # Add new dependency to pyproject.toml
|
52 |
+
```
|
53 |
+
|
54 |
+
## Key Functions and Logic
|
55 |
+
|
56 |
+
### Task Parsing and Normalization
|
57 |
+
- `normalize_task_name()` - Converts task names to lowercase with underscores for internal processing
|
58 |
+
- `parse_requirements()` - Parses dependency strings like "TaskA requires TaskB" into dependency graphs
|
59 |
+
- `parse_tasks()` - Extracts task lists from comma/newline separated text
|
60 |
+
|
61 |
+
### Constraint Solving
|
62 |
+
- `solve_all_tasks()` - Main CP-SAT solver that schedules all tasks respecting dependencies
|
63 |
+
- Uses Google OR-Tools constraint programming to find valid task orderings
|
64 |
+
- Returns ordered task lists or indicates if no solution exists (cyclic dependencies)
|
65 |
+
|
66 |
+
### Visualization
|
67 |
+
- `generate_mermaid_gantt()` - Creates Mermaid Gantt charts from task schedules
|
68 |
+
- Supports both simple ordering and time-based scheduling with durations
|
69 |
+
|
70 |
+
### Gradio Interface
|
71 |
+
The web UI provides text areas for:
|
72 |
+
- Task list input (comma or newline separated)
|
73 |
+
- Requirements/dependencies input
|
74 |
+
- Interactive solving and visualization
|
75 |
+
|
76 |
+
## Code Conventions
|
77 |
+
|
78 |
+
- Uses snake_case for functions and variables
|
79 |
+
- Type hints encouraged for public APIs
|
80 |
+
- Ruff for linting/formatting (PEP8 style)
|
81 |
+
- 4-space indentation, 120-character line limit
|
82 |
+
- Comprehensive docstrings for public functions
|
83 |
+
|
84 |
+
## Development Notes
|
85 |
+
|
86 |
+
- The project uses UV instead of pip/venv for faster dependency management
|
87 |
+
- Tests exist but some are failing due to recent changes in task name handling
|
88 |
+
- The application can handle cyclic dependency detection
|
89 |
+
- Both programmatic (schedule.py) and interactive (app.py) interfaces available
|
90 |
+
- Mermaid diagram generation supports time-based and simple orderings
|
91 |
+
- try to keep all features accessible from gradio
|
schedule.py
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ortools.sat.python import cp_model
|
2 |
+
|
3 |
+
def main():
|
4 |
+
model = cp_model.CpModel()
|
5 |
+
horizon = 48 # 24-hour day in 30-minute slots (adjust as needed)
|
6 |
+
|
7 |
+
# Activities and durations (in 30-min increments)
|
8 |
+
activities = {
|
9 |
+
'breakfast': 2, # 1 hour (prep + eat + cleanup)
|
10 |
+
'lunch': 2,
|
11 |
+
'dinner': 2,
|
12 |
+
'nap': 4, # 2-hour nap
|
13 |
+
'laundry': 4, # 2 hours
|
14 |
+
'wifes_parents': 6, # 3-hour visit
|
15 |
+
'mom': 6, # Friday night (fixed)
|
16 |
+
'personal_time': 4, # 2 hours total
|
17 |
+
'kids_duty': 1, # Rotating 30-min shifts
|
18 |
+
}
|
19 |
+
|
20 |
+
# --- Time Windows ---
|
21 |
+
# All times are in 30-min slots from 0 (8:00 AM) to 48 (next day 8:00 AM)
|
22 |
+
time_windows = {
|
23 |
+
'mom': (36, 42), # Friday 6:00 PM–9:00 PM (if Friday is day 0)
|
24 |
+
'nap': (12, 18), # Preferred nap window: 1:00 PM–4:00 PM
|
25 |
+
'laundry': (20, 36), # Flexible but avoid late-night
|
26 |
+
}
|
27 |
+
|
28 |
+
# --- Variables ---
|
29 |
+
starts = {act: model.NewIntVar(0, horizon, f'start_{act}') for act in activities}
|
30 |
+
ends = {act: model.NewIntVar(0, horizon, f'end_{act}') for act in activities}
|
31 |
+
|
32 |
+
# Duration constraints
|
33 |
+
for act, duration in activities.items():
|
34 |
+
model.Add(ends[act] == starts[act] + duration)
|
35 |
+
|
36 |
+
# --- Fixed Time Constraints ---
|
37 |
+
model.Add(starts['mom'] == time_windows['mom'][0]) # Fixed Friday night
|
38 |
+
|
39 |
+
# --- Meal Spacing (4-hour gaps) ---
|
40 |
+
model.Add(starts['lunch'] >= starts['breakfast'] + 8) # 8 slots = 4 hours
|
41 |
+
model.Add(starts['dinner'] >= starts['lunch'] + 8)
|
42 |
+
|
43 |
+
# --- Nap After Lunch ---
|
44 |
+
model.Add(starts['nap'] >= starts['lunch'] + 2) # At least 1 hour after lunch
|
45 |
+
|
46 |
+
# --- Laundry During Kid-Free Time ---
|
47 |
+
model.Add(starts['laundry'] >= 20) # Not before 10 AM
|
48 |
+
|
49 |
+
# --- Personal Time (flexible, but prioritize) ---
|
50 |
+
model.AddMaxEquality(ends['personal_time'], [horizon])
|
51 |
+
|
52 |
+
# --- Kids’ Duty Constraints ---
|
53 |
+
# Simplified: Alternate shifts (for realism, expand to check overlaps)
|
54 |
+
for act in ['wifes_parents', 'mom', 'personal_time']:
|
55 |
+
model.AddNoOverlap([starts[act], ends[act], starts['kids_duty'], ends['kids_duty']])
|
56 |
+
|
57 |
+
# --- Solve ---
|
58 |
+
solver = cp_model.CpSolver()
|
59 |
+
status = solver.Solve(model)
|
60 |
+
|
61 |
+
# --- Print Schedule ---
|
62 |
+
if status == cp_model.OPTIMAL:
|
63 |
+
for act in activities:
|
64 |
+
start = solver.Value(starts[act])
|
65 |
+
print(f"{act}: {start//2}:{30*(start%2):02}–{(start+activities[act])//2}:{30*((start+activities[act])%2):02}")
|
66 |
+
else:
|
67 |
+
print("No feasible schedule found.")
|
68 |
+
|
69 |
+
if __name__ == '__main__':
|
70 |
+
main()
|