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.0 (2018-04-03)

  • Initial release on PyPi

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.2.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.2-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

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

File metadata

File hashes

Hashes for python-intervals-1.0.2.tar.gz
Algorithm Hash digest
SHA256 a0159478643e1035a1e65082e5feca8cf408b8754c3515cf3a150a1b465991cd
MD5 aac2e378808e6705035a03bac5421279
BLAKE2b-256 26b346216da4c6c3b7483bac53ab018852f2f64303b7781dabf049f555e29cb6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for python_intervals-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 22f84562c27df982e0c098506b01bed310dcad7fb08c86c700dc321df0a43c8b
MD5 fb0c5e32b1163bfd7730a9ba550a1637
BLAKE2b-256 cc738061be44278251a8c76f7e5dddbc791ed5806c9daa393db1d60e4da2f1eb

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