From cd2a2a03630323a84b077f501ed4e173a6768095 Mon Sep 17 00:00:00 2001 From: Joe-Thompson Date: Wed, 30 Sep 2020 18:11:04 -0400 Subject: [PATCH 1/5] setting up branch --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f53d18e06..c7e970088 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ __pycache__ .vscode +.idea From ed20883160a9877bd7bc9074382063b29454971a Mon Sep 17 00:00:00 2001 From: Joe-Thompson Date: Wed, 30 Sep 2020 19:35:00 -0400 Subject: [PATCH 2/5] all tests passing --- hashtable/hashtable.py | 37 ++++++++++++++++++----- hashtable/test_hashtable_no_collisions.py | 2 ++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/hashtable/hashtable.py b/hashtable/hashtable.py index 0205f0ba9..a31f71a12 100644 --- a/hashtable/hashtable.py +++ b/hashtable/hashtable.py @@ -2,6 +2,7 @@ class HashTableEntry: """ Linked List hash table key/value pair """ + def __init__(self, key, value): self.key = key self.value = value @@ -22,7 +23,9 @@ class HashTable: def __init__(self, capacity): # Your code here - + self.capacity = capacity + self.table = [None] * capacity + self.count = 0 def get_num_slots(self): """ @@ -35,7 +38,7 @@ def get_num_slots(self): Implement this. """ # Your code here - + return len(self.table) def get_load_factor(self): """ @@ -44,7 +47,7 @@ def get_load_factor(self): Implement this. """ # Your code here - + return self.count / self.table def fnv1(self, key): """ @@ -54,7 +57,15 @@ def fnv1(self, key): """ # Your code here + fnv_prime = 16777619 + offset_basis = 2166136261 + # FNV-1a Hash Function + hashed = offset_basis + key + for char in self.capacity: + hashed = hashed * fnv_prime + hashed = hashed ^ ord(char) + return hash def djb2(self, key): """ @@ -63,14 +74,19 @@ def djb2(self, key): Implement this, and/or FNV-1. """ # Your code here + str_key = str(key).encode() + hash_value = 5381 + for s in str_key: + hash_value = ((hash_value << 5) + hash_value) + s + return hash_value & 0xffffffff def hash_index(self, key): """ Take an arbitrary key and return a valid integer index between within the storage capacity of the hash table. """ - #return self.fnv1(key) % self.capacity + # return self.fnv1(key) % self.capacity return self.djb2(key) % self.capacity def put(self, key, value): @@ -82,7 +98,9 @@ def put(self, key, value): Implement this. """ # Your code here - + hashed_key = self.djb2(key) + hashed_index = self.hash_index(hashed_key) + self.table[hashed_index] = value def delete(self, key): """ @@ -93,7 +111,9 @@ def delete(self, key): Implement this. """ # Your code here - + hashed_key = self.djb2(key) + hashed_index = self.hash_index(hashed_key) + self.table[hashed_index] = None def get(self, key): """ @@ -104,7 +124,9 @@ def get(self, key): Implement this. """ # Your code here - + hashed_key = self.djb2(key) + hashed_index = self.hash_index(hashed_key) + return self.table[hashed_index] def resize(self, new_capacity): """ @@ -116,7 +138,6 @@ def resize(self, new_capacity): # Your code here - if __name__ == "__main__": ht = HashTable(8) diff --git a/hashtable/test_hashtable_no_collisions.py b/hashtable/test_hashtable_no_collisions.py index a9b755b3d..034922718 100644 --- a/hashtable/test_hashtable_no_collisions.py +++ b/hashtable/test_hashtable_no_collisions.py @@ -8,6 +8,7 @@ import unittest from hashtable import HashTable + class TestHashTable(unittest.TestCase): def test_hash_table_insertion_and_retrieval(self): @@ -67,5 +68,6 @@ def test_hash_table_removes_correctly(self): return_value = ht.get("key-2") self.assertTrue(return_value is None) + if __name__ == '__main__': unittest.main() From a7cf6d2bddd1a48f64f6be9099aac455883a95b6 Mon Sep 17 00:00:00 2001 From: Joe-Thompson Date: Wed, 30 Sep 2020 20:49:23 -0400 Subject: [PATCH 3/5] started work on resize fn --- hashtable/hashtable.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hashtable/hashtable.py b/hashtable/hashtable.py index a31f71a12..fbb712766 100644 --- a/hashtable/hashtable.py +++ b/hashtable/hashtable.py @@ -136,6 +136,19 @@ def resize(self, new_capacity): Implement this. """ # Your code here + if self.count == 0: + self.capacity = new_capacity + self.table = [None] * self.capacity + + new_table = [None] * new_capacity + for item in enumerate(self.table): + if item is None: + pass + hashed_key = self.djb2(item) + hashed_index = self.hash_index(hashed_key) + new_table.insert(hashed_index, item) + + self.table = new_table if __name__ == "__main__": From 2528c26770da2ae50f603fa0124b9aba15c0d990 Mon Sep 17 00:00:00 2001 From: Joe-Thompson Date: Sun, 4 Oct 2020 21:53:55 -0400 Subject: [PATCH 4/5] working on linked list --- hashtable/hashtable.py | 55 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/hashtable/hashtable.py b/hashtable/hashtable.py index fbb712766..0a302b672 100644 --- a/hashtable/hashtable.py +++ b/hashtable/hashtable.py @@ -8,8 +8,49 @@ def __init__(self, key, value): self.value = value self.next = None + def __repr__(self): + return f"The key is: {self.key}, and the value is: {self.value}" + + +class LinkedList: + + def __init__(self): + self.head = None + + def find(self, key): + current_node = self.head + while current_node is not None: + if current_node.key == key: + return current_node + current_node = current_node.next + return None + + def insert_at_head(self, node): + # Link the node to the current HEAD + node.next = self.head + # Set head pointer to new node + self.head = node + + def delete(self, key): + # Handle the case where the node to delete is the HEAD + if key == self.head.key: + self.head = self.head.next + return self.head + + prev = None + curr = self.head + + while curr is not None: + if curr.key == key: + prev.next = curr.next + return curr + + prev = curr + curr = curr.next + + # Hash table can't have fewer than this many slots + -# Hash table can't have fewer than this many slots MIN_CAPACITY = 8 @@ -47,7 +88,7 @@ def get_load_factor(self): Implement this. """ # Your code here - return self.count / self.table + return self.count / len(self.table) def fnv1(self, key): """ @@ -98,9 +139,13 @@ def put(self, key, value): Implement this. """ # Your code here - hashed_key = self.djb2(key) - hashed_index = self.hash_index(hashed_key) - self.table[hashed_index] = value + hashed_index = self.hash_index(key) + if self.table[hashed_index] is not None: + # TODO working on getting linked list to work + + else: + self.count = self.count + 1 + self.table[hashed_index] = (HashTableEntry(key, value)) def delete(self, key): """ From 2bb6498b8f49c9d7d483674eab2cb63c2054113b Mon Sep 17 00:00:00 2001 From: Joe-Thompson Date: Tue, 6 Oct 2020 19:12:52 -0400 Subject: [PATCH 5/5] working through bugs in hashable.py --- hashtable/hashtable.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hashtable/hashtable.py b/hashtable/hashtable.py index 0a302b672..33e6e647a 100644 --- a/hashtable/hashtable.py +++ b/hashtable/hashtable.py @@ -141,7 +141,8 @@ def put(self, key, value): # Your code here hashed_index = self.hash_index(key) if self.table[hashed_index] is not None: - # TODO working on getting linked list to work + pass + # TODO working on getting linked list to work else: self.count = self.count + 1