https://www.codecademy.com/paths/computer-science/tracks/complex-data-structures/modules/cspath-hash-maps/projects/blossom
Below is my code, it works pretty well except for one thing: It doesn’t assign all the “flower_definitions” into self.array. When I call for the value of keys :rose, hyacinth, and wisteria, I get returned None. I was wondering if anyone knows why?
from linked_list import Node, LinkedList
from blossom_lib import flower_definitions
class HashMap:
def init(self,size):
self.array_size=size
self.array=[LinkedList() for i in range(size)]
def hash(self,key):
hash_code=sum(key.encode())
return hash_code
def compress(self,hash_code):
dab=hash_code%self.array_size
return dab
def assign(self,key,value):
hash_code=self.hash(key)
array_index=self.compress(hash_code)
payload=Node([key,value])
list_at_array=self.array[array_index]
for i in list_at_array:
if i[0]==key:
i[1]=value
list_at_array.insert(payload)
def retrieve(self,key):
hash_code=self.hash(key)
array_index=self.compress(hash_code)
list_at_index=self.array[array_index]
for i in list_at_index:
if i[0]==key:
return i[1]
else:
return None
blossom=HashMap(len(flower_definitions))
for flower in flower_definitions:
blossom.assign(flower[0],flower[1])
print(blossom.retrieve(“hyacinth”))
print(flower_definitions)
Hi @focussion ,
Please format the entirety of your code so that other users can see its indentation, which is essential for defining the structure of a Python program. You can find advice on how to do that in How to ask good questions (and get good answers).
EDIT: October 3, 2018:
From a portion of your code that is formatted, it is evident that the else
block within your retrieve
method is matched to an if
block header, due to its degree of indentation. It should, instead, be matched to the for
loop header so that this line executes only if the loop completes all its iterations without finding a valid key …
return None
I attempted this as well. By unindenting the else: return None in the .retrieve() method to be outside the if statement but in response to the for loop, it fixed my problem. I have a slight bit of confusion as to why (perhaps it’s because those 4 flowers were indexed at already filled buckets in the array, so they were the ones where linked lists were implemented), but I hope my input helps you figure out your own question!
I got the same problem here, so I’m not sure if it’s my retrieve or assign methods that are screwing up:
def assign(self, key, value):
array_index = self.compress(self.hash(key))
payload = Node([key, value])
list_at_array = self.array[array_index]
for item in list_at_array:
if key == item[0]:
item[1] = value
self.array[array_index] = list_at_array.insert(payload)
def retrieve(self, key):
array_index = self.compress(self.hash(key))
list_at_index = self.array[array_index]
for i in list_at_index:
if i[0] == key:
return i[1]
if i[0] is None or i[0] != key:
return
blossom = HashMap(len(flower_definitions))
for flower in flower_definitions:
blossom.assign(flower[0], flower[1])
print(blossom.retrieve('daisy'))
@zchrybwmn,
The else
header should be matched with the for
header. If key
is found within list_at_index
, which is the bucket to which key
hashes, the value associated with key
gets return
ed and execution of the retrieve
function ceases. However, if all iterations of the loop complete without key
being found, then key
is not in the database at all. If, and only if, a loop completes all its iterations without being interrupted, and if there is an associated else
block, that block will execute. In this case, None
will be the return
value, indicating to us that key
was not found.
2 Likes
Hi @jhern603,
Instead of this …
if i[0] is None or i[0] != key:
return
… create an else
header that aligns with the for
loop header. Inside the else
block, just return None
.
That block should execute if key
is not found.
Regardless of the else
block being formatted as that, I still get None
after running script.py
@jhern603 ,
The assign
method also needs some revision.
This should not be an assignment statement …
self.array[array_index] = list_at_array.insert(payload)
It should simply be an appropriate call to the insert
method, as follows …
list_at_array.insert(payload)
Also, you should only call the insert
method if the key was not found in the existing data.
Accordingly, you can rearrange the assign
method as follows …
def assign(self, key, value):
array_index = self.compress(self.hash(key))
payload = Node([key, value])
list_at_array = self.array[array_index]
for item in list_at_array:
if key == item[0]:
item[1] = value
break
else:
list_at_array.insert(payload)
Then the else
block will only execute if break
was not executed because key
did not already exist in the database.
1 Like