Python - 算法查找时隙

时间:2012-05-22 12:40:08

标签: python algorithm datetime

我们今天说我的工作时间是09:00到18:00,我有3个约会:

  • 10:00 - 10:30
  • 12:00 - 13:00
  • 15:30 - 17:10

我需要找到当天1小时的可用时段列表 这是我应该得到的清单

  • 09:00 - 10:00
  • 10:30 - 11:30
  • 13:00 - 14:00
  • 14:00 - 15:00

我已经在php中实现了它,我只是试着把它放在python中 这是我的尝试:

def get_slots(areas, duration):
    slots = []
    for area in areas:
        if area['start'] == area['end']:
            continue
        i = area['start']
        while (i + duration) <= area['end']:
            i += duration
            slots.append({
                'start': (i - duration),
                'end': i,
            })
    return slots

def get_areas(day_start, day_end, appts):
    areas = []
    old_end = day_start
    for appt in appts:
        if appt['start'] > old_end:
            areas.append({
                'start': old_end,
                'end': appt['start'],
            })
        old_end = appt['end']
        if old_end > day_end:
            return areas
    areas.append({
        'start': old_end,
        'end': day_end,
    })
    return areas

测试:

>>> day_start = datetime.datetime(2012, 5, 22, 9)
>>> day_end = datetime.datetime(2012, 5, 22, 18)
>>> appts = [{
    'start': datetime.datetime(2012, 5, 22, 10),
    'end': datetime.datetime(2012, 5, 22, 10, 30),
  },{
    'start': datetime.datetime(2012, 5, 22, 12),
    'end': datetime.datetime(2012, 5, 22, 13),
  },{
    'start': datetime.datetime(2012, 5, 22, 15, 30),
    'end': datetime.datetime(2012, 5, 22, 17, 10),
  },]
>>> duration = datetime.timedelta(hours=1)
>>> pprint.pprint(get_slots(get_areas(day_start, day_end, appts), duration))

它有效,但我只是从php移植代码 所以我不确定这是一种蟒蛇式的方式。

你能告诉我在哪里可以改进吗?

1 个答案:

答案 0 :(得分:10)

#time_slots.py
from datetime import datetime, timedelta

appointments = [(datetime(2012, 5, 22, 10), datetime(2012, 5, 22, 10, 30)),
                (datetime(2012, 5, 22, 12), datetime(2012, 5, 22, 13)),
                (datetime(2012, 5, 22, 15, 30), datetime(2012, 5, 22, 17, 10))]

hours = (datetime(2012, 5, 22, 9), datetime(2012, 5, 22, 18))

def get_slots(hours, appointments, duration=timedelta(hours=1)):
    slots = sorted([(hours[0], hours[0])] + appointments + [(hours[1], hours[1])])
    for start, end in ((slots[i][1], slots[i+1][0]) for i in range(len(slots)-1)):
        assert start <= end, "Cannot attend all appointments"
        while start + duration <= end:
            print "{:%H:%M} - {:%H:%M}".format(start, start + duration)
            start += duration

if __name__ == "__main__":
    get_slots(hours, appointments)


% python time_slots.py 
09:00 - 10:00
10:30 - 11:30
13:00 - 14:00
14:00 - 15:00