Name | pyintervals JSON |
Version |
1.0.3
JSON |
| download |
home_page | None |
Summary | Efficient interval operations. |
upload_time | 2025-08-01 09:54:27 |
maintainer | None |
docs_url | None |
author | Serkan Kalay |
requires_python | <4.0.0,>=3.8.1 |
license | MIT |
keywords |
interval
timespan
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
📐 pyintervals
===============================
.. image:: https://img.shields.io/pypi/v/pyintervals.svg?style=flat-square&color=blue
:target: https://pypi.python.org/pypi/pyintervals
.. image:: https://img.shields.io/pypi/pyversions/pyintervals.svg?style=flat-square
:target: https://pypi.python.org/pypi/pyintervals
.. image:: https://img.shields.io/pypi/l/pyintervals.svg?style=flat-square&color=blue
:target: https://pypi.python.org/pypi/pyintervals
.. image:: https://img.shields.io/badge/mypy-strict-forestgreen?style=flat-square
:target: https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-strict
.. image:: https://img.shields.io/badge/coverage-99%25-forestgreen?style=flat-square
:target: https://github.com/serkankalay/pyintervals
.. image:: https://img.shields.io/github/actions/workflow/status/serkankalay/pyintervals/tests.yml?branch=master&style=flat-square
:target: https://github.com/serkankalay/pyintervals
**Execute efficient interval operations in Python.**
*(Currently in active development. Leave a* ⭐️ *on GitHub if you're interested how this develops!)*
Why?
--------
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.
How?
--------
Declare ``Interval`` objects with **pyintervals** and check whether they ``overlap`` with each other or
one ``contains`` the other.
.. code-block:: python
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``.
.. code-block:: python
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
What else?
-----------
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** allows you to fetch this value in `O(log n)` time.
.. code-block:: python
# Add open times with value 1
mon_interval_1 = Interval(start=datetime(2025,7,21,9,00),end=datetime(2025,7,21,12,0), value=1)
mon_interval_2 = Interval(start=datetime(2025,7,21,13,00),end=datetime(2025,7,21,16,0), value=1)
tue_interval_1 = Interval(start=datetime(2025,7,22,9,00),end=datetime(2025,7,22,12,0), value=1)
tue_interval_2 = Interval(start=datetime(2025,7,22,13,00),end=datetime(2025,7,22,16,0), value=1)
capacity = IntervalHandler()
capacity.add(
[
mon_interval_1,
mon_interval_2,
tue_interval_1,
tue_interval_2,
]
)
# Check the capacity, which indicates open when value is positive
capacity.value_at_time(datetime(2025,7,21,9,30))
>>> 1 # Open
capacity.value_at_time(datetime(2025,7,21,12,30))
>>> 0 # Closed
capacity.value_at_time(datetime(2025,7,22,13,00))
>>> 1 # Open
capacity.value_at_time(datetime(2025,7,22,16,00))
>>> 0 # Closed
capacity.value_at_time(datetime(2025,7,22,15,59))
>>> 1 # Open
See roadmap_ for the list of available and upcoming features.
When?
---------
Start with **pyintervals** right away with
.. code-block:: bash
pip install pyintervals
.. _roadmap:
Roadmap
---------
**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
Acknowledgements
----------------
Following resources and people have inspired **pyintervals**:
- `Always use [closed, open) intervals <https://fhur.me/posts/always-use-closed-open-intervalshttps://fhur.me/posts/always-use-closed-open-intervals>`_
- `Arie Bovenberg <https://github.com/ariebovenberg>`_
- `pdfje (for initial setup of this project) <https://github.com/ariebovenberg/pdfje>`_
- `Sam de Wringer <https://github.com/samdewr>`_
- Tim Lamballais-Tessensohn
Raw data
{
"_id": null,
"home_page": null,
"name": "pyintervals",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0.0,>=3.8.1",
"maintainer_email": null,
"keywords": "interval, timespan",
"author": "Serkan Kalay",
"author_email": "serkanosmankalay@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/63/2f/ebace75465bc96acc1c6a731ab1cc6df6c5d4b85db0614a3d1176721c0f4/pyintervals-1.0.3.tar.gz",
"platform": null,
"description": "\ud83d\udcd0 pyintervals\n===============================\n\n.. image:: https://img.shields.io/pypi/v/pyintervals.svg?style=flat-square&color=blue\n :target: https://pypi.python.org/pypi/pyintervals\n\n.. image:: https://img.shields.io/pypi/pyversions/pyintervals.svg?style=flat-square\n :target: https://pypi.python.org/pypi/pyintervals\n\n.. image:: https://img.shields.io/pypi/l/pyintervals.svg?style=flat-square&color=blue\n :target: https://pypi.python.org/pypi/pyintervals\n\n.. image:: https://img.shields.io/badge/mypy-strict-forestgreen?style=flat-square\n :target: https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-strict\n\n.. image:: https://img.shields.io/badge/coverage-99%25-forestgreen?style=flat-square\n :target: https://github.com/serkankalay/pyintervals\n\n.. image:: https://img.shields.io/github/actions/workflow/status/serkankalay/pyintervals/tests.yml?branch=master&style=flat-square\n :target: https://github.com/serkankalay/pyintervals\n\n**Execute efficient interval operations in Python.**\n\n*(Currently in active development. Leave a* \u2b50\ufe0f *on GitHub if you're interested how this develops!)*\n\nWhy?\n--------\n\nInspired by a discussion and initial implementation in a professional project\nand a library I've been using in one of my previous jobs, **pyintervals** is born.\n\nIntervals pop-up frequently in programming, specifically in domains where you\nhave an activity or a proxy for it.\n\n- Suppose you are implementing a single machine scheduling algorithm.\n In order to schedule an operation, you need to makes sure that the machine is available\n during your desired time of operation.\n- Or you are implementing a booking system and need to check\n that the hotel has at least 1 room with desired number of beds for the dates selected.\n For such cases, you need to control some information overlapping with an interval.\n\nAs the examples suggest, **pyintervals** defines intervals with date and time.\nHowever, adding support for other comparable types such as ``int``, ``float`` is also possible.\n\nHow?\n--------\n\nDeclare ``Interval`` objects with **pyintervals** and check whether they ``overlap`` with each other or\none ``contains`` the other.\n\n.. code-block:: python\n\n from pyintervals import Interval, overlaps, contains\n from datetime import datetime\n\n my_first_interval = Interval(start=datetime(2017,5,20,12,15),end=datetime(2024,10,10,19,0))\n my_second_interval = Interval(start=datetime(2024,10,6,7,21),end=datetime(2024,10,10,19,0))\n\n overlaps(my_first_interval, my_second_interval)\n >>> True\n\n my_first_interval.overlaps_with(my_second_interval)\n >>> True\n\n contains(my_first_interval, my_second_interval)\n >>> True\n\n my_first_interval.contains(my_second_interval)\n >>> True\n\n my_third_interval=Interval(start=datetime(1988,5,21,10,45),end=datetime(1989,6,20,1,30))\n overlaps(my_first_interval,my_third_interval)\n >>> False\n\n contains(my_first_interval,my_third_interval)\n >>> False\n\n**pyintervals** also support `degenerate` intervals, which have their ``start`` equal to their ``end``.\n\n.. code-block:: python\n\n my_degenerate_interval = Interval(start=datetime(2024,10,10,9,0), end=datetime(2024,10,10,9,0))\n\n overlaps(my_first_interval, my_degenerate_interval)\n >>> True\n\n my_same_degenerate_interval = Interval(start=datetime(2024,10,10,9,0), end=datetime(2024,10,10,9,0))\n\n overlaps(my_degenerate_interval, my_same_degenerate_interval)\n >>> True\n\nWhat else?\n-----------\n\nInterval concept also leads to `aggregate value over time`. Let's dive with an example:\n\nLet there be a beautiful and exclusive patisserie and you heard it from a foodie friend.\nShe/he suggested you to go there as soon as possible.\nYou checked your agenda and seems you have an empty spot at your calendar starting at 12:30.\nThe place is open between 9:00-12:00 and 13:00 - 16:00 daily.\n\nIf you want to programatically check whether the shop is open at a given time **T**, then\nyou need to iterate over `all (in the worst case)` the time intervals the patisserie is open\nfor the time you are curious about, 12:30 in this case. This will take `O(n)` time.\n\nLinear time is nice but can we not improve it? Well, with **pyintervals**, you can!\nWhat we essentially are curious about is the status of that beautiful store at a given time.\n**pintervals** allows you to fetch this value in `O(log n)` time.\n\n.. code-block:: python\n\n # Add open times with value 1\n mon_interval_1 = Interval(start=datetime(2025,7,21,9,00),end=datetime(2025,7,21,12,0), value=1)\n mon_interval_2 = Interval(start=datetime(2025,7,21,13,00),end=datetime(2025,7,21,16,0), value=1)\n tue_interval_1 = Interval(start=datetime(2025,7,22,9,00),end=datetime(2025,7,22,12,0), value=1)\n tue_interval_2 = Interval(start=datetime(2025,7,22,13,00),end=datetime(2025,7,22,16,0), value=1)\n\n capacity = IntervalHandler()\n capacity.add(\n [\n mon_interval_1,\n mon_interval_2,\n tue_interval_1,\n tue_interval_2,\n ]\n )\n\n # Check the capacity, which indicates open when value is positive\n capacity.value_at_time(datetime(2025,7,21,9,30))\n >>> 1 # Open\n\n capacity.value_at_time(datetime(2025,7,21,12,30))\n >>> 0 # Closed\n\n capacity.value_at_time(datetime(2025,7,22,13,00))\n >>> 1 # Open\n\n capacity.value_at_time(datetime(2025,7,22,16,00))\n >>> 0 # Closed\n\n capacity.value_at_time(datetime(2025,7,22,15,59))\n >>> 1 # Open\n\nSee roadmap_ for the list of available and upcoming features.\n\nWhen?\n---------\n\nStart with **pyintervals** right away with\n\n.. code-block:: bash\n\n pip install pyintervals\n\n.. _roadmap:\n\nRoadmap\n---------\n**pyintervals** is in active development and not feature complete yet. Please see below\nfor completed and planned features.\n\nFeatures:\n\n\u2705 = implemented, \ud83d\udea7 = planned, \u274c = not planned\n\n- Fundamentals:\n - \u2705 Overlap controls\n - \u2705 Contain controls\n- Interval Handler:\n - \u2705 Own intervals with associated values\n - \u2705 Provide value projection graph\n - \u2705 Query value over time\n - \ud83d\udea7 Access intervals overlapping with a specific timespan\n- Single-level Pegging:\n - \ud83d\udea7 Introduce object association to Intervals\n - \ud83d\udea7 Single level pegging with first-in-first-out\n - \ud83d\udea7 Enable callback for pegging quantity\n - \ud83d\udea7 Enable callback for pegging matching\n- Support other comparable types\n - \ud83d\udea7 Define comparable protocol and generics\n - \ud83d\udea7 Adapt Interval and Interval Handler concepts\n\nAcknowledgements\n----------------\n\nFollowing resources and people have inspired **pyintervals**:\n\n- `Always use [closed, open) intervals <https://fhur.me/posts/always-use-closed-open-intervalshttps://fhur.me/posts/always-use-closed-open-intervals>`_\n- `Arie Bovenberg <https://github.com/ariebovenberg>`_\n- `pdfje (for initial setup of this project) <https://github.com/ariebovenberg/pdfje>`_\n- `Sam de Wringer <https://github.com/samdewr>`_\n- Tim Lamballais-Tessensohn\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Efficient interval operations.",
"version": "1.0.3",
"project_urls": {
"Repository": "https://github.com/serkankalay/pyintervals"
},
"split_keywords": [
"interval",
" timespan"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7c7216043a7ee66b6adebaf8c14d0916831f5e714e6203e30c28d422952310c7",
"md5": "911dc5b3326a150d2f52928f62043761",
"sha256": "6f3780d60bd59be9cf96d569197d9374470908d49cf0486768c76a5ed28a63ec"
},
"downloads": -1,
"filename": "pyintervals-1.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "911dc5b3326a150d2f52928f62043761",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0.0,>=3.8.1",
"size": 8585,
"upload_time": "2025-08-01T09:54:26",
"upload_time_iso_8601": "2025-08-01T09:54:26.536777Z",
"url": "https://files.pythonhosted.org/packages/7c/72/16043a7ee66b6adebaf8c14d0916831f5e714e6203e30c28d422952310c7/pyintervals-1.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "632febace75465bc96acc1c6a731ab1cc6df6c5d4b85db0614a3d1176721c0f4",
"md5": "fb0c7f569fa542eb344de1b949ff4e1d",
"sha256": "8e068ace92c7be97dd0c9d2096b7c3a89bde0fdfbc8232a52598ebfcbf148a91"
},
"downloads": -1,
"filename": "pyintervals-1.0.3.tar.gz",
"has_sig": false,
"md5_digest": "fb0c7f569fa542eb344de1b949ff4e1d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0.0,>=3.8.1",
"size": 6969,
"upload_time": "2025-08-01T09:54:27",
"upload_time_iso_8601": "2025-08-01T09:54:27.669566Z",
"url": "https://files.pythonhosted.org/packages/63/2f/ebace75465bc96acc1c6a731ab1cc6df6c5d4b85db0614a3d1176721c0f4/pyintervals-1.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-01 09:54:27",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "serkankalay",
"github_project": "pyintervals",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "pyintervals"
}