# Principled Programming / Tim Teitelbaum / Chapter 18.
from typing import NoReturn

class HashSet[E]:
    """Generic HashSet containing items of type E."""
    # Representation.
    _A: set[E]     # _A is the set of items.

    # Constructor.
    def __init__(self, m: int = 20) -> None:
        """A set of unbounded capacity containing items of type E."""
        if m < 0: raise ValueError("Capacity must be non-negative int")
        self._A = set[E]()

    # Size.
    def size(self) -> int:
        """Return the number of items in the set."""
        return len(self._A)

    def is_empty(self) -> bool:
        """Return True iff the set is empty."""
        return len(self._A) == 0

    # Access.
    def get(self, k: int) -> NoReturn:
        """Unsupported."""
        assert False, "get not supported"

    def set(self, k: int, v: E) -> NoReturn:
        """Unsupported."""
        assert False, "set not supported"

    # Insertion / Deletion.        
    def add(self, v: E, k: int = -1) -> None:
        """
        If no k is provided, insert v into the set, else
        raise an assertion exception "add at index not supported".
        """
        if k != -1:
            assert False, "add at index not supported"
        self._A.add(v)

    def remove(self, k: int) -> NoReturn:
        """Unsupported."""
        assert False, "remove (by index) not supported"

    def remove_by_value(self, v: E) -> bool:
        """Return False if v is not in the set, else remove v from the set and return True."""
        try:
            self._A.remove(v)
            return True
        except ValueError:
            return False

     # Capacity.
    def ensure_capacity(self, min_capacity: int) -> None:
        """A superfluous operation that purports to increase the set's capacity."""
        pass

    # Membership.
    def index_of(self, v: E) -> NoReturn:
        """Unsupported."""
        assert False, "index_of not supported"

    def contains(self, v: E) -> bool:
        """Return True iff the set contains v."""
        return v in self._A