Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dictionaries - Warmup Challenge, Assignments and Implementations #40

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions assignments/Assignments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from Student import Student


def gol_hash(s):
total = 0
for char in s:
if char != '':
total += ord(char)
return total


def hash_object(s, method_one=False):
"""
* Approach One using the id
* This returns the address of the instance S(which is an int).
* Therefore, the hashes will only match if it is the same instance when comparing
That is
a = Object()
b = a
id(a) == id(b) # This will return true
Any other instance will be false, even if the variables of the class match-up
"""
if method_one:
return id(s)
"""
* Approach Two using the variables
* This uses the variables to return the hash value
* Therefore, the hashes will only match if they have the same variables / the combination sum is the same
"""
return gol_hash(s.get_name()) + s.get_age() + s.get_marks()


def histogram(s):
counter = dict()
arr_words = s.split()
max_word_length = 0
for word in arr_words:
if word in counter:
counter[word] += 1
else:
counter[word] = 1
max_word_length = max(max_word_length, len(word))

for word in counter:
temp_word = word + ':'
temp_value = '*' * counter[word]
print('{0:<{width}} {1}'.format(temp_word, temp_value, width=max_word_length + 1))


# Histograms example
histogram("Life is so so good")

# Object Hashing example
student_a = Student("Joshua Maina", 23, 123)
student_b = Student("Edith Nekesa", 23, 223)
student_c = student_a
student_d = Student("Joshua Maina", 23, 123)
students = [student_a, student_b, student_c, student_d]
for index, student in enumerate(students, 1):
print("Students {}".format(index))
print(student)
print("Student hash - method 1: {}\n"
"Student hash - method 2: {}".format(hash_object(student, method_one=True), hash_object(student)))
118 changes: 118 additions & 0 deletions assignments/GolDictionary-LL.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.next = None

def __repr__(self):
return "{} -> {}".format(self.key, self.value)


class GolDictionaryLL:
def __init__(self, size):
self.size = size
self.array = [None] * self.size
self.count = 0

def _hash(self, key):
total = 0
for char in key:
total += ord(char)
return total % self.size

def put(self, key, value):
hash_value = self._hash(key)
# Check for values
if self.array[hash_value] is None:
# If array position is empty
self.array[hash_value] = Node(key, value)
else:
curr_node = self.array[hash_value]
while curr_node.next is not None:
curr_node = curr_node.next
curr_node.next = Node(key, value)
self.count += 1

def get(self, key):
# Gets the address
hash_value = self._hash(key)
curr_node = self.array[hash_value]
if curr_node is None:
# Element not found
print("The element you are searching for doesn't exist")
return None
while curr_node.key != key:
curr_node = curr_node.next
if curr_node is None:
print("The element you are searching for doesn't exist")
return None
return curr_node.value

def delete(self, key):
# Gets the address
hash_value = self._hash(key)
curr_node = self.array[hash_value]
if curr_node is None:
# Element not found
print("The element you are searching for doesn't exist")
return False
previous_node = None
while curr_node.key != key:
previous_node = curr_node
curr_node = curr_node.next
if curr_node is None:
print("The element you are searching for doesn't exist")
return False
self.count -= 1
if previous_node is None:
# Deleting the first element
self.array[hash_value] = curr_node.next
return True
else:
previous_node.next = curr_node.next
return True

def load(self):
return self.count / self.size

def __repr__(self):
main_str = "The items in the dictionary are :\n"
for i in range(self.size):
main_str += "{} : ".format(i)
curr_node = self.array[i]
while curr_node is not None:
main_str += "{}, ".format(curr_node)
curr_node = curr_node.next
main_str += "\n"
return main_str


if __name__ == '__main__':
class_dictionary = GolDictionaryLL(5)
class_dictionary.put("s001", "Joshua")
class_dictionary.put("s002", "George")
class_dictionary.put("s003", "Collins")
print(class_dictionary)
class_dictionary.put("002s", "Joshua2")
print("To test the put function")
print(class_dictionary)

print(class_dictionary.get("002s"))
print(class_dictionary.get("s001"))
print(class_dictionary.get("s002"))
print(class_dictionary.get("s003"))
print("Trying against an Index Error")
print(class_dictionary.get("s004"))

print("To test the delete operation")
print(class_dictionary.delete("s002"))
print(class_dictionary)

print("Now we try and get the 002s element")
print(class_dictionary.get("002s"))

