Beispiel #1
0
def get_free_time(total_range, schedule):
    schedule.sort(key=lambda x: x.lower_bound)
    free_timeslots = [
        Timeslot(total_range.lower_bound, schedule[0].lower_bound)
    ]
    for i in range(len(schedule[:-1])):
        free_timeslots.append(
            Timeslot(schedule[i].upper_bound, schedule[i + 1].lower_bound))
    free_timeslots.append(
        Timeslot(schedule[-1].upper_bound, total_range.upper_bound))
    return [
        timeslot for timeslot in free_timeslots if validate_timeslot(timeslot)
    ]
Beispiel #2
0
def union_no_overlap(events1: List[Event], events2: List[Event]) -> List[Event]:
    """Merges two eventlists and removes overlap, the first eventlist will have precedence

    Example:
      events1  | xxx    xx     xxx     |
      events1  |  ----     ------   -- |
      result   | xxx--  xx ----xxx  -- |
    """
    events1 = deepcopy(events1)
    events2 = deepcopy(events2)

    # I looked a lot at aw_transform.union when I wrote this
    events_union = []
    e1_i = 0
    e2_i = 0
    while e1_i < len(events1) and e2_i < len(events2):
        e1 = events1[e1_i]
        e2 = events2[e2_i]
        e1_p = Timeslot(e1.timestamp, e1.timestamp + e1.duration)
        e2_p = Timeslot(e2.timestamp, e2.timestamp + e2.duration)

        if e1_p.intersects(e2_p):
            if e1.timestamp <= e2.timestamp:
                events_union.append(e1)
                e1_i += 1

                # If e2 continues after e1, we need to split up the event so we only get the part that comes after
                _, e2_next = _split_event(e2, e1.timestamp + e1.duration)
                if e2_next:
                    events2[e2_i] = e2_next
                else:
                    e2_i += 1
            else:
                e2_next, e2_next2 = _split_event(e2, e1.timestamp)
                events_union.append(e2_next)
                e2_i += 1
                if e2_next2:
                    events2.insert(e2_i, e2_next2)
        else:
            if e1.timestamp <= e2.timestamp:
                events_union.append(e1)
                e1_i += 1
            else:
                events_union.append(e2)
                e2_i += 1
    events_union += events1[e1_i:]
    events_union += events2[e2_i:]
    return events_union
Beispiel #3
0
    def test_course_can_take(self):
        ts1 = Timeslot('FA12', {
            'M': ['09:00', '11:00'],
            'R': ['09:00', '11:00']
        })
        ts2 = Timeslot('FA13', {
            'M': ['09:00', '11:00'],
            'R': ['09:00', '11:00']
        })
        ts3 = Timeslot('FA14', {
            'M': ['09:00', '11:00'],
            'R': ['09:00', '11:00']
        })

        c1 = Course("CS101", ts1)
        c2 = Course("CS201", ts2, ["CS101"])
        c3 = Course("CS101", ts3)

        self.assertFalse(c2.can_take([]))

        self.assertTrue(c2.can_take([c1]))

        self.assertFalse(c2.can_take([c3]))
Beispiel #4
0
def parse_time(days, start_time, end_time):
    # Convert times from 12 hr to 24 hr
    start_time = convert_time(start_time)
    end_time = convert_time(end_time)

    # Read in the times for the course
    d = {}
    if 'M' in days:
        d['M'] = [start_time, end_time]
    if 'T' in days:
        d['T'] = [start_time, end_time]
    if 'W' in days:
        d['W'] = [start_time, end_time]
    if 'R' in days:
        d['R'] = [start_time, end_time]
    if 'F' in days:
        d['F'] = [start_time, end_time]

    # Create timeslot for the course
    # Hard-code semester (should be read in somehow)
    return Timeslot("FA14", d)
