2012-05-22 4 views
8

Digamos que hoy trabajo desde 09:00 a 18:00, tengo 3 citas:Python - Algoritmo de encontrar espacios de tiempo

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

necesito encontrar una lista de intervalos de tiempo disponibles de 1 hora en el día.
Aquí está la lista que debo conseguir

  • 09:00 -
  • las 10:00 de
  • 10:30-once y media
  • 13:00-14:00
  • 14:00 - 15:00

Ya lo he implementado en php y acabo de intentar ponerlo en python.
Aquí es mi intento:

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 

prueba:

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

Funciona, pero simplemente portado el código de PHP.
Así que no estoy seguro de que sea una forma de pythonist para hacerlo.

¿Me puede mostrar dónde puedo mejorar?

+0

¿Debe considerarse también el intervalo de tiempo de 11: 00-12: 00? –

+0

No, solo debería obtener los bloques de tiempo secuenciales de cada "área" iniciar –

Respuesta

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

Eso es de hecho más pitónico :) Trataré de usarlo –

+0

Funciona bien. Pero tal vez 'get_slots' también debe ordenar las citas para evitar errores –

+0

@PierredeLESPINAY solo por diversión. Hice algunos cambios para ordenar las ranuras + trato de verificar si se pueden atender todas las citas. Ordenar es una buena idea –

Cuestiones relacionadas