def add(self, val) -> bool:
     val_hash = _get_hash(val)
     if not self._contains(vals):
         self.hash *= val_hash
         return True
     else:
         return False
 def remove(self, val):
     val_hash = _get_hash(val)
     if self._contains(vals):
         self.hash //= val_hash
         return True
     else:
         return False
    def __init__(self, iter_vals=[]):
        if not isinstance(iter_vals, (str, list)):
            raise ValueError("value must be string or list")

        self.hash = 1
        for val in iter_vals:
            val_hash = _get_hash(val)
            if not self._contains(val_hash):
                self.hash *= val_hash
 def remove(self, val) -> bool:
    _hash = _get_hash(val)
    idx = _hash % len(self.container)
    bucket: SortedSet = self.container[idx]
    if val in bucket:
       bucket.remove(val)
       self.size -= 1
       return True
    else:
       return False
 def _resize():
    new_size = len(self.container) * 2
    old_container = self.container
    self.container = [SortedSet()] * new_size
    item_count = 0
    for bucket in old_container:
       for val in bucket:
          _hash = _get_hash(val)
          _add_to_bucket(val, _hash)
          item_count += 1
    
    self.size = item_count
   def add(self, val) -> bool:
      content_ratio = self.size / len(self.container)
      _hash = _get_hash(val)
      idx = _hash % len(self.container)
      bucket: SortedSet = self.container[idx]
      if val in bucket: return False

      if content_ratio > self.collision_prob:
         self._resize()
      
      bucket.add(val)
      self.size += 1
      return True
 def contains(self, val) -> bool:
     val_hash = _get_hash(val)
     return self._contains(val_hash)
 def contains(self, val) -> bool:
    _hash = _get_hash(val)
    idx = _hash % len(self.container)
    bucket: SortedSet = self.container[idx]
    return val in bucket