• Stars
    star
    106
  • Rank 315,112 (Top 7 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created over 10 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Python tools for handling intervals (ranges of comparable objects).

intervals

Build Status Version Status Downloads

Python tools for handling intervals (ranges of comparable objects).

Interval initialization

Intervals can be initialized using the class constructor, various factory methods or from_string class method. The recommended way is to use the factory methods.

Notation Definition Factory method
(a..b) {x | a < x < b} open
[a..b] {x | a <= x <= b} closed
(a..b] {x | a < x <= b} open_closed
[a..b) {x | a <= x < b} closed_open
(a..+โˆž) {x | x > a} greater_than
[a..+โˆž) {x | x >= a} at_least
(-โˆž..b) {x | x < b} less_than
(-โˆž..b] {x | x <= b} at_most
(-โˆž..+โˆž) {x} all

When both endpoints exist, the upper endpoint may not be less than the lower. The endpoints may be equal only if at least one of the bounds is closed:

  • [a..a]: a singleton range (contains only one value)
  • [a..a), (a..a]: empty ranges
  • (a..a): invalid; an IllegalArgument exception will be thrown
>>> from intervals import IntInterval
>>> interval = IntInterval.open_closed(1, 5)
>>> interval.lower
1
>>> interval.upper
5
>>> interval.upper_inc
True

>>> interval = IntInterval.all()
>>> interval.lower
-inf
>>> interval.upper
inf

The first argument of class constructor should define the bounds of the interval.

>>> from intervals import IntInterval

>>> # All integers between 1 and 4
>>> interval = IntInterval([1, 4])
>>> interval.lower
1
>>> interval.upper
4
>>> interval.lower_inc
True
>>> interval.upper_inc
True

You can also pass a scalar as the first constructor argument.

>>> from intervals import IntInterval

>>> # All integers between 1 and 4
>>> interval = IntInterval(1)
>>> interval.lower
1
>>> interval.upper
1

Initializing an interval from string

The from_string method accepts two different formats.

  1. Standard string format
>>> from intervals import IntInterval

>>> # All integers between 1 and 4
>>> interval = IntInterval.from_string('[1, 4]')
>>> interval.lower
1
>>> interval.upper
4

By using standard string format you can easily initialize half-open intervals.

>>> from intervals import IntInterval

>>> interval = IntInterval.from_string('[1, 4)')
>>> interval.lower
1
>>> interval.upper
4
>>> interval.upper_inc
False

Unbounded intervals are supported as well.

>>> from intervals import IntInterval

>>> interval = IntInterval.from_string('[1, ]')
>>> interval.lower
1
>>> interval.upper
inf
  1. Hyphenized format
>>> from intervals import IntInterval

>>> # All integers between 1 and 4
>>> interval = IntInterval.from_string('1 - 4')
>>> interval.lower
1
>>> interval.upper
4

You can also initialize unbounded ranges.

>>> from intervals import IntInterval
>>> interval = IntInterval.from_string('1 - ')
>>> interval.lower
1
>>> interval.upper
inf

Open, half-open and closed intervals

Intervals can be either open, half-open or closed. Properties lower_inc and upper_inc denote whether or not given endpoint is included (open) or not.

  • An open interval is an interval where both endpoints are open.

    >>> interval = IntInterval((1, 4))
    >>> interval.is_open
    True
    >>> interval.lower_inc
    False
    >>> interval.upper_inc
    False
  • Half-open interval has one of the endpoints as open

    >>> from intervals import Interval
    
    >>> interval = IntInterval.from_string('[1, 4)')
    >>> interval.is_open
    False
    >>> interval.lower_inc
    True
    >>> interval.upper_inc
    False
  • Closed interval includes both endpoints

    >>> interval = IntInterval.from_string('[1, 4]')
    >>> interval.is_closed
    True
    >>> interval.lower_inc
    True
    >>> interval.upper_inc
    True

Unbounded intervals

Unbounded intervals are intervals where either one of the bounds is infinite.

>>> from infinity import inf
>>> from intervals import IntInterval

>>> interval = IntInterval.closed_open(1, inf)
>>> interval = IntInterval.open(-inf, inf)

Interval types

Each interval encapsulates a type. Interval is not actually a class. Its a convenient factory that generates AbstractInterval subclasses. Whenever you call Interval() the IntervalFactory tries to guess to best matching interval for given bounds.

>>> from datetime import date
>>> from infinity import inf

>>> interval = Interval([1, 4])
>>> interval
IntInterval('[1, 4]')
>>> interval.type.__name__
'int'

>>> interval = Interval(['a', 'd'])
>>> interval
CharacterInterval('[a, d]')
>>> interval.type.__name__
'str'

>>> interval = Interval([1.5, 4])
>>> interval
FloatInterval('[1.5, 4.0]')
>>> interval.type == type(5.5)
True

>>> interval = Interval([date(2000, 1, 1), inf])
>>> interval
DateInterval('[2000-01-01,]')
>>> interval.type.__name__
'date'

You can also create interval subtypes directly (this is also faster than using Interval).

>>> from intervals import FloatInterval, IntInterval
>>> IntInterval([1, 4])
IntInterval('[1, 4]')
>>> FloatInterval((1.4, 2.7))
FloatInterval('(1.4, 2.7)')

Currently provided subtypes are:

  • IntInterval
  • CharacterInterval
  • FloatInterval
  • DecimalInterval
  • DateInterval
  • DateTimeInterval

Properties

  • radius gives the half-length of an interval

    >>> IntInterval([1, 4]).radius
    1.5
  • length gives the length of an interval.

    >>> IntInterval([1, 4]).length
    3
  • centre gives the centre (midpoint) of an interval

    >>> IntInterval([-1, 1]).centre
    0.0
  • Interval [a, b] is degenerate if a = b

    >>> IntInterval([1, 1]).degenerate
    True
    >>> IntInterval([1, 2]).degenerate
    False

Emptiness

An interval is empty if it contains no points:

>>> IntInterval.from_string('(1, 1]').empty
True

Data type coercion

Interval evaluates as True if its non-empty

>>> bool(IntInterval([1, 6]))
True
>>> bool(IntInterval([0, 0]))
True
>>> bool(IntInterval.from_string('(1, 1]'))
False

Integer intervals can be coerced to integer if they contain only one point, otherwise passing them to int() throws a TypeError

>>> int(IntInterval([1, 6]))
Traceback (most recent call last):
    ...
TypeError: Only intervals containing single point can be coerced to integers

>>> int(IntInterval([1, 1]))
1

Operators

Operator coercion rules

All the operators and arithmetic functions use special coercion rules. These rules are made for convenience.

So for example when you type:

IntInterval([1, 5]) > IntInterval([3, 3])

Its actually the same as typing:

IntInterval([1, 5]) > [3, 3]

Which is also the same as typing:

IntInterval([1, 5]) > 3

Comparison operators

>>> IntInterval([1, 5]) > IntInterval([0, 3])
True
>>> IntInterval([1, 5]) == IntInterval([1, 5])
True
>>> IntInterval([2, 3]) in IntInterval([2, 6])
True
>>> IntInterval([2, 3]) in IntInterval([2, 3])
True
>>> IntInterval([2, 3]) in IntInterval((2, 3))
False

Intervals are hashable

Intervals are hashed on the same attributes that affect comparison: the values of the upper and lower bounds, lower_inc and upper_inc, and the type of the interval. This enables the use of intervals as keys in dict() objects.

>>> IntInterval([3, 7]) in {IntInterval([3, 7]): 'zero to ten'}
True
>>> IntInterval([3, 7]) in set([IntInterval([3, 7])])
True
>>> IntInterval((3, 7)) in set([IntInterval([3, 7])])
False
>>> IntInterval([3, 7]) in set([FloatInterval([3, 7])])
False

Discrete intervals

>>> IntInterval([2, 4]) == IntInterval((1, 5))
True

Using interval steps

You can assign given interval to use optional step argument. By default IntInterval uses step=1. When the interval encounters a value that is not a multiplier of the step argument it tries to round it to the nearest multiplier of the step.

>>> from intervals import IntInterval

>>> interval = IntInterval([0, 5], step=2)
>>> interval.lower
0
>>> interval.upper
6

You can also use steps for FloatInterval and DecimalInterval classes. Same rounding rules apply here.

>>> from intervals import FloatInterval

>>> interval = FloatInterval([0.2, 0.8], step=0.5)
>>> interval.lower
0.0
>>> interval.upper
1.0

Arithmetics

Arithmetic operators

>>> Interval([1, 5]) + Interval([1, 8])
IntInterval('[2, 13]')

>>> Interval([1, 4]) - 1
IntInterval('[0, 3]')

Intersection:

>>> Interval([2, 6]) & Interval([3, 8])
IntInterval('[3, 6]')

Union:

>>> Interval([2, 6]) | Interval([3, 8])
IntInterval('[2, 8]')

Arithmetic functions

>>> interval = IntInterval([1, 3])

>>> # greatest lower bound
>>> interval.glb(IntInterval([1, 2]))
IntInterval('[1, 2]')

>>> # least upper bound
>>> interval.lub(IntInterval([1, 2]))
IntInterval('[1, 3]')

>>> # infimum
>>> interval.inf(IntInterval([1, 2]))
IntInterval('[1, 2]')

>>> # supremum
>>> interval.sup(IntInterval([1, 2]))
IntInterval('[1, 3]')

More Repositories

1

sqlalchemy-utils

Various utility functions and datatypes for SQLAlchemy.
Python
1,206
star
2

validators

Python Data Validation for Humansโ„ข.
Python
582
star
3

sqlalchemy-continuum

Versioning extension for SQLAlchemy.
Python
554
star
4

wtforms-alchemy

Tools for creating wtforms from sqlalchemy models
Python
241
star
5

wtforms-json

Adds smart json support for WTForms. Useful for when using WTForms with RESTful APIs.
Python
138
star
6

postgresql-audit

Audit trigger for PostgreSQL
Python
124
star
7

wtforms-components

Additional fields, validators and widgets for WTForms.
Python
68
star
8

sqlalchemy-i18n

Internationalization extension for SQLAlchemy models
Python
49
star
9

sqlalchemy-json-api

Fast SQLAlchemy query builder for returning JSON API responses
Python
45
star
10

flask-storage

Various file storage backends for Flask applications.
Python
20
star
11

infinity

All-in-one infinity value for Python. Can be compared to any object.
Python
20
star
12

sqlalchemy-defaults

Smart SQLAlchemy defaults for lazy guys, like me.
Python
16
star
13

sqlalchemy-fixtures

Functional fixtures for SQLAlchemy
Python
11
star
14

flask-jinjahelpers

Various helpers for Jinja2 templates
Python
10
star
15

sqlalchemy-sluggable

SQLAlchemy-Sluggable
Python
8
star
16

python-poker

Python poker library
Python
6
star
17

flask-test

Various unit test helpers for Flask applications
Python
6
star
18

flask-activity-stream

4
star
19

total-ordering

functools.total_ordering backport for Python 2.6
Python
4
star
20

colander-alchemy

Generates colander schemas from SQLAlchemy models
Python
4
star
21

wtforms-test

Various unit test helpers for WTForms forms
Python
4
star
22

flask-generic-views

Generic pluggable views for flask
Python
4
star
23

serializer

Easy object serialization. Mimics RoR ActiveRecord serializer.
Python
4
star
24

primitives

Data types you've always missed in Python
Python
3
star
25

postgresql-snippets

Various snippets for PostgreSQL
2
star
26

bourne

Easy object json serialization. Mimics RoR ActiveRecord json serializer
Python
2
star
27

schemas

Python data structures for Humansโ„ข.
Python
2
star
28

flask-alchemy

Various SQLAlchemy helpers for Flask, built on top of Flask-SQLAlchemy
Python
1
star
29

dotfiles

Shell
1
star
30

wtforms-errors

Better error messages for wtforms
1
star
31

sqlalchemy-test

Various unit test helpers for SQLAlchemy models
Python
1
star