barakplasma Claude commited on
Commit
30f018f
·
1 Parent(s): 9434ff2

docs: add CLAUDE.md development guide and schedule.py

Browse files

Added 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>

Files changed (2) hide show
  1. CLAUDE.md +91 -0
  2. 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()