Defining the Tree class

We'll start with the wrapper or Façade class, Tree. This is the core of an extension to the MutableSet class that provides the minimal method functions:

class Tree(collections.abc.MutableSet):

def __init__(self, source: Iterable[Comparable] = None) -> None:
self.root = TreeNode(None)
self.size = 0
if source:
for item in source:
self.root.add(item)
self.size += 1

def add(self, item: Comparable) -> None:
self.root.add(item)
self.size += 1

def discard(self, item: Comparable) -> None:
if self.root.more:
try:
self.root.more.remove(item)
self.size -= 1
except KeyError:
pass
else:
pass

def __contains__(self, item: Any) -> bool:
if self.root.more:
self.root.more.find(cast(Comparable, item))
return True
else:
return False

def __iter__(self) -> Iterator[Comparable]:
if self.root.more:
for item in iter(self.root.more):
yield item
# Otherwise, the tree is empty.

def __len__(self) -> int:
return self.size

The initialization design is similar to that of a Counter object; this class will accept an iterable and load the elements into the structure. The source of data is provided with a type hint of Iterable[Comparable]. This hint imposes a restriction on the kinds of items which this collection can handle.  If the collection is used with items that do not support the proper comparable protocol methods, then mypy will report an error.

Here's the definition of the Comparable type hint:

class Comparable(metaclass=ABCMeta):
@abstractmethod
def __lt__(self, other: Any) -> bool: ...
@abstractmethod
def __ge__(self, other: Any) -> bool: ...

The Comparable class definition is an abstraction which requires two methods: __lt__() and __ge__(). This is the minimum required for a class of objects to work properly with the <, <=, >, and >= operators. This defines the comparable protocol among objects that can be sorted or ranked.

The add() and discard() methods both update the tree, and also keep track of the overall size. That saves counting nodes via a recursive traversal of the tree. These methods also delegate their work to the TreeNode object at the root of the tree.

The __contains__() special method performs a recursive find. The initial check to be sure the tree contains a value in the root node is required by mypy. Without the if statement, the type hints suggest the more attribute could be None

The __iter__() special method is a generator function. It also delegates the real work to recursive iterators within the TreeNode class.

We defined discard(); mutable sets require this to be silent when attempting to discard the missing keys. The abstract superclass provides a default implementation of remove(), which raises an exception if a key is not found. Both method functions must be present; we defined discard() based on remove(), by silencing the exception. In some cases, it might be easier to define remove() based on discard(), by raising an exception if a problem is found.

Because this class extends the MutableSet abstraction, numerous features are provided automatically. This saves us from copy-and-paste programming to create a number of boilerplate features. In some cases, our data structure may have more efficient implementations than the defaults, and we may want to override additional methods inherited from the abstract superclass.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset