def intersects_segment(self, other): """ Returns True if the intersection of self and the segment other is not the null set, otherwise returns False. The algorithm is O(log n). Requires the list to be coalesced. """ i = _bisect_left(self, other) return ((i != 0) and (other[0] < self[i-1][1])) or ((i != len(self)) and (other[1] > self[i][0]))
def _Heads(self, start=None, end=None, reverse=False): if start is None: start = self.MinEA() if end is None: end = self.MaxEA() if reverse: inc = -1 i = _bisect_left(self._heads, end) else: inc = 1 i = _bisect_left(self._heads, start) # TODO: Make global num_heads? num_heads = len(self._heads) while (0 <= i < num_heads): ea = self._heads[i] if start <= ea <= end: yield ea i += inc
def __setitem__(self, index, item): """this does not support item assignment""" raise TypeError( f"{type(self).__name__!r} object does not support item assignment") k = self._key(item) i = _bisect_left(self._keys, k) j = _bisect_right(self._keys, k) print(f"{item=} {index=} {i=} {j=}") if (i == j) and i == index: self._keys[i] = k self._items[i] = item else: raise ValueError( "Can't insert item in position {index} and preserve the order")
def __contains__(self, item): """ Returns True if the given object is wholly contained within the segments in self. If self has length n, then if item is a scalar or a segment this operation is O(log n), if item is a segmentlist of m segments this operation is O(m log n). Note the difference between this operator and the standard Python "in" operator for sequence-like objects: in the case of standard sequence-like objects the in operator checks for an exact match between the given item and one of the contents of the list; for segmentlists, the in operator checks if the given item is contained within any of the segments in the segmentlist. """ if isinstance(item, self.__class__): return all(seg in self for seg in item) i = _bisect_left(self, item) return ((i != 0) and (item in self[i-1])) or ((i != len(self)) and (item in self[i]))
def get_index(values, value): return len(values) - _bisect_left(values[::-1], value) - 1
def insert(self, item): 'Insert a new item. If equal keys are found, add to the left' k = self._key(item) i = _bisect_left(self._keys, k) self._keys.insert(i, k) self._items.insert(i, item)
def __contains__(self, item): k = self._key(item) lo = _bisect_left(self._keys, k) hi = _bisect_right(self._keys, k) items = self._items return any(item == items[i] for i in range(lo, hi))