Last active
February 14, 2021 06:53
-
-
Save kistters/de0729af4e9175982f1c59496332e466 to your computer and use it in GitHub Desktop.
Time: Split time chunks, check overlap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def at_time(t): | |
return time(hour=int(t.split(':')[0]), minute=int(t.split(':')[1])) | |
def r_time(r): | |
return at_time(r.split('~')[0]), at_time(r.split('~')[1]), | |
def fmt(start, end): | |
return f'{start.strftime("%H:%M")} ~ {end.strftime("%H:%M")}' | |
def splitter(expedient: Tuple[time, time], scheduled_events: List[Tuple[time, time]]): | |
""" expedient | |
|-----------------------| | |
|---inner---| | |
|---left---------|-------right---| | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
""" | |
if not len(scheduled_events): | |
return [expedient] | |
expedient_start, expedient_end = expedient | |
event_start, event_end = scheduled_events[0] | |
# print(f'entrou: {fmt(*expedient)} --- tirar: {[fmt(*event) for event in scheduled_events]}') | |
if not check_overlap(expedient, (event_start, event_end)): | |
print(f'voltou: {fmt(*expedient)}') | |
return [expedient] | |
# inner | |
if expedient_start <= event_start and expedient_end >= event_end: | |
print(f'{"> >" * 2} inner: {expedient_start} < {event_start} and {expedient_end} > {event_end}') | |
expedient_left = splitter((expedient_start, event_start), scheduled_events[1:]) if expedient_start != event_start else [] | |
expedient_right = splitter((event_end, expedient_end), scheduled_events[1:]) if expedient_end != event_end else [] | |
print(f'voltou: {expedient_left} + {expedient_right}') | |
return expedient_left + expedient_right | |
# left | |
if expedient_start > event_start and expedient_end >= event_end: | |
print(f'{"> >" * 2} left: {expedient_start} > {event_start} and {expedient_end} >= {event_end}') | |
return splitter((event_end, expedient_end), scheduled_events[1:]) | |
# right | |
if expedient_start <= event_start and expedient_end < event_end: | |
print(f'{"> >" * 2} right: {expedient_start} <= {event_start} and {expedient_end} < {event_end}') | |
return splitter((expedient_start, event_start), scheduled_events[1:]) | |
print(f'voltou 2: {expedient}') | |
return [] | |
for expedient, events in [ | |
(r_time('01:00 ~ 03:00'), [r_time('04:40 ~ 05:10')]), # nothing | |
(r_time('01:00 ~ 03:00'), [r_time('01:40 ~ 02:10')]), # intersection | |
(r_time('01:00 ~ 03:00'), [r_time('01:00 ~ 01:30')]), # lef | |
(r_time('01:00 ~ 03:00'), [r_time('02:30 ~ 03:00')]), # right | |
(r_time('01:00 ~ 03:00'), [r_time('00:00 ~ 04:00')]), # zero | |
(r_time('01:00 ~ 05:00'), [r_time('00:30 ~ 01:30'), | |
r_time('03:00 ~ 03:30'), | |
r_time('04:30 ~ 05:30')]), | |
(r_time('01:00 ~ 05:00'), []) | |
]: | |
print('') | |
print('*' * 5) | |
print(f'expedient: {fmt(*expedient)}') | |
print(f'events: {[fmt(*r) for r in events]} ') | |
# print(splitter(expedient, events)) | |
print(f'available: {[fmt(*r) for r in splitter(expedient, events)]}') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import datetime, date, time, timedelta | |
from typing import Tuple | |
def _overlap_check(first_interval: Tuple[any, any], second_interval: Tuple[any, any]) ->bool: | |
first_start, first_end = first_interval | |
second_start, second_end = second_interval | |
return first_start <= second_end and second_start <= first_end | |
def time_overlap(first_interval: Tuple[time, time], second_interval: Tuple[time, time]) -> bool: | |
return _overlap_check(first_interval, second_interval) | |
def date_overlap(first_interval: Tuple[date, date], second_interval: Tuple[date, date]) -> bool: | |
return _overlap_check(first_interval, second_interval) | |
def increase_time_in(start_at: time, hours: float = 0, minutes: float = 0) -> time: | |
dt = datetime.combine(date.today(), start_at) + timedelta(**dict(hours=hours, minutes=minutes)) | |
return dt.time() | |
def to_datetime(time_at: time): | |
return datetime.combine(date.today(), time_at) | |
def divide_time_interval_in(start_at: time, end_at: time, hours: float = 0, minutes: float = 0, | |
coffee_break: float = 0) -> list: | |
def _next_start(dt: datetime) -> datetime: | |
return to_datetime(increase_time_in(dt.time(), hours=hours, minutes=minutes)) | |
dt_start = to_datetime(start_at) | |
dt_end = to_datetime(end_at) | |
result = [] | |
while _next_start(dt_start) <= dt_end: | |
result.append((dt_start.time(), _next_start(dt_start).time())) | |
dt_start = _next_start(dt_start) + timedelta(minutes=coffee_break) | |
return result | |
# | |
# def get_time(t_string) -> time: | |
# """ get_time('20:30') -> time """ | |
# hour, minute = t_string.split(':') | |
# return time(hour=int(hour), minute=int(minute)) | |
def get_time(t): return time(hour=int(t.split(':')[0]), minute=int(t.split(':')[1])) | |
def get_date(t): return date(day=int(t.split('-')[0]), month=int(t.split('-')[1]), year=int(t.split('-')[2])) | |
if __name__ == '__main__': | |
assert get_time('12:55') == increase_time_in(get_time('10:30'), hours=2, minutes=25) | |
assert 6 == len(divide_time_interval_in(get_time('09:00'), get_time('15:20'), hours=1)) | |
assert 5 == len(divide_time_interval_in(get_time('09:00'), get_time('15:20'), hours=1, coffee_break=20)) | |
assert 4 == len(divide_time_interval_in(get_time('09:00'), get_time('15:20'), hours=1, coffee_break=40)) | |
assert 3 == len(divide_time_interval_in(get_time('09:00'), get_time('15:20'), hours=1, coffee_break=80)) | |
time_interval_a = (get_time('10:30'), get_time('12:30')) | |
time_interval_b = (get_time('12:30'), get_time('14:30')) | |
time_interval_c = (get_time('12:31'), get_time('14:30')) | |
assert time_overlap(time_interval_a, time_interval_b) | |
assert not time_overlap(time_interval_a, time_interval_c) | |
date_interval_a = (get_date('01-01-2000'), get_date('05-01-2000')) | |
date_interval_b = (get_date('03-01-2000'), get_date('10-01-2000')) | |
date_interval_c = (get_date('05-01-2000'), get_date('10-01-2000')) | |
date_interval_d = (get_date('06-01-2000'), get_date('10-01-2000')) | |
assert date_overlap(date_interval_a, date_interval_b) | |
assert date_overlap(date_interval_a, date_interval_c) | |
assert not date_overlap(date_interval_a, date_interval_d) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment