From 18d5662c6bfd36ea598625ffba06b15620552a48 Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Fri, 19 Sep 2025 06:33:03 +0500 Subject: [PATCH 1/8] started hashtables --- data_structures/hash/hash_table.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index c1c05ced..35a0aae4 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -1,13 +1,21 @@ """ Create a hash table from scratch. Use chaining for hash collision """ - -class HashTable: - - +# the size will be such that it will start size small and when full it will copy everything to the new bigger sized table +class HashTable: + class __node: + def __init__(self,val,next = None): + self.val = val + self.next = next + def __eq__(self,other): + if not(isinstance(other,HashTable.__node)): + return False + return self.val == other.val + def __init__(self): - self.hash_table = - + self.hash_table = [] + self.__curr_size = 1000 + def check_collision(self): pass @@ -25,5 +33,11 @@ def delete(self): pass - def get(self): - pass + def get(self,ele): + """access the value""" + hash_value = self.hash_function(ele) + + def hash_function(self,ele): + """return hash value for the ele""" + # should support all data type such as tup int float str bool + \ No newline at end of file From c8d1cddc164175927a88eff0d84e0110b82093c2 Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Fri, 19 Sep 2025 18:25:24 +0500 Subject: [PATCH 2/8] hashfunctiuon --- data_structures/hash/hash_table.py | 45 ++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index 35a0aae4..3b0b2d77 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -2,20 +2,21 @@ Create a hash table from scratch. Use chaining for hash collision """ # the size will be such that it will start size small and when full it will copy everything to the new bigger sized table + class HashTable: class __node: def __init__(self,val,next = None): self.val = val self.next = next - def __eq__(self,other): - if not(isinstance(other,HashTable.__node)): + def __eq__(self, other): + # Use self.__class__ so it's always the same node type + if not isinstance(other, self.__class__): return False return self.val == other.val - + def __init__(self): - self.hash_table = [] self.__curr_size = 1000 - + self.hash_table = [None] * self.__curr_size def check_collision(self): pass @@ -34,10 +35,42 @@ def delete(self): def get(self,ele): - """access the value""" + """access the value of ele = key""" hash_value = self.hash_function(ele) def hash_function(self,ele): """return hash value for the ele""" # should support all data type such as tup int float str bool + def for_int_float(ele): + return (pow(ele,3)*10)-(pow(ele,2)//7) - ele + + def for_str(ele): + + integer = 0 + k = 1 + for i in ele: + integer += k*(ord(i)) + k += 1 + ele = integer + return (pow(ele,3)*10)+(pow(ele,2)//7) - ele + def for_tup(ele): + total = 0 + k = True + for i in ele: + if isinstance(ele,(int,float)): + answer = for_int_float(ele) + elif isinstance(ele,str): + answer = for_str(ele) + + if isinstance(ele,(int,float)): + return for_int_float(ele) + elif isinstance(ele,str): + return for_str(ele) + + elif isinstance(ele,tuple): + + + + + \ No newline at end of file From 58a857c783a9dc60ea4d2c0344fe9d360c29632d Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Sun, 21 Sep 2025 10:11:42 +0500 Subject: [PATCH 3/8] insert com,pleted --- data_structures/hash/hash_table.py | 52 ++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index 3b0b2d77..97b30220 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -16,7 +16,7 @@ def __eq__(self, other): def __init__(self): self.__curr_size = 1000 - self.hash_table = [None] * self.__curr_size + self.__hash_table = [None] * self.__curr_size def check_collision(self): pass @@ -26,23 +26,40 @@ def add_to_linked_list(self): pass - def insert(self): - pass + def insert(self,ele): + hash_value = self.hash_function(ele) + index = hash_value%self.__curr_size + temp =self.__node(ele) + + if self.__hash_table[index] is None: + self.__hash_table[index] = temp + + else: + head = self.__hash_table[index] + prev = head + curr = head.next + while curr is not None: + curr = curr.next + prev = prev.next + assert prev.next is None + prev.next = temp + - def delete(self): - pass + def delete(self,ele): + hash_value = self.hash_function(ele) + index = hash_value%self.__curr_size + def get(self,ele): """access the value of ele = key""" - hash_value = self.hash_function(ele) - + def hash_function(self,ele): """return hash value for the ele""" # should support all data type such as tup int float str bool def for_int_float(ele): - return (pow(ele,3)*10)-(pow(ele,2)//7) - ele + return (ele*10)+(pow(ele,2)//7) + ele def for_str(ele): @@ -52,23 +69,30 @@ def for_str(ele): integer += k*(ord(i)) k += 1 ele = integer - return (pow(ele,3)*10)+(pow(ele,2)//7) - ele - def for_tup(ele): - total = 0 - k = True + return (ele*10)+(pow(ele,2)//7) + ele + + def for_tup(ele,total = 0): for i in ele: if isinstance(ele,(int,float)): answer = for_int_float(ele) elif isinstance(ele,str): answer = for_str(ele) - + elif isinstance(ele,tuple): + answer = for_tup(ele,total+1) + else: + raise Exception(f"UNHASHABLE ITEM {ele}") + total += answer + return total if isinstance(ele,(int,float)): return for_int_float(ele) elif isinstance(ele,str): return for_str(ele) elif isinstance(ele,tuple): - + return for_tup(ele) + else: + raise Exception(f"UNHASHABLE ITEM {ele}") + From 78135005cb2303fdc32cd75a36d1166fac5d162e Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Sun, 21 Sep 2025 10:15:44 +0500 Subject: [PATCH 4/8] fixed insert + dunder for it --- data_structures/hash/hash_table.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index 97b30220..2523c24f 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -18,18 +18,11 @@ def __init__(self): self.__curr_size = 1000 self.__hash_table = [None] * self.__curr_size - def check_collision(self): - pass - - def add_to_linked_list(self): - pass - - - def insert(self,ele): - hash_value = self.hash_function(ele) + def __insert(self,key,value): + hash_value = self.hash_function(key) index = hash_value%self.__curr_size - temp =self.__node(ele) + temp =self.__node(value) if self.__hash_table[index] is None: self.__hash_table[index] = temp @@ -93,7 +86,8 @@ def for_tup(ele,total = 0): else: raise Exception(f"UNHASHABLE ITEM {ele}") - + def __setitem__(self, key, value): + self.__insert(key,value) From 8e2858598238f942f4a8baceccb96119dd459b7c Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Sun, 21 Sep 2025 10:20:14 +0500 Subject: [PATCH 5/8] fixed hashfunction --- data_structures/hash/hash_table.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index 2523c24f..f1d01228 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -66,16 +66,17 @@ def for_str(ele): def for_tup(ele,total = 0): for i in ele: - if isinstance(ele,(int,float)): - answer = for_int_float(ele) - elif isinstance(ele,str): - answer = for_str(ele) - elif isinstance(ele,tuple): - answer = for_tup(ele,total+1) + if isinstance(i,(int,float)): + answer = for_int_float(i) + elif isinstance(i,str): + answer = for_str(i) + elif isinstance(i,tuple): + answer = for_tup(i,total+1) else: raise Exception(f"UNHASHABLE ITEM {ele}") total += answer return total + if isinstance(ele,(int,float)): return for_int_float(ele) elif isinstance(ele,str): @@ -88,7 +89,7 @@ def for_tup(ele,total = 0): def __setitem__(self, key, value): self.__insert(key,value) - + \ No newline at end of file From 83eda6279a184c16304b5b92bc2958640614e9ca Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Sun, 21 Sep 2025 10:27:50 +0500 Subject: [PATCH 6/8] get done we did change in string the value to storing key value for getting --- data_structures/hash/hash_table.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index f1d01228..973461a7 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -22,7 +22,7 @@ def __init__(self): def __insert(self,key,value): hash_value = self.hash_function(key) index = hash_value%self.__curr_size - temp =self.__node(value) + temp =self.__node(key,value)# so i can identify which node have the value if self.__hash_table[index] is None: self.__hash_table[index] = temp @@ -45,8 +45,20 @@ def delete(self,ele): - def get(self,ele): + def __get(self,ele): """access the value of ele = key""" + hash_value = self.hash_function(ele) + index = hash_value%self.__curr_size + if ele[index] == None: + raise Exception("Error") + + head = ele[index] + while head is not None: + if head.val[0] == ele: + return head.val[1] + head = head.next + raise Exception("error") + def hash_function(self,ele): """return hash value for the ele""" @@ -88,7 +100,10 @@ def for_tup(ele,total = 0): raise Exception(f"UNHASHABLE ITEM {ele}") def __setitem__(self, key, value): - self.__insert(key,value) + self.__insert(key,value) + + def __getitem__(self,key): + return(self.__get(key)) From d865a476585cba06864a604c60b28af9de0a16da Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Sun, 21 Sep 2025 11:15:21 +0500 Subject: [PATCH 7/8] completed --- data_structures/hash/hash_table.py | 43 +++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index 973461a7..1c40b31f 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -22,7 +22,7 @@ def __init__(self): def __insert(self,key,value): hash_value = self.hash_function(key) index = hash_value%self.__curr_size - temp =self.__node(key,value)# so i can identify which node have the value + temp =self.__node((key,value))# so i can identify which node have the value if self.__hash_table[index] is None: self.__hash_table[index] = temp @@ -39,9 +39,38 @@ def __insert(self,key,value): - def delete(self,ele): + def __delete(self,ele): hash_value = self.hash_function(ele) index = hash_value%self.__curr_size + if self.__hash_table[index] is None: + return + + else: + prev = None + head = self.__hash_table[index] + while head is not None: + if head.val[0]==ele: + nex = head.next + while nex is not None: + + head.val = nex.val + prev = head + head = head.next + nex = nex.next + if prev is None: + # first element + temp = head.next + head.next = None + self.__hash_table = temp + else: + assert head.next is None + prev.next = None + del head + return + + prev = head + head = head.next + return @@ -49,10 +78,10 @@ def __get(self,ele): """access the value of ele = key""" hash_value = self.hash_function(ele) index = hash_value%self.__curr_size - if ele[index] == None: + if self.__hash_table[index] == None: raise Exception("Error") - head = ele[index] + head = self.__hash_table[index] while head is not None: if head.val[0] == ele: return head.val[1] @@ -105,6 +134,8 @@ def __setitem__(self, key, value): def __getitem__(self,key): return(self.__get(key)) + def __delete__(self,key): + self.__delete(key) + - - \ No newline at end of file + \ No newline at end of file From 99dd08dc6e470dacc65091b66894163da9336617 Mon Sep 17 00:00:00 2001 From: Huzaifa Rehman Date: Sun, 21 Sep 2025 11:22:27 +0500 Subject: [PATCH 8/8] added 'in' method --- data_structures/hash/hash_table.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/data_structures/hash/hash_table.py b/data_structures/hash/hash_table.py index 1c40b31f..fd099efd 100644 --- a/data_structures/hash/hash_table.py +++ b/data_structures/hash/hash_table.py @@ -79,14 +79,14 @@ def __get(self,ele): hash_value = self.hash_function(ele) index = hash_value%self.__curr_size if self.__hash_table[index] == None: - raise Exception("Error") + raise KeyError head = self.__hash_table[index] while head is not None: if head.val[0] == ele: return head.val[1] head = head.next - raise Exception("error") + raise KeyError def hash_function(self,ele): @@ -137,5 +137,9 @@ def __getitem__(self,key): def __delete__(self,key): self.__delete(key) - - \ No newline at end of file + def __contains__(self,item): + try: + self.__get(item) + return True + except KeyError: + return False \ No newline at end of file