📐 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** `will` allow you fetch this value in `O(log n)` time.
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": "https://github.com/serkankalay/pyintervals",
"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/97/2e/53625711e17322e09a4ab8cdac551fa26f1d14123b18bf6c1ee855d49843/pyintervals-1.0.1.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** `will` allow you fetch this value in `O(log n)` time.\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 - \ud83d\udea7 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.1",
"project_urls": {
"Homepage": "https://github.com/serkankalay/pyintervals",
"Repository": "https://github.com/serkankalay/pyintervals"
},
"split_keywords": [
"interval",
" timespan"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "1ecb2e8e51bbbce9bd359d843a16e24785b08dcf780856eaf72d0cc5355eb9f6",
"md5": "27af6f802cf3deb4cefac65d0e1d3dbc",
"sha256": "6b994d83bcfa739769da2f290aa1a0ff37ca4129bb937d11e504a7f6daea4c54"
},
"downloads": -1,
"filename": "pyintervals-1.0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "27af6f802cf3deb4cefac65d0e1d3dbc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0.0,>=3.8.1",
"size": 11088,
"upload_time": "2024-06-04T14:41:13",
"upload_time_iso_8601": "2024-06-04T14:41:13.287787Z",
"url": "https://files.pythonhosted.org/packages/1e/cb/2e8e51bbbce9bd359d843a16e24785b08dcf780856eaf72d0cc5355eb9f6/pyintervals-1.0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "972e53625711e17322e09a4ab8cdac551fa26f1d14123b18bf6c1ee855d49843",
"md5": "2383d7719c07703c292b90c69751a00e",
"sha256": "c55cdffcb5cf7247901448bfc93a4fa75e36b0aa064903eea1b5b101d2c9d419"
},
"downloads": -1,
"filename": "pyintervals-1.0.1.tar.gz",
"has_sig": false,
"md5_digest": "2383d7719c07703c292b90c69751a00e",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0.0,>=3.8.1",
"size": 9136,
"upload_time": "2024-06-04T14:41:15",
"upload_time_iso_8601": "2024-06-04T14:41:15.352401Z",
"url": "https://files.pythonhosted.org/packages/97/2e/53625711e17322e09a4ab8cdac551fa26f1d14123b18bf6c1ee855d49843/pyintervals-1.0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-04 14:41:15",
"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"
}