From 0b732a0b094b3c95f13d5bc65379a89a4b57f23a Mon Sep 17 00:00:00 2001 From: Ross Date: Tue, 16 Dec 2025 20:58:09 +0000 Subject: [PATCH] start updating cons rota --- gen_cons.py | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/gen_cons.py b/gen_cons.py index c0a3565..d1c418b 100644 --- a/gen_cons.py +++ b/gen_cons.py @@ -39,10 +39,10 @@ def extract_leave_and_rota_from_calender(calender_df): # Get rota data from the second row (index 1), starting from column 5 (index 4) # Extract the rota data for each worker from the first data row (index 0), columns 5 onwards rota_row = calender_df.iloc[0] - rota_data = {} + #rota_data = {} for i, worker in enumerate(worker_names): assignment = str(rota_row.iloc[5 + i]).strip() if len(rota_row) > 5 + i else "" - rota_data[worker] = f"rota {assignment.lower()}" + #rota_data[worker] = f"rota {assignment.lower()}" leave_requests = [] work_requests = [] @@ -77,7 +77,7 @@ def extract_leave_and_rota_from_calender(calender_df): #print(leave_requests) - return leave_requests, work_requests, rota_data + return leave_requests, work_requests#, rota_data def extract_shift_assignments_from_rota(rota_df): """ @@ -140,7 +140,7 @@ def extract_shift_assignments_from_rota(rota_df): def load_workers(): # Path to the ODS file - ods_path = "cons/Oncall rota requests + New rota (first draft) - September 2025.ods" + ods_path = "cons/CONSULTANT TWILIGHT & ONCALL ROTA.ods" # Read all sheets xls = pd.read_excel(ods_path, engine="odf", sheet_name=None) @@ -151,7 +151,7 @@ def load_workers(): rota_df = xls["Rota"] - rota_b_path = "cons/Draft Rota B Sept 25-Feb 26.xlsx" + rota_b_path = "cons/Rota B Feb -July 2026.xlsx" rota_b_df = pd.read_excel(rota_b_path, engine="openpyxl", sheet_name="Sheet1", header=None) # Extract rota_b assignments: date in column A, worker in column B rota_b_assignments = defaultdict(list) @@ -176,6 +176,7 @@ def load_workers(): #print(days_df.head()) weekday_cols = ["Mon", "Tue", "Wed", "Thu", "Fri"] workers_days = [] + rota_data = {} for idx, row in days_df.iloc[7:].iterrows(): # Extract initials from the name column (assumed to be in brackets at the end) text = str(row.iloc[1]).strip() @@ -188,15 +189,16 @@ def load_workers(): continue availability = {} requests = {} + rota_data[name] = f"rota {str(row.iloc[2]).strip().lower()}" for i, day in enumerate(weekday_cols): - val = row.iloc[2 + i] + val = row.iloc[3 + i] # You can adjust the logic below depending on your marking scheme (e.g. "Y", "Yes", "1", etc.) available = not ("no" in str(val).strip().lower()) availability[day] = available workers_days.append({"initial": initial, "name": name, "availability": availability, "requests": requests}) - leave_requests, work_requests, rota_data = extract_leave_and_rota_from_calender(calender_df) + leave_requests, work_requests = extract_leave_and_rota_from_calender(calender_df) assignments, assignments_by_worker = extract_shift_assignments_from_rota(rota_df) print(assignments) @@ -206,20 +208,20 @@ def load_workers(): worker = worker_day["name"] initial = worker_day["initial"] - start_date = "2025-09-01" # Default start date, can be adjusted later + start_date = "2026-02-16" # Default start date, can be adjusted later - if initial == "ND": - start_date = "2025-09-29" # Non-working day worker starts later - if initial == "MF": - start_date = "2026-01-15" # Medical leave worker starts earlier - if initial == "AA": - start_date = "2025-11-17" # Absent worker starts later + #if initial == "ND": + # start_date = "2025-09-29" # Non-working day worker starts later + #if initial == "MF": + # start_date = "2026-01-15" # Medical leave worker starts earlier + #if initial == "AA": + # start_date = "2025-11-17" # Absent worker starts later end_date = None - if initial == "L1": - end_date = "2025-11-17" # L1 worker has a leave request - elif initial == "L2": - end_date = "2025-09-29" # L2 worker has a leave request + #if initial == "L1": + # end_date = "2025-11-17" # L1 worker has a leave request + #elif initial == "L2": + # end_date = "2025-09-29" # L2 worker has a leave request non_working_days = [] for day, available in worker_day["availability"].items(): @@ -255,8 +257,6 @@ def load_workers(): # reason="even out shifts", # )] - if initial == "ND": - print(w.not_available_to_work) if initial in assignments_by_worker: # Add shift assignments for this worker @@ -291,10 +291,10 @@ def load_workers(): w.add_force_assign_with("weekend", "oncall") if w.name in ("DS",): - w.add_hard_day_dependency({"Fri", "Sat", "Sun"}, start_date="2025-11-17") + w.add_hard_day_dependency({"Fri", "Sat", "Sun"}) else: - w.add_hard_day_dependency({"Fri", "Sun"}, start_date="2025-11-17") - w.add_hard_day_exclusion({"Sat", "Sun"}, start_date="2025-11-17") + w.add_hard_day_dependency({"Fri", "Sun"}) + w.add_hard_day_exclusion({"Sat", "Sun"}) #if w.name == "TB": @@ -316,7 +316,7 @@ def main( solve: bool = True, time_to_run: int = 60 * 60, ratio: float = 0.001, - start_date: datetime.datetime = "2025-09-01", + start_date: datetime.datetime = "2026-02-16", weeks: int = 24, bom: int = 1, ): @@ -327,7 +327,7 @@ def main( rota_start_date, weeks_to_rota=weeks, balance_offset_modifier=bom, - name="cons rota test", + name="cons rota feb 2026", allow_force_assignment_with_leave_conflict=True, ) # Rota = RotaBuilder(start_date, weeks_to_rota=20, balance_offset_modifier=1)