Execute efficient interval operations in Python.
(Currently in active development. Leave a ⭐️ on GitHub if you're interested how this develops!)
Inspired by a discussion and initial implementation in a professional project and a library I've been using in one of my previous jobs, pyintervals is born.
Intervals pop-up frequently in programming, specifically in domains where you have an activity or a proxy for it.
- Suppose you are implementing a single machine scheduling algorithm. In order to schedule an operation, you need to makes sure that the machine is available during your desired time of operation.
- Or you are implementing a booking system and need to check that the hotel has at least 1 room with desired number of beds for the dates selected. For such cases, you need to control some information overlapping with an interval.
As the examples suggest, pyintervals defines intervals with date and time.
However, adding support for other comparable types such as int
, float
is also possible.
Declare Interval
objects with pyintervals and check whether they overlap
with each other or
one contains
the other.
from pyintervals import Interval, overlaps, contains
from datetime import datetime
my_first_interval = Interval(start=datetime(2017,5,20,12,15),end=datetime(2024,10,10,19,0))
my_second_interval = Interval(start=datetime(2024,10,6,7,21),end=datetime(2024,10,10,19,0))
overlaps(my_first_interval, my_second_interval)
>>> True
my_first_interval.overlaps_with(my_second_interval)
>>> True
contains(my_first_interval, my_second_interval)
>>> True
my_first_interval.contains(my_second_interval)
>>> True
my_third_interval=Interval(start=datetime(1988,5,21,10,45),end=datetime(1989,6,20,1,30))
overlaps(my_first_interval,my_third_interval)
>>> False
contains(my_first_interval,my_third_interval)
>>> False
pyintervals also support degenerate intervals, which have their start
equal to their end
.
my_degenerate_interval = Interval(start=datetime(2024,10,10,9,0), end=datetime(2024,10,10,9,0))
overlaps(my_first_interval, my_degenerate_interval)
>>> True
my_same_degenerate_interval = Interval(start=datetime(2024,10,10,9,0), end=datetime(2024,10,10,9,0))
overlaps(my_degenerate_interval, my_same_degenerate_interval)
>>> True
Interval concept also leads to aggregate value over time. Let's dive with an example:
Let there be a beautiful and exclusive patisserie and you heard it from a foodie friend. She/he suggested you to go there as soon as possible. You checked your agenda and seems you have an empty spot at your calendar starting at 12:30. The place is open between 9:00-12:00 and 13:00 - 16:00 daily.
If you want to programatically check whether the shop is open at a given time T, then you need to iterate over all (in the worst case) the time intervals the patisserie is open for the time you are curious about, 12:30 in this case. This will take O(n) time.
Linear time is nice but can we not improve it? Well, with pyintervals, you can! What we essentially are curious about is the status of that beautiful store at a given time. pintervals will allow you fetch this value in O(log n) time.
See roadmap for the list of available and upcoming features.
Start with pyintervals right away with
pip install pyintervals
pyintervals is in active development and not feature complete yet. Please see below for completed and planned features.
Features:
✅ = implemented, 🚧 = planned, ❌ = not planned
- Fundamentals:
- ✅ Overlap controls
- ✅ Contain controls
- Interval Handler:
- ✅ Own intervals with associated values
- ✅ Provide value projection graph
- 🚧 Query value over time
- 🚧 Access intervals overlapping with a specific timespan
- Single-level Pegging:
- 🚧 Introduce object association to Intervals
- 🚧 Single level pegging with first-in-first-out
- 🚧 Enable callback for pegging quantity
- 🚧 Enable callback for pegging matching
- Support other comparable types
- 🚧 Define comparable protocol and generics
- 🚧 Adapt Interval and Interval Handler concepts
Following resources and people have inspired pyintervals:
- Always use [closed, open) intervals
- Arie Bovenberg
- pdfje (for initial setup of this project)
- Sam de Wringer
- Tim Lamballais-Tessensohn