Skip to content

Thorium234/offlineTimeTable_Cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Thorium234 β€” School Timetable Generator

A dual-stack school timetable generator combining a Qt5 C++ GUI with a Flask + Vanilla JS web interface, sharing an SQLite database. Includes two independent solver pipelines β€” a high-performance C++ backtracking/MRV solver for uniform period grids, and a Python greedy solver with per-class dynamic timelines for schools that need different lesson durations across streams.


Features

  • Two solver engines: C++ BacktrackingSolver (MRV + LCV + domain propagation) and GreedySolver; Python GreedySolver with dynamic timelines
  • Per-class lesson durations: Form 4 can use 60-minute periods while Form 1 uses 40-minute periods, all under the same break schedule
  • Configurable time blocks: Define assemblies, morning tea, lunch, games β€” any break type, any duration, per day of the week
  • Full constraint set: maxPerDay, blockSize (double periods), secondTeacherId, week types (A/B/Every), teacher max consecutive, class period windows, room capacity/type
  • Fixed events: Lock specific (day, period) slots for recurring events (lunch, assembly)
  • Teacher preferences: Mark slots as BLOCKED/PREFERRED/UNDESIRABLE per teacher
  • Substitutions: Request, suggest, approve, and track substitute teacher assignments
  • Divisions: Group classes for parallel scheduling
  • Versioning: Save, compare, and restore timetable solutions (aSc-style)
  • Drag & drop: Manual slot adjustment with undo/redo and conflict checking
  • Export: Professional aSc-style PDF (ReportLab), HTML, CSV
  • Analytics: Teacher load distribution, room utilization, gap statistics
  • Flask web API: 60+ REST endpoints β€” full CRUD, generate, export, analytics
  • Custom Timetable modal: Load sample Kenyan school data, adjust breaks & durations, generate PDF in one click
  • Docker support: Containerized deployment

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    C++ Binary (timetableGen)                        β”‚
β”‚                                                                     β”‚
β”‚  main.cpp ──→ QApplication ──→ MainWindow ──→ Qt5 GUI              β”‚
β”‚      β”‚                         (16 widget classes)                  β”‚
β”‚      β”œβ”€β”€β†’ startFlaskWebServer() ──→ python3 web/app.py             β”‚
β”‚      β”‚                            (port 5000-5009)                  β”‚
β”‚      └──→ --solve-from-db ──→ DataManager ──→ TimetableEngine      β”‚
β”‚                                                β”œβ”€β”€ BacktrackingSolverβ”‚
β”‚                                                └── GreedySolver     β”‚
β”‚                                                                     β”‚
β”‚  DataManager ──→ SQLiteService ──→ timetable.db                    β”‚
β”‚                                                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                     Flask Server (web/app.py)                       β”‚
β”‚                                                                     β”‚
β”‚  60+ API endpoints: CRUD, generate, export, analytics, versions    β”‚
β”‚                                                                     β”‚
β”‚  /api/generate (POST) ──→ C++ binary --solve-from-db (subprocess)  β”‚
β”‚  /api/generate-timetable (POST) ──→ Python greedy solver + PDF     β”‚
β”‚  /api/export/pdf (GET) ──→ HTMLβ†’pdfkit or ReportLab                β”‚
β”‚                                                                     β”‚
β”‚  timeline_gen.py ──→ per-class dynamic timelines + greedy solver   β”‚
β”‚  pdf_generator.py ──→ ReportLab aSc-style PDF (direct canvas)      β”‚
β”‚                                                                     β”‚
β”‚  templates/index.html ──→ SPA shell                                 β”‚
β”‚  static/js/app.js    ──→ 1665 lines vanilla JS                      β”‚
β”‚  static/css/asc.css  ──→ 290 lines                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Directory Structure

offlineTimeTableCpp/
β”œβ”€β”€ main.cpp                 # Entry point β€” GUI mode or --solve-from-db
β”œβ”€β”€ Makefile                 # GNU Make build
β”œβ”€β”€ CMakeLists.txt           # CMake build (alternative)
β”œβ”€β”€ pyproject.toml           # Python dependencies
β”œβ”€β”€ AGENTS.md                # Developer guide
β”‚
β”œβ”€β”€ models/                  # Domain structs (17 headers)
β”‚   β”œβ”€β”€ Teacher.h, Subject.h, SchoolClass.h, Room.h, Lesson.h
β”‚   β”œβ”€β”€ FixedEvent.h, TimeBlock.h, LessonUnit.h
β”‚   β”œβ”€β”€ Day.h, Period.h, RoomType.h, SubjectRequirement.h
β”‚   β”œβ”€β”€ Division.h, Substitution.h
β”‚   └── TeacherConstraint.h, TeacherPreference.h, ConstraintViolation.h
β”‚
β”œβ”€β”€ services/                # Business logic (19 .cpp/.h pairs)
β”‚   β”œβ”€β”€ DataManager.h/.cpp         # Central data hub + CRUD
β”‚   β”œβ”€β”€ SQLiteService.h/.cpp       # All database operations
β”‚   β”œβ”€β”€ TimetableEngine.h/.cpp     # Solver orchestrator
β”‚   β”œβ”€β”€ BacktrackingSolver.h/.cpp  # MRV + LCV + domain propagation
β”‚   β”œβ”€β”€ GreedySolver.h/.cpp        # Heuristic fallback
β”‚   β”œβ”€β”€ FeasibilityChecker.h/.cpp  # Pre-solve validation
β”‚   β”œβ”€β”€ ConflictChecker.h/.cpp     # Post-placement checks
β”‚   β”œβ”€β”€ TimetableEvaluator.h/.cpp  # Score computation
β”‚   β”œβ”€β”€ AnalyticsService.h/.cpp    # Statistics
β”‚   β”œβ”€β”€ ExportService.h/.cpp       # CSV / HTML export
β”‚   β”œβ”€β”€ PdfReportService.h/.cpp    # Qt5 PDF export
β”‚   β”œβ”€β”€ TimelineGenerator.h/.cpp   # C++ dynamic timeline
β”‚   └── ...                        # Benchmark, UndoRedo, ConstraintExplain
β”‚
β”œβ”€β”€ timetable/               # Grid model
β”‚   └── Timetable.h/.cpp     # TimetableCell, 2D grid storage
β”‚
β”œβ”€β”€ gui/                     # Qt5 GUI widgets (16 files)
β”‚   β”œβ”€β”€ MainWindow.cpp
β”‚   β”œβ”€β”€ ribbon/RibbonToolbar.cpp
β”‚   β”œβ”€β”€ sidebar/DataSidebar.cpp
β”‚   β”œβ”€β”€ timetableview/{TimetableViewWidget,TimetableScene,LessonCardItem}.cpp
β”‚   β”œβ”€β”€ dashboard/DashboardWidget.cpp
β”‚   β”œβ”€β”€ teachers/TeacherDialog.cpp, subjects/SubjectDialog.cpp
β”‚   β”œβ”€β”€ classes/ClassDialog.cpp, rooms/RoomDialog.cpp
β”‚   β”œβ”€β”€ substitutions/SubstitutionWidget.cpp
β”‚   β”œβ”€β”€ divisions/DivisionWidget.cpp
β”‚   └── constraints/ConstraintRelaxationDialog.cpp
β”‚
β”œβ”€β”€ web/                     # Python web layer
β”‚   β”œβ”€β”€ app.py               # Flask server β€” 60 API endpoints
β”‚   β”œβ”€β”€ timetable_gen.py     # Dynamic timeline + greedy solver
β”‚   β”œβ”€β”€ pdf_generator.py     # ReportLab aSc-style PDF
β”‚   β”œβ”€β”€ static/js/app.js     # SPA frontend (1665 lines)
β”‚   β”œβ”€β”€ static/css/asc.css   # Styles (290 lines)
β”‚   └── templates/index.html # SPA shell
β”‚
β”œβ”€β”€ tests/                   # Test suites
β”‚   β”œβ”€β”€ test_runner.cpp      # 12 C++ tests (315 lines)
β”‚   β”œβ”€β”€ test_api.py          # 17 Flask integration tests
β”‚   └── test_timetable_gen.py# 24 Python unit tests
β”‚
β”œβ”€β”€ utils/PathUtil.h         # Path resolution
β”œβ”€β”€ data/                    # SQLite database (gitignored)
β”œβ”€β”€ docs/                    # Documentation
β”‚   └── SYSTEM_REVIEW.md     # Full system review
β”œβ”€β”€ Dockerfile               # Container build
└── run.sh                   # Convenience launcher

Dependencies

C++

  • Compiler: GCC (g++) with C++17 support
  • Qt5: Widgets, Sql, PrintSupport modules
  • pkg-config (for Qt discovery)

Install on Ubuntu/Debian:

sudo apt install g++ make pkg-config qtbase5-dev libqt5sql5-sqlite libqt5printsupport5

Python

pip install flask flask-cors       # Required
pip install reportlab              # Optional β€” for aSc-style PDF export
pip install pdfkit                 # Optional — for HTML→PDF export (requires wkhtmltopdf)

Build & Run

Make (recommended)

make              # Release build (./timetableGen)
make BUILD=debug  # Debug build with sanitizers
make test         # Build and run C++ tests
make clean        # Remove build artifacts
make format       # Run clang-format on all source files

CMake

cmake -B build_cmake -S .
cmake --build build_cmake -j
./build_cmake/timetableGen

Run Tests

# C++ tests
make test
# or
./build_cmake/test_runner

# Python unit tests
python3 -m pytest tests/test_timetable_gen.py -v

# Flask integration tests
python3 tests/test_api.py

Usage

GUI Mode

./timetableGen

Launches the Qt5 desktop application and automatically starts the Flask web server on http://127.0.0.1:5000.

Headless Solver Mode

./timetableGen --solve-from-db

Loads timetable data from the SQLite database, runs the C++ solver, and writes a JSON result to stdout. Used by the Flask /api/generate endpoint.

Web Interface Only

python3 web/app.py

Starts the Flask server without the C++ GUI. The web interface provides full CRUD, generation, export, and analytics.

Custom Timetable (Dynamic Config)

  1. Click Custom TT in the Timetable tab
  2. Click Load Sample School to load realistic Kenyan school data (Alliance High School)
  3. Adjust day start/end, break times, per-class lesson durations
  4. Click Generate Timetable β†’ downloads a professional aSc-style PDF

API Overview (Selected Endpoints)

Endpoint Method Purpose
/api/teachers, /api/subjects, /api/classes, /api/rooms GET/POST/PUT/DELETE Entity CRUD
/api/lessons GET/POST/PUT/DELETE Lesson CRUD with combined classes
/api/generate POST Run C++ solver, return JSON result
/api/generate-timetable POST Run Python dynamic solver, return PDF
/api/sample-school GET Sample Kenyan school configuration
/api/analytics GET Teacher load, room utilization, gap stats
/api/export/html GET Full HTML timetable document
/api/export/pdf GET PDF timetable (via pdfkit)
/api/conflicts GET Current conflict list
/api/substitutions GET/POST Substitution lifecycle
/api/divisions GET/POST/PUT/DELETE Division CRUD
/api/versions GET/POST Save/restore/compare timetable versions
/api/data/export GET Full JSON backup
/api/data/import POST JSON restore

See docs/SYSTEM_REVIEW.md or web/app.py for the complete endpoint listing.


Solvers

Solver Language Algorithm Grid Model Use Case
BacktrackingSolver C++ MRV + LCV + domain propagation Uniform (5Γ—8) High-quality solutions, all classes same period duration
GreedySolver (C++) C++ Weighted slot scoring Uniform (5Γ—8) Fast fallback for simple schedules
GreedySolver (Python) Python First-fit with difficulty ordering Per-class dynamic Schools with different lesson durations per stream

Custom Timetable JSON Schema

{
  "school": { "name": "School Name" },
  "configuration": {
    "day_start": "07:30",
    "day_end": "16:30",
    "default_lesson_duration_minutes": 40
  },
  "time_blocks": [
    { "name": "Assembly", "type": "fixed_break",
      "start": "07:30", "end": "08:00", "days": ["Monday", "Friday"] },
    { "name": "Lunch", "type": "fixed_break",
      "start": "12:30", "end": "13:30", "days": ["All"] }
  ],
  "teachers": [
    { "id": "T1", "name": "Paul Inyangala", "abbreviation": "PI",
      "qualified_subjects": ["MATH"] }
  ],
  "classes": [
    { "id": "F1A", "name": "Form 1 A",
      "lesson_duration_minutes": 40,
      "subject_requirements": [
        { "subject": "MATH", "abbreviation": "MATH",
          "lessons_per_week": 5, "max_per_day": 2, "block_size": 1 }
      ]
    }
  ]
}

License

MIT β€” see LICENSE.MD


Built with Qt5, Flask, ReportLab, SQLite, and love for Kenyan schools.

About

No description, website, or topics provided.

Resources

License

GPL-3.0, MIT licenses found

Licenses found

GPL-3.0
licence.txt
MIT
LICENSE.MD

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors