Skip to content

Repository files navigation

INST326 OOP Project 03 — Caregiver Scheduling Program

Course: INST326 — Object-Oriented Programming
Section: 0104
Group: 56
Authors: Myles Sartor, Dany Drammeh, Inmar Lizama
Date: November 21, 2024
GitHub Repository: INST326_Project03_56_Group


Table of Contents

  1. Project Overview
  2. Problem Context
  3. Features
  4. Requirements
  5. Installation and Setup
  6. How to Run
  7. Application Layout
  8. How It Works
  9. Class Structure and OOP Design
  10. Scheduling Logic
  11. Payroll Calculation
  12. Group Development Workflow
  13. Limitations and Future Improvements

Project Overview

This project is a desktop GUI application for managing caregiver schedules and payroll, built using Python and Tkinter. It was developed as a group project for INST326 and addresses a real-world scheduling challenge: coordinating multiple caregivers across daily AM and PM shifts, seven days a week. The application allows administrators to add and manage caregivers, set per-caregiver weekly availability preferences, automatically generate a weekly schedule based on those preferences, export the schedule as an HTML file, and produce a scrollable payroll report with weekly and monthly pay totals.


Problem Context

The application was designed in response to a specific real-world need: scheduling caregivers for a 93-year-old individual who requires 12 hours of care per day, divided into two 6-hour shifts. Currently, scheduling was managed manually on a physical monthly calendar that had to be photocopied and distributed. This program digitalizes and automates that process, making it broadly applicable to small businesses, care facilities, clubs, or any organization with recurring shift-based scheduling needs.

Scheduling parameters:

  • Care required 7 days a week
  • Two shifts per day: AM (7:00 AM to 1:00 PM) and PM (1:00 PM to 7:00 PM)
  • Each shift is 6 hours long
  • Up to 8 caregivers, some paid and some unpaid (family)
  • Availability varies by caregiver and can include exceptions

Features

  • Add, update, and delete caregiver records (name, phone, email, pay rate, hours)
  • Set per-caregiver weekly availability for each shift using a dropdown menu (Preferred, Available, Unavailable)
  • Automatically generate a weekly schedule that prioritizes "Preferred" caregivers before "Available" ones
  • Export the generated schedule as an HTML file saved to a user-specified location
  • View a scrollable payroll report with individual weekly and monthly pay, plus aggregate totals
  • Update individual caregiver hours independently of the schedule generation
  • Selectable Listbox for navigating and editing caregiver records
  • Entry fields auto-populate when a caregiver is selected from the list

Requirements

  • Python 3.x (3.6+ recommended)
  • Standard library only — no external packages required:
    • tkinter (built-in; on Linux may require sudo apt-get install python3-tk)
    • calendar (built-in)
    • tkinter.filedialog (built-in, part of tkinter)

Installation and Setup

  1. Download or clone the repository from GitHub:
    https://github.com/my1e2/INST326_Project03_56_Group
    
  2. Open the notebook Project03_56.ipynb in Jupyter Notebook or JupyterLab, or extract the code into a standalone .py file.
  3. No external data files are required on first launch.

How to Run

Open the notebook and run the code cell. The Tkinter window will launch as a separate desktop window titled "Caregiver Manager". The notebook kernel must remain active while the application is running.

To run as a standalone script:

python caregiver_manager.py

The application entry point uses the standard Python guard:

if __name__ == "__main__":
    app = CaregiverManager()
    app.run()

Application Layout

The main window (900x900 pixels) contains:

+------------------+---------------------------+
| Name:    [____]  |                           |
| Phone:   [____]  |   Caregiver Listbox       |
| Email:   [____]  |   (selectable, 50x15)     |
| Pay Rate:[____]  |                           |
| Hours:   [____]  |                           |
+------------------+---------------------------+
| [ Update Caregiver  ]                        |
| [ Delete Caregiver  ]                        |
| [ Set Availability  ]                        |
| [ Generate Schedule ]                        |
| [ Pay Report        ]                        |
| [ Update Hours      ]                        |
| [ Add Caregiver     ]                        |
+----------------------------------------------+
  • Left column: labeled entry fields for caregiver attributes
  • Right column: scrollable Listbox showing all caregiver names
  • Button column: action buttons that operate on the selected caregiver or the full roster