class_dictionary.put("s004", "Caleb")
class_dictionary.put("s005", "Edwin")
class_dictionary.put("s006", "Another Person")
print(class_dictionary)
print(class_dictionary.load())
117 changes: 117 additions & 0 deletions assignments/GolDictionary-LP.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
class GolDictionaryLinearProbe:
def __init__(self, size):
self.size = size
self.items = [None] * self.size
self.keys = [None] * self.size
self.count = 0

def _hash(self, key):
total = 0
for char in key:
total += ord(char)
return total % self.size

def _rehash(self, old_hash):
return (old_hash + 1) % self.size

def put(self, key, value):
hash_value = self._hash(key)
if self.load() == 1:
print("The dictionary is full. Consider deleting items")
return False
# Check for None and deleted values
if self.keys[hash_value] is None or self.keys[hash_value] is False:
self.keys[hash_value] = key
self.items[hash_value] = value
self.count += 1
return True
rehash_value = self._rehash(hash_value)
# Check for empty or deleted
while rehash_value != hash_value:
rehash_value = self._rehash(rehash_value)
if self.keys[rehash_value] is None or self.keys[rehash_value] is False:
self.keys[rehash_value] = key
self.items[rehash_value] = value
self.count += 1
return True
return False

def _getter(self, key):
"""
This returns the hash index for the key being searched
It is used by the get and delete method
"""
hash_value = self._hash(key)
if self.keys[hash_value] == key:
return hash_value

rehash_value = self._rehash(hash_value)
while rehash_value != hash_value:
# When it hits a False it rehashes so we avoid missing next values
rehash_value = self._rehash(rehash_value)
if self.keys[rehash_value] == key:
return rehash_value
# This means it is empty
if self.keys[rehash_value] is None:
return -1
return -1

def get(self, key):
hash_value = self._getter(key)
if hash_value == -1:
print("The element does not exist")
return self.items[hash_value]

def delete(self, key):
hash_value = self._getter(key)
if hash_value == -1:
print("The element doesn't exist")
return False

print("The data being deleted has the following components:\n"
"Key : {}\n"
"Value : {}", self.keys[hash_value], self.items[hash_value])
self.keys[hash_value] = False
self.items[hash_value] = False
self.count -= 1
return True

def load(self):
return self.count / self.size

def __repr__(self):
main_str = "The items in the dictionary are :\n"
for i in range(self.size):
main_str += "{} -> {}, ".format(self.keys[i], self.items[i])
return main_str


if __name__ == '__main__':
class_dictionary = GolDictionaryLinearProbe(5)
class_dictionary.put("s001", "Joshua")
class_dictionary.put("s002", "George")
class_dictionary.put("s003", "Collins")
print(class_dictionary)
class_dictionary.put("002s", "Joshua2")
print("To test the put function")
print(class_dictionary)

print(class_dictionary.get("002s"))
print(class_dictionary.get("s001"))
print(class_dictionary.get("s002"))
print(class_dictionary.get("s003"))
print("Trying against an Index Error")
print(class_dictionary.get("s004"))

print("To test the delete operation")
print(class_dictionary.delete("s002"))
print(class_dictionary)

print("Now we try and get the 002s element")
print(class_dictionary.get("002s"))

class_dictionary.put("s004", "Caleb")
class_dictionary.put("s005", "Edwin")
print("This put should fail due to load")
class_dictionary.put("s006", "Failed put")

18 changes: 18 additions & 0 deletions assignments/Student.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Student:
def __init__(self, name, age, marks):
self._name = name
self._age = age
self._marks = marks

def get_marks(self):
return self._marks

def get_age(self):
return self._age

def get_name(self):
return self._name

def __repr__(self) -> str:
return "Student name: {}; Student age: {}; Student marks: {}"\
.format(self._name, self._age, self._marks)
16 changes: 16 additions & 0 deletions classwork/05/WordFreq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
def wordFrequency(S):
arr_words = S.split()
if len(arr_words) == 0:
return 0
Counter = dict()
for word in arr_words:
if word in Counter:
Counter[word] += 1
else:
Counter[word] = 1
return max(Counter.values())

print(wordFrequency("Life is so so good"))
print(wordFrequency("All coders are introverts, George is a coder, therefore George is an introvert"))
print(wordFrequency("Life is good"))
print(wordFrequency(""))