The World’s Largest Online Community for Developers

'; python - Data structure for working out free time given used time - LavOzs.Com

Preamble: I've got a car park with a hundred spaces. I store reservations as free-form start and end times against specified spaces. We currently let people query the car park for a specific time and can easily tell them if there's a free space. But I now have a requirement to advertise how many free spaces there are for 1 hour slots from 7-7, for a span of 5 days. Using the existing query would mean I needed to do 60 queries which is too slow to do interactively and seems just too boggy to do non-interactively.

So I'm looking for a way to map the time between bookings, and then coerce that into slot availability which I can store separately. This process might be a bit boggy in itself but it might also make querying the database for specific availability somewhat faster.

What I want to do is define a day and then "subtract" bookings for that day and be left with a list of available time ranges around those bookings, that I can then go onto coerce into hour-long slots.

I'm halfway through doing this myself by starting from a given time, ranging up to the first booking, skipping to the end, and repeating until I hit the end of the slot but it's pretty dull stuff and I'm struggling to believe this hasn't been done before. I'm using Python but I'm happy to port. Something like...

today = Day(start=datetime.time(7), end=datetime.time(19))
# [(datetime.time(7), datetime.time(19))]

day.subtract(datetime.time(12), datetime.time(13))
# [(datetime.time(7), datetime.time(12)), (datetime.time(13), datetime.time(19))]

I realise I'm probably drifting into a level of specificity where it might only benefit me, but this idea of ranging and splitting time is where I need help. Any ideas?

Can you create all the hour slots and remove the used ones?

def create_hour_slots(start, end):
    return list(zip(range(start, end), range(start+1, end+1)))

today = create_hour_slots(7, 19)
[(7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (12, 13), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19)]

def remove_range(start_subtract, end_subtract, day_range):
    slots_to_remove = create_hour_slots(start_subtract, end_subtract)
    availability = [r in day_range for r in slots_to_remove]
    if not all(availability):
        unavailable = [r for r in slots_to_remove if r not in day_range]
        print("Unavailable slots: {}".format(unavailable))
        return False
    remaining_range = [s for s in day_range if s not in slots_to_remove]
    return remaining_range

remove_noon_slot = remove_range(12, 13, today)
[(7, 8), (8, 9), (9, 10), (10, 11), (11, 12), (13, 14), (14, 15), (15, 16), (16, 17), (17, 18), (18, 19)]
remove_unavailable_slot = remove_range(6, 8, today)
Unavailable slots: [(6, 7)]

If you only want to know "how many free spaces there are for 1 hour slots from 7-7, for a span of 5 days", then my proposition is:

  • the number of 1-hour-slot-spaces is 12*5*100=6000. Set some counter to 6000
  • every time a new reservation is made (assuming 1-hour
    reservations, starting at full hours only) decrement a counter
  • on every full hour run a query to check how many reservations ended and increment counter

At every time you can do one query to check how many free spaces you have.

Tree data structure in C#
What are the lesser known but useful data structures?
Find time occurence and duration in certain time range
“Large data” work flows using pandas
HALF-an-hour and One-hour time slot booking based on selection- c# and sql
Taking value from Timefield in a model and Using datetime operations on it.
How to find out all missing time slot(s) on a day