Reputation: 391
I have a dictionary whose key is date object and value is a list of time objects.
timeSlots = {
datetime.date(2014, 12, 11): [
datetime.time(8, 0),
datetime.time(8, 30),
datetime.time(9, 0),
datetime.time(9, 30),
datetime.time(12, 0),
datetime.time(12, 30),
datetime.time(13, 0),
datetime.time(13, 30),
datetime.time(14, 0),
datetime.time(14, 30)
],
datetime.date(2014, 12, 12): [
datetime.time(8, 0),
datetime.time(8, 30),
datetime.time(9, 0),
datetime.time(9, 30),
datetime.time(12, 0),
datetime.time(12, 30),
datetime.time(13, 0),
datetime.time(13, 30),
datetime.time(14, 0),
datetime.time(14, 30)
]
}
Input : 30 minutes Output : {datetime.date(2014, 12, 11): [90, 150], datetime.date(2014, 12, 12): [90, 150]}
How it is calculated :
assume my interval is 30 minutes as provided in input.
Take first list of time slot. Start seeing that difference between 8:00:00 and 8:30:00 is 30 minutes which is same as input received, so again go to next element of list which is 9:00:00(same case 8:30:00 and 9:00:00 has 30 min difference) and so on.
Stop at 12:00:00 as difference is more than 30 min of previous element in list which is 9:30:00.
Calculate difference between 8:00:00 and 9:30:00 and return in minutes which is 90 minutes.
Continue the process and you will get the output.
Hope I am clear.
What is the best way to do this ?
TIA
Upvotes: 2
Views: 2258
Reputation: 31339
This function returns a generator that splits on your wanted indices (longer than interval
) for each key in your dict
.
import datetime
timeSlots = {
datetime.date(2014, 12, 11): [
datetime.time(8, 0),
datetime.time(8, 30),
datetime.time(9, 0),
datetime.time(9, 30),
datetime.time(12, 0),
datetime.time(12, 30),
datetime.time(13, 0),
datetime.time(13, 30),
datetime.time(14, 0),
datetime.time(14, 30)]
,datetime.date(2 interval = 30
def get_consec(time_slots):
for key, value in time_slots.iteritems():
print "date: %s" % key
last_index = 0
diffs = zip(value[:-1], value[1:])
print "diffs: %s" % diffs
index = None
for index in range(len(diffs)):
start = diffs[index][0]
end = diffs[index][1]
if (end.hour * 60 + end.minute) - (start.hour * 60 + start.minute) > interval:
print "splitting: %s" % str((start ,end))
yield value[last_index: index+1]
last_index = index + 1
if index and index != last_index:
yield value[last_index: index + 2]
else:
yield value
print list(get_consec(timeSlots))014, 12, 12): [
datetime.time(8, 0),
datetime.time(8, 30),
datetime.time(9, 0),
datetime.time(9, 30),
datetime.time(12, 0),
datetime.time(12, 30),
datetime.time(13, 0),
datetime.time(13, 30),
datetime.time(14, 0),
datetime.time(14, 30)
]
,datetime.date(2014, 12, 13): [
datetime.time(8, 0),
]
,datetime.date(2014, 12, 14): [
datetime.time(8, 0),
datetime.time(8, 30),
]
,datetime.date(2014, 12, 15): [
datetime.time(8, 0),
datetime.time(8, 40),
]
}
interval = 30
def get_consec(time_slots):
for key, value in time_slots.iteritems():
print "date: %s" % key
last_index = 0
diffs = zip(value[:-1], value[1:])
print "diffs: %s" % diffs
index = None
for index in range(len(diffs)):
start = diffs[index][0]
end = diffs[index][1]
if (end.hour * 60 + end.minute) - (start.hour * 60 + start.minute) > interval:
print "splitting: %s" % str((start ,end))
yield (key, value[last_index: index+1], )
last_index = index + 1
if index is not None:
print "finished with last: %d, index: %d" % (last_index, index)
yield (key, value[last_index: index+2], )
else:
print "no iteration for %s" % value
yield (key, value, )
print '\n'.join(map(str, list(get_consec(timeSlots))))
Code works for some cases, make sure to add more!
Upvotes: 0
Reputation: 371
Ok, I'll be the first to admit that perhaps this is not the most pythonic way to do this, but here's my solution:
import datetime
def get_difference(d, times):
first = datetime.datetime.combine(d, times[0])
second = datetime.datetime.combine(d, times[1])
return second - first
def solution(ts, interval):
results = []
outputDict = {}
acc = datetime.timedelta()
for key in ts:
for item in range(len(ts[k])-1):
delta = get_difference(key, ts[key][item:item+2])
if delta > interval:
results.append(acc)
acc = datetime.timedelta()
else:
acc += delta
results.append(acc)
acc = datetime.timedelta()
outputDict[key] = [result.total_seconds() / 60 for result in results]
results = []
return outputDict
It gives the exact output you described:
>>> solution(timeSlots, datetime.timedelta(0, 1800)) #Interval needs to be in seconds
{datetime.date(2014, 12, 12): [90.0, 150.0], datetime.date(2014, 12, 11): [90.0, 150.0]}
Upvotes: 1