|
|
import pandas as pd |
|
|
from datetime import datetime, timedelta |
|
|
import bisect |
|
|
|
|
|
JOUR_OFFSET = { |
|
|
'Monday': 0, 'Tuesday': 1, 'Wednesday': 2, 'Thursday': 3, |
|
|
'Friday': 4, 'Saturday': 5, 'Sunday': 6 |
|
|
} |
|
|
BASE_DATE = datetime(2025, 1, 6) |
|
|
|
|
|
def parse_slot(slot_str): |
|
|
jour, horaire = slot_str.split() |
|
|
horaire = horaire.replace(';', ':') |
|
|
h, m = map(int, horaire.split(':')) |
|
|
date = BASE_DATE + timedelta(days=JOUR_OFFSET[jour]) |
|
|
return datetime(date.year, date.month, date.day, h, m) |
|
|
|
|
|
def format_slot(dt): |
|
|
return f"{dt.strftime('%A')} {dt.strftime('%H:%M')}" |
|
|
|
|
|
|
|
|
def add_request(df_fixed, new_slot_str): |
|
|
new_dt = parse_slot(new_slot_str) |
|
|
desired_dt = new_dt - timedelta(minutes=5) |
|
|
|
|
|
|
|
|
slots_dt = sorted(parse_slot(s) for s in df_fixed['adjusted_time']) |
|
|
|
|
|
|
|
|
final_dt = desired_dt |
|
|
|
|
|
|
|
|
while True: |
|
|
conflict = False |
|
|
|
|
|
|
|
|
if new_dt - final_dt < timedelta(minutes=5): |
|
|
|
|
|
final_dt = new_dt - timedelta(minutes=5) |
|
|
conflict = True |
|
|
|
|
|
|
|
|
for slot in slots_dt: |
|
|
if abs((slot - final_dt).total_seconds()) < 5*60: |
|
|
|
|
|
|
|
|
|
|
|
if slot > final_dt: |
|
|
final_dt = slot - timedelta(minutes=5) |
|
|
else: |
|
|
final_dt = slot - timedelta(minutes=5) |
|
|
conflict = True |
|
|
break |
|
|
|
|
|
if not conflict: |
|
|
break |
|
|
|
|
|
final_str = format_slot(final_dt) |
|
|
df_fixed = pd.concat([ |
|
|
df_fixed, |
|
|
pd.DataFrame([{ |
|
|
'schedule_time': new_slot_str, |
|
|
'adjusted_time': final_str |
|
|
}]) |
|
|
], ignore_index=True) |
|
|
|
|
|
return df_fixed.sort_values('adjusted_time').reset_index(drop=True),final_str |
|
|
|