Finding the Best Time to Meet, A Python-Based Optimization Approach


Scheduling meetings can be a challenging task, especially when you have to consider the availability of multiple participants. In this blog post, we will walk you through a Python script that helps you find the best time to meet, given the schedules of all participants. We will also discuss how to handle “not good” time slots and prioritize certain users’ schedules.

Getting Started: Parsing Schedules

First, let’s create a function to parse the schedules of each participant. We will represent schedules as strings in the format “Days Time-Range”, where Days are comma-separated days of the week (e.g., “Mon,Tue,Wed”) and Time-Range is a start and end time separated by a hyphen (e.g., “09:00-17:00”).

def parse_schedule(schedule_str):
days, times = schedule_str.split(" ")
days = days.split(",")
times = times.split("-")
return days, [datetime.datetime.strptime(t, "%H:%M").time() for t in times]

This function takes a schedule string and returns a tuple of days and times.

Finding the Best Time to Meet

Now that we can parse schedules, let’s create a function to find the best time to meet based on the highest overlap in availability.

def find_best_time(schedules):
availability = defaultdict(int)

for schedule in schedules:
days, times = parse_schedule(schedule)
for day in days:
for hour in range(times[0].hour, times[1].hour):
availability[(day, hour)] += 1

best_time = max(availability, key=availability.get)
return best_time

This function takes a list of schedules and returns the best time to meet.

Let’s test it

if __name__ == "__main__":
schedules = [
"Mon,Tue,Wed 09:00-17:00",
"Tue,Wed,Thu 10:00-18:00",
"Wed,Thu,Fri 11:00-19:00",
]

best_time = find_best_time(schedules)
print(f"The best time to meet is {best_time[0]} at {best_time[1]:02d}:00")

In the example provided, the script will output:

The best time to meet is Wed at 11:00

Handling “Not Good” Time Slots

In some cases, you may want to avoid certain time slots when scheduling a meeting. To handle this, we can modify the find_best_time function to take a list of “not good” time slots and remove them from the availability dictionary before finding the best time.

def find_best_time(schedules, not_good_times):
availability = defaultdict(int)

for schedule in schedules:
days, times = parse_schedule(schedule)
for day in days:
for hour in range(times[0].hour, times[1].hour):
availability[(day, hour)] += 1

for not_good_time in not_good_times:
days, times = parse_schedule(not_good_time)
for day in days:
for hour in range(times[0].hour, times[1].hour):
availability.pop((day, hour), None)

best_time = max(availability, key=availability.get)
return best_time

Let’s test it

if __name__ == "__main__":
schedules = [
"Mon,Tue,Wed 09:00-17:00",
"Tue,Wed,Thu 10:00-18:00",
"Wed,Thu,Fri 11:00-19:00",
]

not_good_times = [
"Wed 12:00-14:00",
]

best_time = find_best_time(schedules, not_good_times)
print(f"The best time to meet is {best_time[0]} at {best_time[1]:02d}:00")

In the example provided, the script will output:

The best time to meet is Wed at 11:00

Prioritizing Certain Users’ Schedules

Sometimes, you may need to ensure that certain users’ schedules are satisfied when finding the best time to meet. To achieve this, we can modify the script to include a priority list of users and create a separate availability dictionary for these users.

def find_best_time(schedules, not_good_times, priority_users):
availability = defaultdict(int)
priority_availability = defaultdict(int)

for i, schedule in enumerate(schedules):
days, times = parse_schedule(schedule)
for day in days:
for hour in range(times[0].hour, times[1].hour):
if i in priority_users:
priority_availability[(day, hour)] += 1
else:
availability[(day, hour)] += 1

for not_good_time in not_good_times:
days, times = parse_schedule(not_good_time)
for day in days:
for hour in range(times[0].hour, times[1].hour):
availability.pop((day, hour), None)
priority_availability.pop((day, hour), None)

best_time = None
max_overlap = 0
for time, count in priority_availability.items():
if count == len(priority_users) and availability.get(time, 0) > max_overlap:
best_time = time
max_overlap = availability[time]

return best_time

This function now takes a list of priority user indices and finds the best time based on the highest overlap in availability for both priority and non-priority users.

Let’s test it

if __name__ == "__main__":
schedules = [
"Mon,Tue,Wed 09:00-17:00", # User 0
"Tue,Wed,Thu 10:00-18:00", # User 1
"Wed,Thu,Fri 11:00-19:00", # User 2
]

not_good_times = [
"Wed 12:00-14:00",
]

priority_users = [0, 2] # User 0 and User 2 must be satisfied

best_time = find_best_time(schedules, not_good_times, priority_users)
print(f"The best time to meet is {best_time[0]} at {best_time[1]:02d}:00")

In the example provided, the script will output:

The best time to meet is Wed at 11:00

Conclusion

In this blog post, we have demonstrated how to use Python to find the best time to meet, given the schedules of multiple participants. We have also shown how to handle “not good” time slots and prioritize certain users’ schedules. This script can be further optimized and adapted to specific requirements, such as considering time zones, handling more complex schedules, or finding multiple time slots that work for everyone.


Author: robot learner
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source robot learner !
  TOC