Skip to content

Repository files navigation

Smart Timetable Builder

Python Version Streamlit OR-Tools License Status

An intelligent, animated school timetable generator

Powered by constraint programming • Built with love for educators

Smooth • Stable • Alive

Quick Start FeaturesDocumentation Demo

Separator


Overview

Smart Timetable Builder is a next-generation scheduling solution that transforms the complex task of school timetable creation into an elegant, visual experience. Combining Google's OR-Tools constraint solver with a beautifully animated dark-themed interface, it generates mathematically guaranteed clash-free schedules while providing real-time analytics, scenario simulation, and stunning visualizations.

Why Smart Timetable Builder?

Intelligent

Constraint programming ensures zero conflicts. No manual checking needed.

Beautiful

Fluid animations, glowing transitions, and a modern dark theme.

Analytical

Visual heatmaps and energy fields reveal insights at a glance.

Key Highlights

  • Zero Conflicts Guaranteed - Mathematical proof via constraint programming
  • 5 What-If Scenarios - Test disruptions without touching base timetable
  • 4 Visual Analytics - Heatmaps for load, fatigue, congestion, clashes
  • 4 Energy Maps - Animated Plotly fields with glowing orbs and wave motion
  • Auto-Save Everything - 8 JSON files persist all data across sessions
  • Chrome-Style History - Full audit trail with timestamps
  • Demo Data Included - 12 teachers, 6 classes, 164 periods ready to go
  • Professional PDFs - Print-ready A4 exports for classes and teachers

Features

Core Scheduling Engine

Clash-Free Generation No teacher or class double-booking (hard constraint)
Priority Scheduling Important subjects scheduled earlier in the day (optional)
Teacher Constraints Respect max periods per day + max periods per week
Break Periods Configurable breaks (e.g., "4, Lunch Break" or "7, Tea Break")
Weekly Rotation 3-week automatic rotation for fairness
OR-Tools Solver Google's constraint programming solver (CP-SAT)

What-If Lab (5 Scenarios)

Simulate disruptions without modifying the base timetable:

Scenario Description Use Case
Teacher Absent Mark teacher unavailable, auto-substitute or free period Sick leave, training
Substitute Teacher Assign replacement teacher for specific classes Planned absence
Lab Unavailable Mark lab subjects (Physics, Chemistry, Biology) as free Maintenance, exams
Shortened Day Reduce max periods for the day Half-day schedule
Emergency Free Force specific class/period to be free Assembly, event

Visual Analytics

Heatmaps (4 Types)

┌─────────────────────────────────────────────────────────────┐
│   Teacher Load       │  Periods per teacher per day       │
│   Day Congestion     │  Total teaching periods per day    │
│   Class Fatigue      │  Heavy subject clustering          │
│    Clash Risk        │  Overload and conflict detection   │
└─────────────────────────────────────────────────────────────┘

Energy Maps (4 Types - Animated with Plotly)

┌─────────────────────────────────────────────────────────────┐
│   Teacher Load       │  Glowing orbs sized by workload    │
│   Fatigue Flow       │  Ripple effects show heavy clusters│
│   Congestion         │  Pulsing gradients per day         │
│   Impact Diffusion   │  Wave propagation from changes     │
└─────────────────────────────────────────────────────────────┘

Controls: Animation Speed • Glow Intensity • Motion Toggle

Auto-Persistence (8 JSON Files)

All data automatically saves to data/ directory:

data/
├── teachers.json          # Teacher definitions
├── classes.json           # Class and subject assignments  
├── priority_configs.json  # Priority settings per class
├── config.json            # School configuration
├── history.json           # Activity log (last 500 entries)
├── demo_loaded.json       # Demo data flag
├── base_timetable.json    # Generated timetable
└── scenario_state.json    # What-If Lab scenarios

User Experience

Smooth Animations

  • Fade-in transitions (0.3-0.4s)
  • Glow effects on changes
  • Pulsing notifications
  • Interpolated heatmaps

Intuitive Interface

  • 10-tab navigation
  • Expandable forms
  • In-place editing
  • Stackable toasts

Dark Theme

