Reputation: 205
I have an interesting problem to solve. I need to divide a given time range into chunks of let's say 1 hour and there could be a constant break as well.
So, the scenario is that let's say a company has working hours from 9 AM to 5 PM for a given day, and they want to divide their work slots into slots of 1 hour. Also, there is usually a break in every working company hours and let's say that break is from 12:00 PM to 1:00 PM. That is the constant break. Another restriction is that after every 1-hour work slot, there is a break of 15 mins. So, keeping in view all this information I need to decide how many slots can be made in a given day.
Let's understand this with an example:
Working hours: 9 AM to 5 PM
Constant break: 12:00 PM to 1:00 PM
Max duration of one slot: 1-hour
Break between each slot: 15 mins
The resulting slots should be:
Slot#1: 9 AM to 10 AM
Slot#2: 10:15 AM to 11:15 AM
Slot#3: 1:00 PM to 2:00 PM
Slot#4: 2:15 PM to 3:15 PM
Slot#5: 3:30 PM to 4:30 PM
Just to make a problem bit easier, along with the time we can consider the date as of today.
I am trying to solve the above problem using the native datetime and calendar library of python but could not do so. Can someone help me solve this?
Thanks!
Upvotes: 1
Views: 1206
Reputation: 1137
Here is my solution:
First, i've created a new object called Day
so i can easily do math with hour and minutes:
from functools import total_ordering
@total_ordering
class Day():
def __init__(self, h=0, m=0):
self.h = (h + m // 60) % 24
self.m = m % 60
def __add__(self, other):
return Day(self.h + other.h, self.m + other.m)
def __iadd__(self, other):
return self.__add__(other)
def __sub__(self, other):
return Day(self.h - other.h, self.m - other.m)
def __isub__(self, other):
return self.__sub__(other)
def __repr__(self):
return f'h: {self.h}, m:{self.m}'
def __str__(self):
return self.__repr__()
def __eq__(self, other):
return self.h == other.h and self.m == other.m
def __gt__(self, other):
return self.h > other.h or (self.h == other.h and self.m > other.m)
def __copy__(self):
return Day(self.h, self.m)
def copy(self):
return self.__copy__()
Then i've saved the data in your example in the form of Day
objects
start_day = Day(9) # starting working day
end_day = Day(17) # end working day
start_break = Day(12)
end_break = Day(13)
slot_duration = Day(1)
interbreak_duration = Day(0, 15) # break between slots
Now with this setup it should be easier to write an algorithm to do you calculations.
Here is a draft of my solution but it doesn't work that well, i'll recommend you to write a new algorithm tailored to your desired output
def calculate(start_day, end_day, start_break, end_break, slot_duration, interbreak_duration):
now = start_day.copy()
break_done = False # mid day break
interbreak_done = True # break between slots
while True:
print(now, end=' ')
if interbreak_done:
print('\tslot', end='')
else:
print('\tbreak', end='')
if break_done:
if interbreak_done:
now += slot_duration
if now == end_day:
print(now)
break
if now >= end_day:
print('\r', end='')
break
interbreak_done = False
else:
now += interbreak_duration
if now == end_day:
print(now)
break
if now > end_day:
print('\r', end='')
break
interbreak_done = True
else:
if interbreak_done:
now += slot_duration
interbreak_done = False
if now == start_break:
print('slot')
if now >= start_break:
print('\r', end='')
now = end_break
interbreak_done = True
break_done = True
continue
else:
now += interbreak_duration
if now >= start_break:
now = end_break
break_done = True
interbreak_done = True
print('\t', now)
the output is:
calculate(start_day, end_day, start_break, end_break, slot_duration, interbreak_duration)
h: 9, m:0 slot h: 10, m:0
h: 10, m:0 break h: 10, m:15
h: 10, m:15 slot h: 11, m:15
h: 11, m:15 break h: 11, m:30
h: 13, m:0 slot h: 14, m:0
h: 14, m:0 break h: 14, m:15
h: 14, m:15 slot h: 15, m:15
h: 15, m:15 break h: 15, m:30
h: 15, m:30 slot h: 16, m:30
h: 16, m:30 break h: 16, m:45
h: 16, m:45 slot
it's a little buggy but it should help you to get started
Upvotes: 1