<reponame>NarwhalBlast/DataStructureUCO
"""
An implementation of a HashTable.

Contributors: <NAME>, and <NAME>.
"""
from __future__ import annotations
from typing import Any, Tuple
from lists.singly_linked_list import SinglyLinkedList


class HashTable:
    """ A Hash Table that is implemented using linked-list chaining.
        Assume all keys are Strings.
    """
    # This implementation will used linked-list chaining.
    _buckets: list[SinglyLinkedList[Tuple[str, Any]]]
    _size: int  # Size of Hash Table.

    def __init__(self, buckets: int) -> None:
        if buckets < 1:
            raise ValueError('Cannot have less than 1 buckets')

        self._buckets = [SinglyLinkedList() for bucket in range(0, buckets)]
        self._size = 0

    def __str__(self) -> str:
        """ Return string representation of a list of linked lists.
        """
        string_so_far = '['
        for bucket in self._buckets:
            string_so_far += bucket.__str__() + ', '
        return string_so_far[:-2] + ']'

    def __getitem__(self, key: str) -> Any:
        """ Returns the item the key is mapped to. Raise ValueError if not in table.
        """
        hash_code = self._get_hash_code(key)
        for item in self._buckets[hash_code]:
            if item[0] == key:
                return item[1]
        raise ValueError('Item is not in Hash Table')

    def __len__(self) -> int:
        """ Return the size of the hash table.
        """
        return self._size

    def __contains__(self, key: Any) -> bool:
        """ Return whether item is in the hash table.
        """
        hash_code = self._get_hash_code(key)
        for item in self._buckets[hash_code]:
            if item[0] == key:
                return True
        return False

    def _get_hash_code(self, key: str) -> int:
        """ Returns a hash code of the string.
        """
        hash_code = 0
        for char in key:
            hash_code = (ord(char) + hash_code) % len(self._buckets)
        return hash_code

    def add(self, key: str, item: Any) -> None:
        """ Adds the key-item pair to the hash table.
        """
        hash_code = self._get_hash_code(key)
        key_value_pair = (key, item)
        self._buckets[hash_code].append(key_value_pair)
        self._size += 1

"""
An implementation of a HashTable.

Contributors: <NAME>, and <NAME>.
"""
from __future__ import annotations
from typing import Any, Tuple
from lists.singly_linked_list import SinglyLinkedList


class HashTable:
    """ A Hash Table that is implemented using linked-list chaining.
        Assume all keys are Strings.
    """
    # This implementation will used linked-list chaining.
    _buckets: list[SinglyLinkedList[Tuple[str, Any]]]
    _size: int  # Size of Hash Table.

    def __init__(self, buckets: int) -> None:
        if buckets < 1:
            raise ValueError('Cannot have less than 1 buckets')

        self._buckets = [SinglyLinkedList() for bucket in range(0, buckets)]
        self._size = 0

    def __str__(self) -> str:
        """ Return string representation of a list of linked lists.
        """
        string_so_far = '['
        for bucket in self._buckets:
            string_so_far += bucket.__str__() + ', '
        return string_so_far[:-2] + ']'

    def __getitem__(self, key: str) -> Any:
        """ Returns the item the key is mapped to. Raise ValueError if not in table.
        """
        hash_code = self._get_hash_code(key)
        for item in self._buckets[hash_code]:
            if item[0] == key:
                return item[1]
        raise ValueError('Item is not in Hash Table')

    def __len__(self) -> int:
        """ Return the size of the hash table.
        """
        return self._size

    def __contains__(self, key: Any) -> bool:
        """ Return whether item is in the hash table.
        """
        hash_code = self._get_hash_code(key)
        for item in self._buckets[hash_code]:
            if item[0] == key:
                return True
        return False

    def _get_hash_code(self, key: str) -> int:
        """ Returns a hash code of the string.
        """
        hash_code = 0
        for char in key:
            hash_code = (ord(char) + hash_code) % len(self._buckets)
        return hash_code

    def add(self, key: str, item: Any) -> None:
        """ Adds the key-item pair to the hash table.
        """
        hash_code = self._get_hash_code(key)
        key_value_pair = (key, item)
        self._buckets[hash_code].append(key_value_pair)
        self._size += 1
An implementation of a HashTable.  Contributors: <NAME>, and <NAME>. A Hash Table that is implemented using linked-list chaining.         Assume all keys are Strings. # This implementation will used linked-list chaining. # Size of Hash Table. Return string representation of a list of linked lists. Returns the item the key is mapped to. Raise ValueError if not in table. Return the size of the hash table. Return whether item is in the hash table. Returns a hash code of the string. Adds the key-item pair to the hash table.