2012-05-22 20 views
8

Diciamo che oggi io lavoro da 09:00 alle 18:00 ho 3 appuntamenti:Python - Algoritmo trovare fasce orarie

  • 10:00 - 10:30
  • 12:00 - 13: 00
  • le ore 15.30 - 17:10

ho bisogno di trovare un elenco di intervalli di tempo disponibili da 1 ora nel corso della giornata.
Ecco la lista che dovrei ottenere

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

L'ho già implementato in PHP e ho appena provato a metterlo in python.
Qui è la mia prova:

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 

prova:

>>> 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)) 

Funziona, ma ho semplicemente il porting del codice php.
Quindi non sono sicuro che sia un modo pitonista per farlo.

Puoi mostrarmi dove posso migliorare?

+0

È necessario prendere in considerazione anche l'intervallo di tempo compreso tra 11: 00-12: 00? –

+0

No, dovrebbe solo ottenere i blocchi temporali sequenziali da ogni "area" start –

risposta

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 
+0

Questo è davvero più pythonic :) Proverò ad usarlo –

+0

Sto lavorando bene. Ma forse 'get_slots' dovrebbe anche ordinare gli appuntamenti per prevenire errori –

+0

@PierredeLESPINAY solo per divertimento ho apportato alcune modifiche per ordinare gli slot + provare a verificare se tutti gli appuntamenti possono essere frequentati. L'ordinamento è una buona idea. –

Problemi correlati