How to check if two time ranges are overlapping in an efficient manner (Python)

Issue

I have a list with a set of particular time ranges as such:

['ARTS  111  A', 'M', '09:00 - 12:00', 'W', '09:00 - 12:00', 'F', '02:00 - 12:00', 'COMP 111  A', 'M', '09:00 - 12:00', 'W', '09:00 - 12:00']

Now, I wish to compare these ranges with another set of day and date ranges as so:

['COMP 200 A', 'M', '09:30 - 11:30', 'W', '09:00 - 12:00']

If it helps, here’s the raw version of the dictionary:

dict = {
    'ARTS  111  A': {'course_code': 'ARTS  111  A', 'course_final': 'Fundam. of Drawing I', 'course_credits': '3 ',
                      'course_type': 'SBLOCK', 'course_room': 'S008', 'start_date': 'start:03/07/2022', 'days': 'M W',
                      'time': '09:00 - 12:00', 'instructor': 'John', 'capacity': '20', 'enrolled': '15', 'days_2': 'F',
                      'time_2': '02:00 - 12:00'
                     },
    'COMP  111  A': {'course_code': 'COMP 111  A', 'course_final': 'Fundam. of Drawing I', 'course_credits': '3 ',
                      'course_type': 'SBLOCK', 'course_room': 'S008', 'start_date': 'start:03/07/2022', 'days': 'M W',
                      'time': '09:00 - 12:00', 'instructor': 'John', 'capacity': '20', 'enrolled': '15'}
}

clash = {

'SCI 100  A': {'course_code': 'SCI  100  A', 'course_final': 'Fundam. of Drawing I', 'course_credits': '3 ',
                      'course_type': 'SBLOCK', 'course_room': 'S008', 'start_date': 'start:03/07/2022', 'days': 'M W',
                      'time': '09:00 - 12:00', 'instructor': 'John', 'capacity': '20', 'enrolled': '15'}
}

I have constructed the following function in order to ‘clean’ things up leading to the output mentioned above:

def date_time(dict):
    lst = []
    for x in dict:
        lst.append(dict[x]['course_code'])
        days = dict[x]['days']
        days = days.split()
        for y in days:
            lst.append(y)
            lst.append(dict[x]['time'])
        return lst

As apparent, just equating these two would not work. I am creating a timetable that would check for clashes between pre-existing classes and would compare them with the one new class that the user wishes to select.
Would appreciate some help on what I need to do!

Solution

So after some working and sleep in between
I’ve managed to fetch you up with a solution
there’s a function that breaks the given lists to comfy dictionary
and then a function that checks if they overlap

exisitng_classes=['ARTS  111  A', 'M', '09:00 - 12:00', 'W', '09:00 - 12:00', 'F',
                  '02:00 - 12:00', 'COMP 111  A', 'M', '09:00 - 12:00', 'W', '09:00 - 12:00']

proposed_class=['COMP 200 A', 'M', '09:30 - 11:30', 'W', '09:00 - 12:00']

def check_time_overlap(time1,time2):
    """
    returns boolean whether these times overlap or not, True if overlap
    """
    split=time1.split("-")
    min1=int(split[0].replace(":",""))
    max1=int(split[-1].replace(":",""))
    split=time2.split("-")
    min2=int(split[0].replace(":",""))
    max2=int(split[-1].replace(":",""))

    return not ((max2 - min1) * (min2 - max1) >= 0)
      
    
def where_overlapping(existing,proposed):
    """
    This function checks whether or not
    and where the classes are overlapping

    gets 1 list of all lessons and their hours
    and 1 list of new single proposed lesson and its hours

    returns a list of all overlaps, if empty = no overlaps
    """
    name_of_class=""
    sliced=existing[0].split(" ")[1:]
    for item in sliced[:-1]:
        name_of_class+=item+" "
    name_of_class+=sliced[-1]
    
    indexes=[]
    counter=0
    for each in existing:
        
        if name_of_class in each:
            indexes.append((counter,each))

        counter+=1


        
    class_dictionary={}
    index=0
    while index<len(indexes)-1:
        class_dictionary[indexes[index][1]]=existing[indexes[index][0]+1:indexes[index+1][0]]
        index+=1
   
    class_dictionary[indexes[-1][1]]=existing[indexes[-1][0]+1:]

    overlaps=[]

    

    for classroom in class_dictionary:
        prop_counter=0
        while prop_counter<len(proposed[1:]):
            counter=0
            while counter<len(class_dictionary[classroom]):
                if class_dictionary[classroom][counter]==proposed[1:][prop_counter]:

                    if check_time_overlap(class_dictionary[classroom][counter+1],proposed[1:][prop_counter+1]):

                        
                        overlaps.append(classroom+" of "+ class_dictionary[classroom][counter+1]
                                        +" with "+proposed[0]+" at "+proposed[1:][prop_counter+1]+" at day "
                                        +proposed[1:][prop_counter])
                    
                counter+=2
            prop_counter+=2
            
    return overlaps
            
            
if __name__ == "__main__":

    for x in where_overlapping(exisitng_classes,proposed_class):
        print(x)
    print(check_time_overlap("12:00 - 14:00","13:00-17:00"))
    print(check_time_overlap("12:00 - 14:00","15:00-17:00"))
    print(check_time_overlap("12:00 - 14:00","12:00-14:00"))
    print(check_time_overlap("12:00 - 14:00","11:00-15:00"))
    print(check_time_overlap("12:00 - 14:00","10:00-16:00"))
            

Answered By – DanielGzgzz

Answer Checked By – Candace Johnson (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.