Selecting a caregiver in the Listbox automatically populates the entry fields with that caregiver's current data, ready for editing.


How It Works

Managing Caregivers

New caregivers are created by filling in the five entry fields (Name, Phone, Email, Pay Rate, Hours) and clicking "Add Caregiver". A Caregiver object is instantiated and appended to self.caregivers. The Listbox is refreshed and entry fields are cleared.

Selecting a caregiver from the Listbox triggers the add_attributes() method via a <<ListboxSelect>> event binding, which populates all entry fields with that caregiver's current values. Clicking "Update Caregiver" calls caregiver.update_details() to write the new values back to the object. Clicking "Delete Caregiver" removes the caregiver from the list entirely using list.pop().

Setting Availability

Clicking "Set Availability" while a caregiver is selected opens a Toplevel child window for that caregiver. The window displays a 7-row grid (one row per day of the week) with two dropdown menus per row (one for the AM shift, one for the PM shift). Each dropdown offers three options:

  • Preferred — caregiver actively wants this shift
  • Available — caregiver can take the shift if needed (default)
  • Unavailable — caregiver cannot work this shift

Each dropdown is backed by a StringVar initialized to the caregiver's current availability value for that day and shift. Clicking "Save" reads all StringVar values, constructs a 7x2 nested list, and calls caregiver.set_availability() to store it. The window is then closed.

Availability is stored internally as:

self.availability = [["Available"] * 2 for _ in range(7)]  # 7 days, 2 shifts

Generating the Schedule

Clicking "Generate Schedule" calls generate_schedule(), which:

  1. Resets all caregiver hours to 0
  2. Iterates over every day (0–6) and every shift (0 = AM, 1 = PM)
  3. For each slot, collects all caregivers marked as "Preferred" for that day/shift
  4. If any preferred caregivers exist, selects the first one
  5. If none are preferred, selects the first "Available" caregiver
  6. If neither preferred nor available caregivers exist, the slot is left empty
  7. Assigns the selected caregiver's name to the schedule slot and increments their hours by 6
if preferred:
    selected = preferred[0]
elif available:
    selected = available[0]
else:
    selected = None

if selected:
    schedule[day][shift] = selected.name
    selected.hours += 6

After the schedule is built, create_html_calendar() is called.

HTML Calendar Output

create_html_calendar() constructs an HTML table representing the weekly schedule. Each row corresponds to a day of the week and contains columns for Day, AM Shift, and PM Shift:

<table border='1'>
  <tr><th>Day</th><th>AM Shift</th><th>PM Shift</th></tr>
  <tr><td>Monday</td><td>CaregiverName</td><td>CaregiverName</td></tr>
  ...
</table>

A filedialog.asksaveasfilename() dialog prompts the user to choose a file name and save location. The HTML is written to the specified path. This file can be opened in any web browser or shared directly with caregivers.

Payroll Report

Clicking "Pay Report" opens a new Tk window with a scrollable Text widget. For each caregiver, the report displays:

  • Name
  • Weekly hours worked
  • Weekly gross pay (hours * pay_rate, rounded to 2 decimal places)
  • Monthly gross pay (weekly pay multiplied by 4)

Aggregate weekly and monthly totals for all caregivers are appended at the bottom. The text area is set to read-only (state="disabled") after the report is inserted to prevent accidental editing.

Updating Hours

The "Update Hours" button allows the administrator to manually override a caregiver's hours without regenerating the full schedule. The selected caregiver's hours field is updated using the value in the "Weekly Hours" entry field, validated with a try/except block to ensure a numeric value is provided.


Class Structure and OOP Design

Person

The base class representing any person in the system:

Attribute Type Description
name str Full name
phone str Phone number
email str Email address

Person.__init__() accepts and stores these three attributes. It serves as the parent class for Caregiver and establishes a reusable identity layer that could be extended to other staff roles.

Caregiver

Inherits from Person and extends it with scheduling and payroll attributes:

Attribute Type Description
pay_rate float Hourly pay rate in USD (default: 20.0)
hours float Weekly hours worked (used for payroll calculation)
availability list[list] 7x2 nested list of availability strings per day/shift

Key methods:

Method Description
update_details() Updates name, phone, email, and pay rate in a single call
set_availability() Replaces the full availability matrix with a new 7x2 list
calculate_weekly_pay() Returns self.hours * self.pay_rate (used for payroll)

Inheritance is used here to demonstrate the OOP principle of specialization: every Caregiver is-a Person, but with additional domain-specific behavior.

CaregiverManager

The top-level application class that owns the main Tkinter window and all GUI widgets:

Attribute Type Description
master tk.Tk The root window
caregivers list In-memory list of all Caregiver objects
name_var StringVar Tkinter variable bound to the Name entry field
phone_var StringVar Tkinter variable bound to the Phone entry field
email_var StringVar Tkinter variable bound to the Email entry field
pay_rate_var StringVar Tkinter variable bound to Pay Rate entry (default: 20.0)
hours_var StringVar Tkinter variable bound to Hours entry (default: 0)
caregiver_list Listbox Scrollable widget displaying caregiver names

This class encapsulates the entire application state and all event handling, following the principle that the GUI layer manages user interaction while delegating data concerns to Person and Caregiver.


Scheduling Logic

The scheduler uses a greedy first-fit algorithm:

  1. For each of the 14 weekly time slots (7 days x 2 shifts), scan all caregivers
  2. Collect all whose availability for that slot is "Preferred"; assign the first one found
  3. If none are preferred, fall back to the first "Available" caregiver
  4. If no caregiver is available, the slot is assigned an empty string

This is a deterministic, priority-based approach. It does not attempt to balance workloads or avoid scheduling the same caregiver for consecutive shifts. The hours counter is incremented by 6 for each assignment and resets to 0 at the start of every generate_schedule() call.


Payroll Calculation

Pay is calculated as:

Weekly Gross Pay = hours * pay_rate
Monthly Gross Pay = Weekly Gross Pay * 4

This is a simplified estimate that assumes exactly 4 weeks per month. All monetary values are displayed with two decimal places. The calculate_weekly_pay() method on the Caregiver class performs this calculation, although the payroll_report() method in CaregiverManager also computes it inline. Caregivers with a pay rate of 0.0 (unpaid family members) will appear in the report with $0.00 pay values.


Group Development Workflow

This project was developed collaboratively using Git and GitHub:

  • One group member (Myles Sartor) hosted the group repository at https://github.com/my1e2/INST326_Project03_56_Group
  • Individual branches were created for each group member
  • Each member implemented their assigned portion of the application on their branch
  • Branches were merged back into main upon completion
  • Iteration and debugging were performed after merging to resolve integration issues

Group members and their areas of contribution are tracked in the GitHub repository's commit and branch history.


Limitations and Future Improvements

  • Caregiver data is not persisted between sessions. Adding JSON or SQLite storage for caregiver records and availability would allow the program to be used across multiple sessions without re-entering all data.
  • The scheduling algorithm selects the first matching caregiver from the list without considering workload balance. A more sophisticated approach (e.g., round-robin or least-hours-first) would distribute hours more equitably.
  • The program does not prevent a single caregiver from being assigned to both shifts on the same day, which may not be desirable in all scheduling contexts.
  • Monthly pay is approximated as weekly pay multiplied by 4. A more accurate calculation would account for the actual number of weeks in the given month.
  • The HTML calendar displays a single weekly schedule rather than a full monthly calendar. Integrating the Python calendar module (which was imported but not used in the final version) to generate a proper monthly grid would better match the original problem statement.
  • There is no input validation on the Name, Phone, or Email fields — empty or malformed entries can be submitted.
  • The payroll report opens as a new root Tk() window rather than a Toplevel child window. Using Toplevel would follow Tkinter best practices and avoid potential issues with having two root windows.
  • No export option is provided for the payroll report. Adding a "Save as TXT" or "Save as PDF" button would improve usability.

About

Project 3

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages