import datetime
import re
from dataclasses import dataclass, field
raw_data = ['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',
            'COMP 200 A', 'M', '09:30 - 11:30', 'W', '09:00 - 12:00']
# the data is not structured, so let's parse it !
days_letters = ('M', 'T', 'W', 'H', 'F')  # 'H' used for tHursday
timerange_pattern = re.compile(r"(\d\d):(\d\d) - (\d\d):(\d\d)")
#                        group(1) ^^^^  2^^^^    3^^^^  4^^^^
coursename_pattern = re.compile(r"(\w+\s+\d+\s+\w)")
#                         group(1) ^^^^^^^^^^^^^^
@dataclass
class Course:
    name: str
    slots: list = field(default_factory=list)
@dataclass
class CourseSlot:
    day: str
    time_start: datetime.time
    time_end: datetime.time
tokens = list(raw_data)
courses = []
while tokens:
    token = tokens.pop(0)  # get the first string
    course_name_match = coursename_pattern.fullmatch(token)
    assert course_name_match is not None
    course_name = course_name_match.group(1)
    course = Course(name=course_name)
    # then read the days and hours
    while tokens:
        if tokens[0] in days_letters:
            day = tokens.pop(0)
            timerange_match = timerange_pattern.fullmatch(tokens.pop(0))
            assert timerange_match is not None
            start_hour = int(timerange_match.group(1))
            start_minute = int(timerange_match.group(2))
            end_hour = int(timerange_match.group(3))
            end_minute = int(timerange_match.group(4))
            course.slots.append(CourseSlot(
                day=day,
                time_start=datetime.time(hour=start_hour, minute=start_minute),
                time_end=datetime.time(hour=end_hour, minute=end_minute),
            ))
        else:
            break
    courses.append(course)
print(courses)
# [Course(name='ARTS  111  A', slots=[CourseSlot(day='M', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#                                     CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#                                     CourseSlot(day='F', time_start=datetime.time(2, 0), time_end=datetime.time(12, 0))]),
#  Course(name='COMP 111  A', slots=[CourseSlot(day='M', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#                                    CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0))]),
#  Course(name='COMP 200 A', slots=[CourseSlot(day='M', time_start=datetime.time(9, 30), time_end=datetime.time(11, 30)),
#                                   CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0))])]
@dataclass
class Clash:
    course1_name: str
    course2_name: str
    course1_slot: CourseSlot
    course2_slot: CourseSlot
# now search for overlap :
clashes = []
for i, first_course in enumerate(courses[:-1], start=1):  # from first to last-1
    for second_course in courses[i:]:  # from after the first to the last
        for first_slot in first_course.slots:
            for second_slot in second_course.slots:
                if first_slot.day == second_slot.day:
                    if first_slot.time_start <= second_slot.time_end and \
                            second_slot.time_start <= first_slot.time_end:  # see https://stackoverflow.com/a/3269471/11384184
                        # we have a match !
                        clashes.append(Clash(course1_name=first_course.name,
                                             course2_name=second_course.name,
                                             course1_slot=first_slot,
                                             course2_slot=second_slot))
print(clashes)
# [
#   Clash(course1_name='ARTS  111  A',
#         course2_name='COMP 111  A',
#         course1_slot=CourseSlot(day='M', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#         course2_slot=CourseSlot(day='M', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0))
#   ),
#   Clash(course1_name='ARTS  111  A',
#         course2_name='COMP 111  A',
#         course1_slot=CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#         course2_slot=CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0))
#   ),
#   Clash(course1_name='ARTS  111  A',
#         course2_name='COMP 200 A',
#         course1_slot=CourseSlot(day='M', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#         course2_slot=CourseSlot(day='M', time_start=datetime.time(9, 30), time_end=datetime.time(11, 30))
#   ),
#   Clash(course1_name='ARTS  111  A',
#         course2_name='COMP 200 A',
#         course1_slot=CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#         course2_slot=CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0))
#   ),
#   Clash(course1_name='COMP 111  A',
#         course2_name='COMP 200 A',
#         course1_slot=CourseSlot(day='M', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#         course2_slot=CourseSlot(day='M', time_start=datetime.time(9, 30), time_end=datetime.time(11, 30))
#   ),
#   Clash(course1_name='COMP 111  A',
#         course2_name='COMP 200 A',
#         course1_slot=CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0)),
#         course2_slot=CourseSlot(day='W', time_start=datetime.time(9, 0), time_end=datetime.time(12, 0))
#   )
# ]