Home > Software engineering >  find available meeting time slots in python3?
find available meeting time slots in python3?

Time:10-04

I have specific meetings times for each person and i want to find the suitable time for all meetings

this is my code but its not doing the work done

im dealing with times in integers like this-> 855 means 8:15 .

p1_meetings = [
            (855,  915), 
            (955, 1015), 
            (1155, 1215), 
        ]

p2_meetings = [
            (815, 955),
            (1015, 1055), 
            (1115, 1255),
        ]

morning = "00:00"
end_day = "23:59"

meetings = [p1_meetings, p2_meetings]

#define a function to find available times meetings.
def get_meetings(List_of_meetings_times):

    # we will find the min value for two meetings times and make it from the startday to min value
    min_meet_time = p1_meetings   p2_meetings
    first_meet = min(min_meet_time)

    # we will find the max value for two meetings times and make it from it till end of the day
    max_meet_time = p1_meetings   p2_meetings
    last_meet = max(max_meet_time)

    #first meeting time
    print(morning,":",first_meet[0])

    #last meeting time
    print(last_meet[1],":",end_day)


get_meetings(meetings)  

i have found the first and last meetings time but how can i found others ?

the expect output is :

00 815
1055 1115
1255 2359

i have read a lot of questions here but its not solve my problem, etc: Algorithm to find meeting time slots where all participants are available

CodePudding user response:

You could build a set of busy minutes in the day and use it to flag a list of all possible minutes in a day (1440 of them). Then form the available meeting periods based on streaks of consecutive minutes that are free.

Note that, to make this easier to manage, the time representation will need to be converted to base 60 (instead of base 100) so that all 1440 minutes are consecutive numbers.

def get_meetings(List_of_meetings_times):
    busy = { t for meets in List_of_meetings_times
               for start,end in meets
               for t in range(start-start//100*40,end-end//100*40) }
    free   = [t not in busy for t in range(1440)]
    breaks = [i for i,(a,b) in enumerate(zip(free,free[1:]),1) if b!=a]
    result = [(s,e) for s,e in zip([0] breaks,breaks [1439]) if free[s]]
    return [(s s//60*40,e e//60*40) for s,e in result]

Output:

p1_meetings = [
            (855,  915), 
            (955, 1015), 
            (1155, 1215), 
        ]

p2_meetings = [
            (815, 955),
            (1015, 1055), 
            (1115, 1255),
        ]
    
meetings = [p1_meetings, p2_meetings]

print(get_meetings(meetings))
[(0, 815), (1055, 1115), (1255, 2359)]

here's how it works:

  • busy is a set of non-available minute numbers in the day (in base 60, i.e. number of minutes since midnight).
  • It is built using a 3 level comprehension:
  • ... for meets in List_of_meetings_times goes through all the meeting lists to obtain a list of meeting time ranges in meets
  • ... for start,end in meets splits each of the meeting time ranges into a start and end time
  • ... for t in range(start-start//100*40,end-end//100*40) generates every minute number of the meeting time range (in base 60)
  • ... The resulting set is made of all the minute numbers (t) and only hold one copy of the busy minute numbers even if several meetings overlap
  • free is a list of True/False values for each of the 1440 minutes of the day (the index is the minute number) where busy minutes are False and free minutes are True. It is built by checking each minute (from 0 to 1439) against the busy set
  • breaks is a list of the indexes (minutes) where the free/busy flags change from True to False or from False to True. This is obtained using zip() to compare each minute with it's successor
  • result uses zip() again to match each break index with the next break index, thus forming ranges. Only ranges that start on a free minute are kept.
  • return ... converts the base 60 minutes in each range back into base 100 encoding

Note that I used 1439 instead of 1440 to represent the end of the last time range so that it matched the inconsistency in your expected output of 12:55-23:59 instead of 12:55-24:00 or 12:55-00:00 (although the end times are exclusive in all other meeting period except that last one)

Results converted to strings:

slots = ["-".join(f"{h:02}:{m:02}" for t in slot for h,m in [divmod(t,100)] )
         for slot in get_meetings(meetings)]

print(*slots,sep="\n")

00:00-08:15
10:55-11:15
12:55-23:59
  • Related