def test_ivl_overlap_within(self): clnd = tb_12_days() ivl = Interval(clnd, (2, 8)) other = Interval(clnd, (3, 7)) overlap = ivl.overlap(other) assert overlap._loc == (3, 7) assert len(overlap) == 5
def test_ivl_whatportion_other_is_outside_ivl(self): clnd = tb_12_days() other = Interval(clnd, (2, 8)) ivl = Interval(clnd, (9, 10)) assert ivl.what_portion_of(other) == 0 assert ivl.what_portion_of(other, duty='off') == 0 assert ivl.what_portion_of(other, duty='any') == 0
def test_ivl_overlap_total(self): clnd = tb_12_days() ivl = Interval(clnd, (2, 8)) other = Interval(clnd, (0, 12)) overlap = ivl.overlap(other) assert overlap._loc == (2, 8) assert len(overlap) == 7
def test_ivl_compound_total_dur_other_schedule2(self): clnd = tb_10_8_6_hours() other_sdl = clnd.add_schedule('other', lambda x: x > -1) ivl = Interval(clnd, (2, 8), schedule=other_sdl) assert ivl.total_duration() == 58 assert ivl.total_duration(duty='off') == 0 assert ivl.total_duration(duty='any') == 58
def test_ivl_compound_worktime_in_labels_other_schedule(self): clnd = tb_10_8_6_hours(worktime_source='labels') other_sdl = clnd.add_schedule('other', lambda x: x > 1) ivl = Interval(clnd, (2, 8)) assert ivl.worktime(schedule=other_sdl) == 0 assert ivl.worktime(duty='off', schedule=other_sdl) == 4 assert ivl.worktime(duty='any', schedule=other_sdl) == 4
def test_ivl_whatportion_other_is_the_same(self): clnd = tb_12_days() other = Interval(clnd, (2, 8)) ivl = Interval(clnd, (2, 8)) assert ivl.what_portion_of(other) == 1 assert ivl.what_portion_of(other, duty='off') == 1 assert ivl.what_portion_of(other, duty='any') == 1
def test_interval_direct_schedules(self): clnd = tb_12_days() my_schedule = clnd.add_schedule('my_schedule', lambda x: True) ivl = Interval(clnd, (2, 8)) assert ivl.schedule.name == clnd.default_schedule.name ivl = Interval(clnd, (2, 8), my_schedule) assert ivl.schedule.name == 'my_schedule'
def test_ivl_overlap_mul(self): clnd = tb_12_days() ivl = Interval(clnd, (2, 8)) other = Interval(clnd, (6, 12)) overlap = ivl * other assert overlap._loc == (6, 8) assert len(overlap) == 3
def test_ivl_count_periods_avoiding_long_ws(self): clnd = clnd_variable_mins() ivl = Interval(clnd, (1, 3)) # ivl contains ws 1, 2, 3 # ws 1, 2 fall into hour of 03:00; ws 3, 4 fall into hour of 04:00 assert ivl.count_periods('H') == 1.0 # (1/1 + 0/1) assert ivl.count_periods('H', duty='off') == 2.0 assert ivl.count_periods('H', duty='any') == 1.5 # (2/2 + 1/2)
def test_ivl_to_dataframe(self): clnd = tb_12_days() clnd.add_schedule('my_schedule', lambda x: True) ivl = Interval(clnd, (2, 8)) clnd_df = clnd.to_dataframe(2, 8) ivl_df = ivl.to_dataframe() assert len(ivl_df) == len(ivl) == len(clnd_df) assert list(ivl_df.columns) == list(clnd_df.columns) assert 'my_schedule' in list(ivl_df.columns)
def test_interval_find_my_bounds_no_off_duty_in_tb(self): clnd = tb.Timeboard(base_unit_freq='D', start='31 Dec 2016', end='12 Jan 2017', layout=[1]) ivl = Interval(clnd, (1, 2), clnd.default_schedule) _, duty_loc = ivl._get_duty_idx('on', ivl.schedule) assert duty_loc == (1, 2) _, duty_loc = ivl._get_duty_idx('off', ivl.schedule) assert duty_loc == (None, None)
def test_ivl_count_periods_long_ws_caught_by_period(self): clnd = clnd_variable_mins('end') ivl = Interval(clnd, (1, 3)) # ivl contains ws 1, 2, 3 # hour of 03:00 catches ws 0 as ws ref time is end time # ws 0 is 3 hours long but it is NOT in the interval so we don't raise # ws 0, 1 fall into hour of 03:00; ws 2, 3 fall into hour of 04:00 assert ivl.count_periods('H') == 1.0 # (0/0 + 1/1) assert ivl.count_periods('H', duty='off') == 1.5 # (1/2 + 1/1) assert ivl.count_periods('H', duty='any') == 1.5 # (1/2 + 2/2)
def test_interval_direct_OOB_locs(self): clnd = tb_12_days() with pytest.raises(OutOfBoundsError): Interval(clnd, (-1, 2), clnd.default_schedule) with pytest.raises(OutOfBoundsError): Interval(clnd, (8, 13), clnd.default_schedule) with pytest.raises(OutOfBoundsError): Interval(clnd, (-1, 13), clnd.default_schedule) with pytest.raises(OutOfBoundsError): Interval(clnd, (13, 25), clnd.default_schedule)
def test_void_ivl_to_dataframe(self): clnd = tb_12_days() clnd.add_schedule('my_schedule', lambda x: True) ivl = Interval(clnd, (2, 8)) void_ivl = _VoidInterval(clnd, (8, 2)) ivl_df_columns = list(ivl.to_dataframe().columns) void_ivl_df = void_ivl.to_dataframe() assert void_ivl_df.empty assert list(void_ivl_df.columns) == ivl_df_columns assert 'my_schedule' in list(void_ivl_df.columns)
def test_interval_nth_single(self): clnd = tb_12_days() for loc, duty in ((0, 'off'), (3, 'any'), (4, 'on'), (7, 'any'), (12, 'off')): ivl = Interval(clnd, (loc, loc), clnd.default_schedule) wsf = ivl.first(duty=duty) wsl = ivl.last(duty=duty) ws2 = ivl.nth(0, duty=duty) assert isinstance(wsf, Workshift) assert isinstance(wsl, Workshift) assert isinstance(ws2, Workshift) assert wsf._loc == loc assert wsl._loc == loc assert ws2._loc == loc
def test_interval_direct_bad_args(self): clnd = tb_12_days() with pytest.raises(AttributeError): Interval('not a clnd', (2, 8), clnd.default_schedule) with pytest.raises(TypeError): Interval(clnd, (2, 8.5), clnd.default_schedule) with pytest.raises(TypeError): Interval(clnd, (2, '08 Jan 2017'), clnd.default_schedule) with pytest.raises(IndexError): Interval(clnd, (2, ), clnd.default_schedule) with pytest.raises(TypeError): Interval(clnd, 'not a tuple', clnd.default_schedule) # 'on_duty' is _Schedule.name but _Schedule is expected with pytest.raises(TypeError): _VoidInterval(clnd, (8, 2), 'on_duty')
def test_void_ivl_overlap(self): clnd = tb_12_days() my_schedule = clnd.add_schedule('my_schedule', lambda x: True) void_ivl = _VoidInterval(clnd, (8, 2)) ivl = Interval(clnd, (2, 8)) overlap = void_ivl.overlap(ivl, schedule=my_schedule) assert isinstance(overlap, _VoidInterval) assert overlap._loc == (8, 2) assert len(overlap) == 0 assert overlap.schedule.name == 'my_schedule' overlap = void_ivl * ivl assert overlap._loc == (8, 2) assert len(overlap) == 0 assert overlap.schedule.name == clnd.default_schedule.name overlap = void_ivl.overlap(void_ivl) assert overlap._loc == (8, 2) assert len(overlap) == 0 assert overlap.schedule.name == clnd.default_schedule.name void_ivl2 = _VoidInterval(clnd, (1, 0), schedule=my_schedule) overlap = void_ivl2.overlap(void_ivl) assert isinstance(overlap, _VoidInterval) assert overlap._loc == (1, 0) assert len(overlap) == 0 assert overlap.schedule.name == 'my_schedule'
def test_void_ivl_whatportion(self): clnd = tb_12_days() void_ivl = _VoidInterval(clnd, (8, 2)) ivl = Interval(clnd, (2, 8)) assert void_ivl.what_portion_of(ivl) == 0 assert void_ivl / ivl == 0 assert void_ivl.what_portion_of(void_ivl) == 0
def test_interval_nth_OOB(self): clnd = tb_12_days() ivl = Interval(clnd, (2, 8), clnd.default_schedule) with pytest.raises(OutOfBoundsError): ivl.nth(2) with pytest.raises(OutOfBoundsError): ivl.nth(5, duty='off') with pytest.raises(OutOfBoundsError): ivl.nth(7, duty='any')
def test_interval_nth_no_off_duty(self): clnd = tb_12_days() ivl = Interval(clnd, (4, 4), clnd.default_schedule) with pytest.raises(OutOfBoundsError): ivl.first(duty='off') with pytest.raises(OutOfBoundsError): ivl.last(duty='off') with pytest.raises(OutOfBoundsError): ivl.nth(0, duty='off')
def test_ivl_whatportion_change_schedule(self): clnd = tb_12_days() sdl = clnd.add_schedule('sdl', lambda label: label > 1) sdl_other = clnd.add_schedule('sdl_other', lambda label: label > 2) other = Interval(clnd, (7, 10), schedule=sdl_other) ivl = Interval(clnd, (10, 10)) assert ivl.what_portion_of(other) == 1.0 / 2 assert ivl.what_portion_of(other, schedule=sdl) == 1 ivl = Interval(clnd, (10, 10), schedule=sdl) assert ivl.what_portion_of(other) == 1 assert ivl.what_portion_of(other, schedule=clnd.default_schedule) == 1.0 / 2
def test_interval_direct_same_locs(self): clnd = tb_12_days() ivl = Interval(clnd, (2, 2), clnd.default_schedule) assert ivl.start_time == datetime.datetime(2017, 1, 2, 0, 0, 0) assert ivl.end_time > datetime.datetime(2017, 1, 2, 23, 59, 59) assert ivl.end_time < datetime.datetime(2017, 1, 3, 0, 0, 0) assert ivl._loc == (2, 2) assert len(ivl) == 1
def test_interval_direct_mixed_args(self): clnd = tb_12_days() ivl = Interval(clnd, (2, clnd('08 Jan 2017')), clnd.default_schedule) assert ivl.start_time == datetime.datetime(2017, 1, 2, 0, 0, 0) assert ivl.end_time > datetime.datetime(2017, 1, 8, 23, 59, 59) assert ivl.end_time < datetime.datetime(2017, 1, 9, 0, 0, 0) assert ivl._loc == (2, 8) assert len(ivl) == 7
def test_ivl_count_periods_shorter_than_ws_at_start(self): clnd = clnd_variable_mins() ivl = Interval(clnd, (0, 3)) # 3H long ws #0 is first in ivl with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H') with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H', duty='off') with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H', duty='any')
def test_ivl_count_periods_shorter_than_ws_at_mid(self): clnd = clnd_variable_mins() ivl = Interval(clnd, (5, 9)) # 3H long ws #7 is in the middle of ivl with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H') with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H', duty='off') with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H', duty='any')
def test_ivl_count_periods_shorter_than_ws_at_end(self): clnd = clnd_variable_mins() ivl = Interval(clnd, (12, 14)) # 3H long ws #14 is the last in ivl with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H') with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H', duty='off') with pytest.raises(UnacceptablePeriodError): ivl.count_periods('H', duty='any')
def test_ivl_workshift_generator(self): clnd = tb_12_days() ivl = Interval(clnd, (1, 4)) ws_locs = [] for ws in ivl.workshifts(): ws_locs.append(ws._loc) assert ws_locs == [1, 4] ws_locs = [] for ws in ivl.workshifts(duty='off'): ws_locs.append(ws._loc) assert ws_locs == [2, 3] ws_locs = [] for ws in ivl.workshifts(duty='any'): ws_locs.append(ws._loc) assert ws_locs == [1, 2, 3, 4]
def test_interval_direct_with_ws(self): clnd = tb_12_days() ivl = Interval(clnd, (Workshift(clnd, 2), Workshift(clnd, 8)), clnd.default_schedule) assert ivl.start_time == datetime.datetime(2017, 1, 2, 0, 0, 0) assert ivl.end_time > datetime.datetime(2017, 1, 8, 23, 59, 59) assert ivl.end_time < datetime.datetime(2017, 1, 9, 0, 0, 0) assert ivl._loc == (2, 8) assert len(ivl) == 7
def test_ivl_compound_count_periods_OOB_floating(self): clnd = tb_10_8_6_hours() ivl = Interval(clnd, (14, 15)) assert ivl.count_periods('D', duty='off') == 1.0 / 2.0 clnd = tb_10_8_6_hours(workshift_ref='end') ivl = Interval(clnd, (14, 15)) with pytest.raises(PartialOutOfBoundsError): ivl.count_periods('D', duty='off')
def test_workshift_generator_change_schedule(self): clnd = tb_12_days() all_on = clnd.add_schedule('all_on', lambda x: True) ivl = Interval(clnd, (1, 4)) ws_locs = [] ws_sdl_is_ok = [] for ws in ivl.workshifts(): ws_locs.append(ws._loc) ws_sdl_is_ok.append(ws.schedule.name == clnd.default_schedule.name) assert ws_locs == [1, 4] assert all(ws_sdl_is_ok) ws_locs = [] ws_sdl_is_ok = [] for ws in ivl.workshifts(schedule=all_on): ws_locs.append(ws._loc) ws_sdl_is_ok.append(ws.schedule.name == all_on.name) assert ws_locs == [1, 2, 3, 4] assert all(ws_sdl_is_ok)