10

假设今天我从 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.ini 移植了代码。
所以我不确定这是一种pythonist方式。

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

4

1 回答 1

16
#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
于 2012-05-22T13:07:38.150 回答