Modern, eye-friendly design:

  • Background: #0f0f0f
  • Containers: #18181b
  • Borders: #27272a
  • Text: #fafafa / #e4e4e7 / #a1a1aa

Quick Start

Prerequisites

Python 3.8 or higher
pip package manager
4GB RAM recommended

Installation

# Clone the repository
git clone https://github.com/yourusername/smart-timetable-builder.git
cd smart-timetable-builder

# Install dependencies
pip install -r requirements.txt

Run Application

streamlit run app.py

Application opens at: http://localhost:8501

First Steps (3 Minutes)

1. Load Demo

Click "Load Demo Data" in sidebar

12 teachers + 6 classes ready to use

2. Generate

Navigate to "Class Timetables" tab

Click "Generate Timetable"

Solver runs ~2-5 seconds

3. Explore

View results, try scenarios, check analytics

All features now unlocked!


Demo Data

Teachers (12 Total)

Stream Teacher Subjects Max/Day
Science Eric Simon Physics 5
Aisha Khan Chemistry 5
Rahul Mehta Mathematics 5
Neha Verma Biology 5
Commerce Priya Nair Economics 5
Arjun Patel Accountancy 5
Kavita Rao Business Studies 4
Humanities Sofia Mendes History 5
Aman Gupta Political Science 5
Ritu Chawla Geography 4
Common Daniel Brooks English (all streams) 4
Marcus Lee Physical Education (all) 3

Classes (6 Total)

┌─────────┬────────────────────────────────────────────────┬────────┐
│ Class   │ Subjects (periods/week)                        │ Total  │
├─────────┼────────────────────────────────────────────────┼────────┤
│ 11SCI   │ Physics(6) • Chemistry(6) • Math(6)           │   30   │
│         │ Biology(6) • English(4) • PE(2)                │        │
├─────────┼────────────────────────────────────────────────┼────────┤
│ 12SCI   │ Physics(6) • Chemistry(6) • Math(6)           │   30   │
│         │ Biology(6) • English(4) • PE(2)                │        │
├─────────┼────────────────────────────────────────────────┼────────┤
│ 11COM   │ Accountancy(6) • Business(6) • Economics(6)   │   28   │
│         │ Math(4) • English(4) • PE(2)                   │        │
├─────────┼────────────────────────────────────────────────┼────────┤
│ 12COM   │ Accountancy(6) • Business(6) • Economics(6)   │   28   │
│         │ Math(4) • English(4) • PE(2)                   │        │
├─────────┼────────────────────────────────────────────────┼────────┤
│ 11HUM   │ History(6) • PolSci(6) • Geography(6)         │   24   │
│         │ English(4) • PE(2)                             │        │
├─────────┼────────────────────────────────────────────────┼────────┤
│ 12HUM   │ History(6) • PolSci(6) • Geography(6)         │   24   │
│         │ English(4) • PE(2)                             │        │
└─────────┴────────────────────────────────────────────────┴────────┘

Total: 164 periods/week across 6 classes

Documentation

10-Tab Interface

┌────────────────────────────────────────────────────────────────────┐
│  Teachers &   Saved   History   Class     Teacher      │
│    Classes      Data                 Timetables   Timetables       │
│                                                                     │
│  Rotation   What-If   Insights   Energy   PDF           │
│               Lab                     Maps      Export            │
└────────────────────────────────────────────────────────────────────┘

Complete User Guide

1. Configure School (Sidebar)

Days: Mon,Tue,Wed,Thu,Fri
Periods per day: 8

Break Periods:
  4, Lunch Break
  7, Tea Break

Click "Apply Config" to save.

2. Add Teachers

Navigate to "Teachers & Classes" tab:

┌─────────────────────────────────────┐
│ Teacher ID: Eric Simon              │
│ Subjects: Physics                   │
│ Sections: 11SCI, 12SCI              │
│ Max Periods/Day: 5                  │
│                                     │
│        [Save]   [Cancel]            │
└─────────────────────────────────────┘

Result: Toast notification " Teacher Eric Simon added"

3. Add Classes

Scroll to "2. Add Classes" section:

┌─────────────────────────────────────┐
│ Class ID: 11SCI                     │
│                                     │
│ Add Subjects:                       │
│ • Physics: 6 periods → Eric Simon   │
│ • Chemistry: 6 periods → Aisha Khan │
│ • Math: 6 periods → Rahul Mehta     │
│ ...                                 │
│                                     │
│        [Save]   [Cancel]            │
└─────────────────────────────────────┘

4. Priority Settings (Optional)

Expand each class to configure:

Priorities for 11SCI:
┌─────────────────────────────────────┐
│ Priority (early) subjects:          │
│ Physics, Chemistry, Mathematics     │
│                                     │
│ Weak subjects:                      │
│ Physics, Chemistry                  │
│                                     │
│ Heavy subjects:                     │
│ Physics, Chemistry, Math, Biology   │
│                                     │
│        [Save]                       │
└─────────────────────────────────────┘

5. Generate Timetable

Navigate to " Class Timetables" tab:

  1. Click " Generate Timetable"
  2. Spinner appears: "Solving..."
  3. Toast: " Timetable generated!"
  4. View results in tables below

6. What-If Scenarios

Navigate to " What-If Lab" tab:

Day: [Monday ▼]

Scenarios:
☑ Teacher absent today
  └─ Absent teacher: [Eric Simon ▼]

☑ Shortened school day  
  └─ Max periods today: [6]

Live timetable updates below ↓

7. Visual Analytics

Heatmaps ( Insights tab):

Heatmap: [Teacher load ▼]

Displays: Styled dataframe with color gradients
- Green → Yellow → Orange → Red
- Darker = Higher load

Energy Maps ( Energy Maps tab):

Energy Map Type: [Teacher Load Energy Field ▼]
Animation Speed: ————●———— 0.5
Glow Intensity:  ————●———— 1.0
Motion: ☑

Displays: Animated Plotly chart with:
- Glowing orbs (teacher workload)
- Smooth gradients
- Wave motion effects

8. Export PDFs

Navigate to " PDF Export" tab:

┌──────────────────────────────────┐
│   Download Class PDFs          │
│   Download Teacher PDFs        │
└──────────────────────────────────┘

Format: A4, print-ready

Technical Architecture

Data Models (models.py)

@dataclass
class Teacher:
    teacher_id: str                    # Unique ID (e.g., "Eric Simon")
    subjects: List[str]                # ["Physics"]
    sections: List[str]                # ["11SCI", "12SCI"]
    max_periods_per_day: int = 6       # Daily limit

@dataclass
class ClassSubject:
    subject: str                       # "Physics"
    weekly_periods: int                # 6
    teacher_id: str                    # "Eric Simon"

@dataclass
class Class:
    class_id: str                      # "11SCI"
    subjects: List[ClassSubject]       # List of subjects

@dataclass
class SchoolConfig:
    days: List[str] = ["Mon", "Tue", "Wed", "Thu", "Fri"]
    periods_per_day: int = 8
    break_periods: Dict[int, str] = {}  # {3: "Lunch", 6: "Tea"}

@dataclass
class ClassPriorityConfig:
    class_id: str
    priority_subjects: List[str] = []  # Early scheduling
    weak_subjects: List[str] = []      # Morning only
    heavy_subjects: List[str] = []     # Avoid consecutive

Application Flow

┌─────────────────────────────────────────────────────────────┐
│  1. Session State Init (_init_session)                      │
│     └─ Load from JSON (all 8 files)                         │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  2. Render UI (10 tabs)                                     │
│     └─ Streamlit components + custom CSS                    │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  3. User Actions (add/edit/delete/generate)                 │
│     └─ Form submissions, button clicks                      │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  4. Business Logic                                          │
│     ├─ Solver (OR-Tools CP-SAT)                            │
│     ├─ Scenarios (overlay, no mutation)                    │
│     └─ Analytics (heatmaps, energy maps)                   │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  5. Auto-Save (storage.py → JSON)                          │
│     └─ Persist to data/ directory                          │
└──────────────────────┬──────────────────────────────────────┘
                       │
┌──────────────────────▼──────────────────────────────────────┐
│  6. Update UI + Show Toast Notification                     │
│     └─ Fragment reruns, smooth animations                   │
└─────────────────────────────────────────────────────────────┘

Constraint Solver (solver.py)

# Hard Constraints (MUST be satisfied)No teacher conflicts     # Teacher can't be in 2 placesNo class conflicts       # Class can't have 2 subjectsAll periods satisfied    # Sum matches weekly_periodsTeacher max per day      # Respect daily limitTeacher max per week     # Respect weekly limit

# Soft Constraints (Optimization - if priority configs exist)Priority subjects early  # Morning schedulingWeak subjects morning    # When students freshHeavy not consecutive    # Avoid back-to-back

Solver Performance:

  • Small (6 classes): ~2 seconds
  • Medium (20 classes): ~5-10 seconds
  • Large (50+ classes): ~20-60 seconds

Storage Layer (storage.py)

# Core Functions
load_teachers() → List[Teacher]
save_teachers(teachers: List[Teacher])

load_classes() → List[Class]
save_classes(classes: List[Class])

load_config() → SchoolConfig
save_config(config: SchoolConfig)

load_priority_configs() → List[ClassPriorityConfig]
save_priority_configs(configs)

# History & State
append_history(action, target, summary, details)
load_history() → List[dict]  # Last 500 entries

load_scenario_state() → dict
save_scenario_state(state: dict)

load_base_timetable() → Optional[dict]
save_base_timetable(serialized: dict)

# Utility
is_demo_loaded() → bool
set_demo_loaded()
clear_demo_loaded()
clear_base_timetable()
clear_scenario_state()

UI Design

Dark Theme

/* Color Palette */
--bg-primary: #0f0f0f
--bg-secondary: #18181b
--border: #27272a
--text-primary: #fafafa
--text-secondary: #e4e4e7
--text-muted: #a1a1aa

