Skip to main content

Python Intervals Arithmetic

Project description

Interval arithmetic for Python

Travis PyPi

This repository contains the Python 3.5+ intervals library that provides basic arithmetic for intervals in Python, supporting arbitrary object type.

This library is inspired by pyinter.

Features

  • Support intervals of arbitrary comparable objects.
  • Closed or open, finite or infinite intervals.
  • Union of intervals out of the box.
  • Automatically simplify union of intervals.
  • Support intersection, union, complement, difference and containment.

Installation

You can use pip to install this library:

pip install python-intervals

This will install the latest available version from pypi branche.
Prereleases are available from the master branch.

Usage

Assuming this library is imported using import intervals as I, intervals can be easily created using one of the following functions:

  • I.open(1, 2) corresponds to (1, 2);
  • I.closed(1, 2) corresponds to [1, 2];
  • I.openclosed(1, 2) corresponds to (1, 2];
  • and I.closedopen(1, 2) corresponds to [1, 2).
>>> I.closed(0, 3)  
[0,3]  
>>> I.openclosed('a', 'z')  
('a','z']  

Infinite and semi-infinite intervals are supported using I.inf and -I.inf as upper or lower bounds. These two objects support comparison with any other object.

>>> I.openclosed(-I.inf, 0)  
(-inf,0]  
>>> I.closed(-I.inf, I.inf)  # Automatically converted
(-inf,+inf)
>>> I.inf > 'a', I.inf > 0, I.inf > True
(True, True, True)

Intervals created with this library are Interval instances. An Interval object is a disjunction of AtomicInterval. An AtomicInterval represents a single interval (e.g. [1,2]) while an Interval represents union of intervals (e.g. [1,2] | [3,4]).

For convenience, Interval are automatically simplified:

>>> I.closed(0, 2) | I.closed(2, 4)
[0,4]
>>> I.closed(1, 2) | I.closed(3, 4) | I.closed(2, 3)
[1,4]
>>> I.closed(1, 2) | I.openclosed(2, 3) | I.closedopen(5, 5)
[1,3]

Both classes support interval arithmetic:

  • x.is_empty() tests if the interval is empty.

    >>> I.closed(0, 1).is_empty()
    False
    >>> I.closed(0, 0).is_empty()
    False
    >>> I.openclosed(0, 0).is_empty()
    True
    
  • x.overlaps(other) test if there is an overlap between two intervals. This method accepts a permissive parameter which defaults to False. If True, it considers that [1, 2) and [2, 3] have an overlap on 2 (but not [1, 2) and (2, 3]).

    >>> I.closed(1, 2).overlaps(I.closed(2, 3))
    True
    >>> I.closed(1, 2).overlaps(I.open(2, 3))
    False
    >>> I.closed(1, 2).overlaps(I.open(2, 3), permissive=True)
    True
    
  • x.intersection(other) or x & other returns the intersection of two intervals.

    >>> I.closed(0, 2) & I.closed(1, 3)
    [1,2]
    >>> I.closed(0, 4) & I.open(2, 3)
    (2,3)
    
  • x.union(other) or x | other returns the union of two intervals.

    >>> I.closed(0, 1) | I.closed(1, 2)
    [0,2]
    >>> I.closed(0, 1) | I.closed(2, 3)
    [0,1] | [2,3]
    
  • x.contains(other) or other in x returns True if given item is contained in the interval. Support Interval, AtomicInterval and arbitrary comparable values.

    >>> 2 in I.closed(0, 2)
    True
    >>> 2 in I.open(0, 2)
    False
    >> I.open(0, 1) in I.closed(0, 2)
    True
    
  • x.complement(other) or ~x returns the complement of the interval.

    >>> ~I.closed(0, 1)
    (-inf,0) | (1,+inf)
    >>> ~(I.open(-I.inf, 0) | I.open(1, I.inf))
    [0,1]
    
  • x.difference(other) or x - other returns the difference between x and other.

    >>> I.closed(0,2) - I.closed(1,2)
    [0,1)
    >>> I.closed(0, 4) - I.closed(1, 2)
    [0,1) | (2,4]
    
  • x == other checks for interval equality.

    >>> I.closed(0, 2) == I.closed(0, 1) | I.closed(1, 2)
    True
    

Additionally, an Interval provides:

  • x.is_atomic() evaluates to True if interval is the union of a single (possibly empty) atomic interval.
  • x.to_atomic() returns the smallest AtomicInterval that contains the interval(s).
  • Iteration protocol for the underlying set of AtomicInterval, sorted by their lower bound value.

The left and right boundaries, and the lower and upper bound of an AtomicInterval can be respectively accessed with its left, right, lower and upper attribute.

>>> [(i.left, i.lower, i.upper, i.right) for i in I.open(2, 3) | I.closed(0, 1)]
[(True, 0, 1, True), (False, 2, 3, False)]

Contributions

Contributions are very welcome!
Feel free to report bugs or suggest new features using GitHub issues and/or pull requests.

Licence

LGPLv3 - GNU Lesser General Public License, version 3

Changelog

1.0.3 (2018-04-03)

  • Initial working release on PyPi.

1.0.0 (2018-04-03)

  • Initial release.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python-intervals-1.0.3.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_intervals-1.0.3-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file python-intervals-1.0.3.tar.gz.

File metadata

File hashes

Hashes for python-intervals-1.0.3.tar.gz
Algorithm Hash digest
SHA256 98b0dc8376fdc75b746414017677de5b40347b323b40353b17ef760b8c328c1c
MD5 a7566b39d0f4ed64d6cd4b3b8729b174
BLAKE2b-256 b757862fb20b39e447bffd87be01d73f31f72ca167651894ae37c8f794646464

See more details on using hashes here.

File details

Details for the file python_intervals-1.0.3-py3-none-any.whl.

File metadata

File hashes

Hashes for python_intervals-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 2b590742c4b52408f6641f9474e96f2971982befce5e954d7bf62269e96d0335
MD5 3cafb679576502347c8939d86416966c
BLAKE2b-256 02e18c1d71578ceb8cb09206e665fa7a59e81613adb048b761184434fc25092c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page