"""
This is a class describing a sorted frozen set. This is a collection implementation for a set of ordered elements that establish specific protocols for iteration, information access, element identification.
"""
# ============================================================================
# STANDARD IMPORTS
# ============================================================================
from collections.abc import Sequence, Set
from itertools import chain
from bisect import bisect_left
# ============================================================================
# CLASS AND DEFINITIONS
# ============================================================================
[docs]class SortedFrozenSet(Sequence, Set):
"""
This is a collection that provides a set of properties to create a sorted frozen set.
In particular
Args:
Sequence (Sequence): Inherits from the `Sequence` collection object.
Set (Set): Inherits from the `Set` collection object.
"""
def __init__(self, items=None):
self._items = list(
sorted(
set(items) if (items is not None) else set(),
key=lambda x: x.vehid,
)
)
def __contains__(self, item):
try:
self.index(item)
return True
except ValueError:
return False
def __len__(self):
return len(self._items)
def __iter__(self):
return iter(self._items)
def __getitem__(self, index):
result = self._items[index]
return SortedFrozenSet(result) if isinstance(index, slice) else result
def __repr__(self):
return "{type}({arg})".format(
type=type(self).__name__,
arg=(
"[{}]".format(", ".join(map(repr, self._items))) if self._items else ""
),
)
def __eq__(self, rhs):
if not isinstance(rhs, type(self)):
return NotImplemented
return self._items == rhs._items
def __hash__(self):
return hash((type(self), self._items))
def __add__(self, rhs):
if not isinstance(rhs, type(self)):
return NotImplemented
return SortedFrozenSet(chain(self._items, rhs._items))
def __mul__(self, rhs):
return self if rhs > 0 else SortedFrozenSet()
def __rmul__(self, lhs):
return self * lhs
[docs] def count(self, item):
return int(item in self)
[docs] def index(self, item):
index = bisect_left(self._items, item)
if (index != len(self._items)) and self._items[index] == item:
return index
raise ValueError(f"{item!r} not found")
[docs] def issubset(self, iterable):
return self <= SortedFrozenSet(iterable)
[docs] def issuperset(self, iterable):
return self >= SortedFrozenSet(iterable)
[docs] def intersection(self, iterable):
return self & SortedFrozenSet(iterable)
[docs] def union(self, iterable):
return self | SortedFrozenSet(iterable)
[docs] def symmetric_difference(self, iterable):
return self ^ SortedFrozenSet(iterable)
[docs] def difference(self, iterable):
return self - SortedFrozenSet(iterable)