/* Gradients */
--sidebar: linear-gradient(180deg, #18181b 0%, #0f0f0f 100%)

✨ Animations

/* Fade In */
@keyframes cardFadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Glow (Changed Cells) */
@keyframes glow {
  0% { box-shadow: 0 0 8px 2px #ffd700; }
  100% { box-shadow: 0 0 16px 6px #ffec99; }
}

/* Toast Slide */
@keyframes toastFadeIn {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}

📲 Notifications

Stackable toast notifications with live countdown:

show_toast("Timetable generated!", duration_sec=3)

Display:

┌─────────────────────────────────┐
│  Timetable generated!     3s │
│  Teacher added            2s │
│  PDF exported             1s │
└─────────────────────────────────┘

Fragment reruns every 1 second via @st.fragment(run_every=timedelta(seconds=1))


Example Output

Class Timetable

Class 11SCI
┌───────────┬──────────┬──────────┬──────────┬────────────┬──────────┬──────────┬──────────┬──────────┐
│ Day       │ P1       │ P2       │ P3       │ P4 (Lunch) │ P5       │ P6       │ P7 (Tea) │ P8       │
│           │ 08:00    │ 08:45    │ 09:30    │ 10:15      │ 11:00    │ 11:45    │ 12:30    │ 13:15    │
├───────────┼──────────┼──────────┼──────────┼────────────┼──────────┼──────────┼──────────┼──────────┤
│ Monday    │ Physics  │ Chemistry│ Math     │ BREAK      │ Biology  │ English  │ BREAK    │ Free     │
├───────────┼──────────┼──────────┼──────────┼────────────┼──────────┼──────────┼──────────┼──────────┤
│ Tuesday   │ Chemistry│ Math     │ Biology  │ BREAK      │ Physics  │ English  │ BREAK    │ PE       │
├───────────┼──────────┼──────────┼──────────┼────────────┼──────────┼──────────┼──────────┼──────────┤
│ Wednesday │ Math     │ Physics  │ Chemistry│ BREAK      │ English  │ Biology  │ BREAK    │ Free     │
├───────────┼──────────┼──────────┼──────────┼────────────┼──────────┼──────────┼──────────┼──────────┤
│ Thursday  │ Biology  │ Chemistry│ Physics  │ BREAK      │ Math     │ PE       │ BREAK    │ Free     │
├───────────┼──────────┼──────────┼──────────┼────────────┼──────────┼──────────┼──────────┼──────────┤
│ Friday    │ English  │ Math     │ Chemistry│ BREAK      │ Physics  │ Biology  │ BREAK    │ Free     │
└───────────┴──────────┴──────────┴──────────┴────────────┴──────────┴──────────┴──────────┴──────────┘

Teacher Timetable

Teacher: Eric Simon (Physics) - Max 5 periods/day
┌───────────┬─────────┬─────────┬─────────┬────────────┬─────────┬─────────┬──────────┬─────────┐
│ Day       │ P1      │ P2      │ P3      │ P4 (Lunch) │ P5      │ P6      │ P7 (Tea) │ P8      │
├───────────┼─────────┼─────────┼─────────┼────────────┼─────────┼─────────┼──────────┼─────────┤
│ Monday    │ 11SCI   │ Free    │ 12SCI   │ BREAK      │ Free    │ Free    │ BREAK    │ Free    │
├───────────┼─────────┼─────────┼─────────┼────────────┼─────────┼─────────┼──────────┼─────────┤
│ Tuesday   │ Free    │ 12SCI   │ Free    │ BREAK      │ 11SCI   │ Free    │ BREAK    │ Free    │
├───────────┼─────────┼─────────┼─────────┼────────────┼─────────┼─────────┼──────────┼─────────┤
│ Wednesday │ Free    │ 11SCI   │ Free    │ BREAK      │ Free    │ 12SCI   │ BREAK    │ Free    │
├───────────┼─────────┼─────────┼─────────┼────────────┼─────────┼─────────┼──────────┼─────────┤
│ Thursday  │ Free    │ Free    │ 11SCI   │ BREAK      │ Free    │ Free    │ BREAK    │ Free    │
├───────────┼─────────┼─────────┼─────────┼────────────┼─────────┼─────────┼──────────┼─────────┤
│ Friday    │ Free    │ Free    │ Free    │ BREAK      │ 12SCI   │ Free    │ BREAK    │ Free    │
└───────────┴─────────┴─────────┴─────────┴────────────┴─────────┴─────────┴──────────┴─────────┘

Summary:
• Total periods: 10/40 (25%)
• Periods per day: 2.0 average
• Max daily: 2 periods
• Free periods: 30

Advanced Features

History Log

Chrome-style activity tracking (last 500 entries):

┌────────────────────────────────────────────────────────────┐
│  2024-02-15 14:30 — Generated clash-free timetable      │
│    Action: generate | Target: Timetable                   │
├────────────────────────────────────────────────────────────┤
│  2024-02-15 14:25 — Exported class timetables PDF       │
│    Action: export | Target: PDF                           │
├────────────────────────────────────────────────────────────┤
│  2024-02-15 14:20 — Updated teacher Eric Simon          │
│    Action: edit | Target: Teacher Eric Simon              │
├────────────────────────────────────────────────────────────┤
│  2024-02-15 14:15 — Added class 11SCI                   │
│    Action: add | Target: Class 11SCI                      │
└────────────────────────────────────────────────────────────┘

🔄 Weekly Rotation

Automatic 3-week rotation system:

Week 1: Original schedule
Week 2: All subjects shifted +1 period (with wraparound)
Week 3: All subjects shifted +2 periods (with wraparound)

Result: Same subject doesn't always fall at same time of day
Benefits: Fairer for students, accounts for energy variations

Scenario Persistence

What-If scenarios auto-save:

{
  "selected_day": 0,
  "scenarios": {
    "teacher_absent": {
      "active": true,
      "teacher_id": "Eric Simon"
    },
    "shortened_day": {
      "active": true,
      "max_periods": 6
    },
    "substitute": {
      "active": false
    }
  }
}

Base timetable never modified - scenarios create live overlay view.


Troubleshooting

Common Issues

Q: "No solution found" error when generating

Possible Causes:

  1. Too many periods required vs. available slots
  2. Teacher max_periods_per_day too restrictive
  3. Conflicting teacher-subject assignments

Solutions:

# Check math:
total_required = sum(subject.weekly_periods for class in classes 
                     for subject in class.subjects)
available_slots = periods_per_day × days_per_week
# Must satisfy: total_required ≤ available_slots × num_classes

# Check teacher capacity:
teacher_capacity = sum(teacher.max_periods_per_day × days_per_week 
                      for teacher in teachers)
# Must satisfy: total_required ≤ teacher_capacity

Quick Fix:

  • Reduce subject weekly_periods
  • Increase teacher max_periods_per_day
  • Add more teachers
Q: Data disappeared after browser refresh

Answer: Check data/ folder exists and has write permissions.

Verify:

ls -la data/
# Should show 8 JSON files

If missing: Click "Load Demo Data" to restore sample data.

Q: Timetable won't generate (button does nothing)

Verify Prerequisites:

  • ✓ At least 1 teacher exists
  • ✓ At least 1 class exists
  • ✓ Days and periods configured (sidebar)
  • ✓ Teachers can teach assigned subjects

Check Console: Press F12 → Console tab → Look for errors

Q: Energy maps not animating

Solutions:

  1. Toggle "Motion" switch ON in Energy Maps tab
  2. Use modern browser (Chrome 90+, Firefox 88+, Safari 14+)
  3. Disable browser extensions that block JavaScript
  4. Check browser console for errors
Q: PDF download shows blank pages

Solutions:

  1. Regenerate timetable first
  2. Try different PDF viewer (Adobe Reader, Chrome, Firefox)
  3. Check if timetable has data:
    # In Class Timetables tab, verify table shows data
  4. Update ReportLab: pip install --upgrade reportlab

📚 Dependencies

# Core Framework
streamlit>=1.28.0          # Web UI framework
ortools>=9.5.0             # Constraint programming solver

# Data Processing
pandas>=1.5.0              # DataFrames and tables
numpy>=1.23.0              # Numerical operations

# Visualization
plotly>=5.14.0             # Interactive charts (energy maps)
matplotlib>=3.7.0          # Static charts (heatmaps)

# PDF Generation
reportlab>=4.0.0           # Professional PDF documents

# Scientific Computing
scipy>=1.10.0              # Gaussian filters, image processing

# Utilities
python-dateutil>=2.8.2     # Date/time handling

Installation:

pip install -r requirements.txt

🛠️ Tech Stack

Layer Technology Version Purpose
Frontend Streamlit 1.28+ Reactive web interface
Custom CSS - Dark theme, animations
Solver OR-Tools CP-SAT 9.5+ Constraint programming
Visualization Plotly 5.14+ Interactive energy maps
Matplotlib 3.7+ Static heatmaps
Data Pandas 1.5+ DataFrames, tables
NumPy 1.23+ Array operations
PDF ReportLab 4.0+ Document generation
Scientific SciPy 1.10+ Filters, effects
Storage JSON stdlib Lightweight persistence

🤝 Contributing

We welcome contributions! Here's how to get started:

🔧 Development Setup

# Fork and clone
git clone https://github.com/YOUR_USERNAME/smart-timetable-builder.git
cd smart-timetable-builder

# Create virtual environment
python -m venv venv
source venv/bin/activate  # macOS/Linux
venv\Scripts\activate     # Windows

# Install dependencies
pip install -r requirements.txt

# Run in development mode
streamlit run app.py

🙏 Acknowledgments


Google OR-Tools
Constraint programming solver

Streamlit
Web app framework

Plotly
Interactive visualizations

ReportLab
PDF generation

Special Thanks:

  • All contributors
  • Educators who provided feedback
  • Open source community

📧 Contact & Support

🐛 Issues

Report Bugs

Found a bug? Let us know!

💬 Discussions

Join Discussions

Questions? Ideas? Let's talk!

📧 Email

your.email@example.com

Direct contact for sensitive issues

Show Your Support

If this project helps your school, please consider:

Starring the repository on GitHub
Sharing on social media
Contributing improvements
Writing about your experience

GitHub stars GitHub forks GitHub watchers


⬆ Back to Top


© 2024 Smart Timetable Builder

Made using Python, Streamlit, and OR-Tools

About

A high school timetable generator built with Python, Streamlit, and OR-Tools

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages