Skip to content

About

An even better Lunch Duty Optimizer

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Lunch Duty Optimizer

A Streamlit app that builds a fair lunch duty schedule for a school year (or any month or date range) from two CSVs: the school calendar and staff availability. The schedule is optimized as a whole with Google OR-Tools.

Features

  • 🎯 Fair Distribution: Everyone gets equal duties (within ±1)
  • 📅 Smart Scheduling: Respects Mon/Tue/Wed availability
  • 🔒 Constraints: Max 1 duty per person per week
  • 🏠 Quiet Room Rotation: Fair distribution of quiet room assignments
  • 📊 Analytics: View duty counts and distribution stats
  • 💾 Export: Download schedules as CSV

Quick Start

Local Development

pip install -r requirements.txt
streamlit run lunch_duty_scheduler_app_02.py

Deploy to Streamlit Cloud

  1. Fork this repository
  2. Go to share.streamlit.io
  3. Connect your GitHub repo
  4. Deploy!

CSV to PDF (companion app)

If you edit the CSV this app exports by hand, csv_to_pdf/ turns it into a printable PDF:

pip install -r csv_to_pdf/requirements.txt
streamlit run csv_to_pdf/csv_to_pdf_app.py

Required Files

Upload these CSV files in the app:

  1. Calendar CSV - School calendar with duty days marked
  2. Staff Availability CSV - Staff names and Mon/Tue/Wed availability

Algorithm

Optimizer (V3, default): the whole period is one cost-minimization problem (an integer program), solved by Google OR-Tools' CP-SAT solver (optimizer.py). Each possible schedule has a total cost, and the solver searches for the cheapest one, starting from the greedy schedule (and never returning anything worse than it).

  • Never broken: nobody works a day they marked unavailable; 3 staff per day; one quiet-room person per day.
  • Costs, most to least important: an empty slot (100,000) → a second duty in one week (5,000) → each duty outside someone's fair range (2,000; the fair range is an even share, lowered for people whose availability can't reach it) → two "avoid pairing" staff on the same day (400) → duties close together (up to 60, fading to 0 at the ideal gap) → a "try to pair" person without a partner (40) → quiet-room and weekday balance (20 / 10).
  • The app reports the cost, the greedy schedule's cost for comparison, whether the result is proven optimal, and what is still not met. Weights live in optimizer.Weights.

Quick greedy (V2): greedy.py, kept as an option and as the optimizer's starting point: it fills one day at a time with the 3 highest-scoring eligible people (quota urgency, gap since last duty, weekday variety), then does one pass of swaps for the pairing tags.

Tests: python -m pytest tests (made-up staff and calendar; about a minute).

Built With

License

MIT License - feel free to adapt for your school!

About

An even better Lunch Duty Optimizer

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages