Skip to content

vayu.interval

interval

Interval dataclass

Interval(start: Comparable, end: Comparable)

A closed interval [start, end] with union / intersection / containment algebra.

Works on any comparable type — int, float, date, datetime. Subclasses (e.g. TimeWindow) flow through operators automatically because the dunder methods use self.__class__.

Single-point intervals (start == end) are allowed so that touching endpoints like [1, 3] & [3, 5] produce [3, 3] instead of raising.

Attributes:

Name Type Description
start Comparable

Lower bound (inclusive).

end Comparable

Upper bound (inclusive).

range property

range: Comparable

The span of the interval (end - start).

intersects

intersects(other: Interval) -> bool

Return True if this interval and other share at least one point.

Source code in vayu/interval.py
def intersects(self, other: "Interval") -> bool:
    """Return True if this interval and ``other`` share at least one point."""
    return self.start <= other.end and other.start <= self.end

intersection

intersection(other: Interval) -> Interval

Return the overlapping sub-interval, or raise if there's no overlap.

Raises:

Type Description
ValueError

If the intervals don't overlap.

Source code in vayu/interval.py
def intersection(self, other: "Interval") -> "Interval":
    """Return the overlapping sub-interval, or raise if there's no overlap.

    Raises:
        ValueError: If the intervals don't overlap.
    """
    if not self.intersects(other):
        raise ValueError("No intersection possible")

    return replace(self, start=max(self.start, other.start), end=min(self.end, other.end))

union classmethod

union(
    intervals: Sequence[Interval], allow_gaps: bool = False
) -> Interval

Return the smallest interval that contains all inputs.

Parameters:

Name Type Description Default
intervals Sequence[Interval]

One or more intervals to union.

required
allow_gaps bool

If False (the default), raise ValueError when the inputs don't collectively touch or overlap. If True, return the bounding envelope even when gaps exist.

False

Raises:

Type Description
AssertionError

If intervals is empty.

ValueError

If allow_gaps is False and there is a gap between two inputs.

Source code in vayu/interval.py
@classmethod
def union(cls, intervals: Sequence["Interval"], allow_gaps: bool = False) -> "Interval":
    """Return the smallest interval that contains all inputs.

    Args:
        intervals: One or more intervals to union.
        allow_gaps: If False (the default), raise ``ValueError`` when the
            inputs don't collectively touch or overlap. If True, return the
            bounding envelope even when gaps exist.

    Raises:
        AssertionError: If ``intervals`` is empty.
        ValueError: If ``allow_gaps`` is False and there is a gap between
            two inputs.
    """
    # TODO: Fix this: should have a signature same as intersection.
    if len(intervals) == 0:
        raise AssertionError("Length of intervals should at least be 1")
    if len(intervals) == 1:
        return intervals[0]

    intervals = sorted(intervals, key=attrgetter("start"))
    if not allow_gaps:
        for i in range(len(intervals) - 1):
            first = intervals[i]
            second = intervals[i + 1]
            if first.end < second.start:
                raise ValueError(f"Gaps not supported in interval union")

    return cls(start=intervals[0].start, end=intervals[-1].end)