Beispiel #5
0
def test_contains():
    now = datetime.now()

    tp1 = Timeslot(now - timedelta(hours=1), now + timedelta(hours=1))
    tp2 = Timeslot(now, now + timedelta(hours=1))
    assert tp1.contains(tp2)
    assert not tp2.contains(tp1)

    # if datetime is contained in period
    assert now in tp1
    assert now in tp2

    # __contains__  operator overloading
    assert tp2 in tp1
    assert tp1 not in tp2

    with pytest.raises(TypeError):
        assert 0 in tp1
Beispiel #6
0
def parse_input_range(input_range):
    return Timeslot(input_range.split(".")[0], input_range.split(".")[1])
Beispiel #7
0
def parse_input_array(input_array):
    return [Timeslot(x, y) for x, y in [val.split(".") for val in input_array.split(",")]]
Beispiel #8
0
def test_union():
    now = datetime.now()

    # adjacent but not overlapping
    tp1 = Timeslot(now - timedelta(hours=1), now)
    tp2 = Timeslot(now, now + timedelta(hours=1))
    tp_union = tp1.union(tp2)
    assert tp1 in tp_union
    assert tp2 in tp_union

    # union with self
    tp_union = tp1.union(tp1)
    assert tp1 == tp_union

    # overlapping
    tp1 = Timeslot(now - timedelta(hours=1), now + timedelta(minutes=30))
    tp2 = Timeslot(now, now + timedelta(hours=1))
    tp_union = tp1.union(tp2)
    assert tp1 in tp_union
    assert tp2 in tp_union

    # tp2 contained in tp1
    tp1 = Timeslot(now - timedelta(minutes=30), now + timedelta(minutes=30))
    tp2 = Timeslot(now, now + timedelta(minutes=10))
    tp_union = tp1.union(tp2)
    assert tp1 in tp_union
    assert tp2 in tp_union
    assert tp1 == tp_union
Beispiel #9
0
def test_adjacent():
    now = datetime.now()
    tp1 = Timeslot(now - timedelta(hours=1), now)
    tp2 = Timeslot(now, now + timedelta(hours=1))
    assert tp1.adjacent(tp2)
    assert tp2.adjacent(tp1)
Beispiel #10
0
def test_intersection_start():
    now = datetime.now()
    tp1 = Timeslot(now, now + timedelta(hours=1))
    tp2 = Timeslot(now - timedelta(minutes=10), now + timedelta(minutes=50))
    assert tp1.intersection(tp2).duration == timedelta(minutes=50)
    assert tp2.intersection(tp1).duration == timedelta(minutes=50)
Beispiel #11
0
def test_overlaps():
    now = datetime.now()
    # If periods are just "touching", they should not count as overlap
    tp1 = Timeslot(now - timedelta(hours=1), now)
    tp2 = Timeslot(now, now + timedelta(hours=1))
    assert not tp1.overlaps(tp2)
    assert not tp2.overlaps(tp1)

    # If outer contains inner, or vice versa, they overlap
    tp1 = Timeslot(now, now + timedelta(hours=1))
    tp2 = Timeslot(now - timedelta(hours=1), now + timedelta(hours=2))
    assert tp1.overlaps(tp2)
    assert tp2.overlaps(tp1)

    # If start/end is contained in the other event, they overlap
    tp1 = Timeslot(now, now + timedelta(hours=2))
    tp2 = Timeslot(now - timedelta(hours=1), now + timedelta(hours=1))
    assert tp1.overlaps(tp2)
    assert tp2.overlaps(tp1)
Beispiel #12
0
def test_intersection_none():
    now = datetime.now()
    tp1 = Timeslot(now, now + timedelta(hours=1))
    tp2 = Timeslot(now - timedelta(hours=1), now)
    assert tp1.intersection(tp2) is None
    assert tp2.intersection(tp1) is None
def _get_event_period(event: Event) -> Timeslot:
    start = event.timestamp
    end = start + event.duration
    return Timeslot(start, end)
Beispiel #14
0
 def create_timeslots(self):
     return [
         Timeslot(timeslot_id=slot) for slot in range(self.no_timeslots)
     ]