Blossom attribute error in OOP

Hey there, quick question:

Why does my logic below in the assign() method not work: instead of node[0] and node[1] I used node.value[0] and node.value[1]. By the node definition, we have the following constructor: self.value = value and the value is the key-value pair i.e. [key,value]. However, it tells me that the item within the linked list (in my opinion item = instances of Node class) does not have a value attribute. Many thanks in advance!!

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 number in range(size)]

      

  def hash(self, key):

    return sum(key.encode())

  def compress(self, hash_code):

     return hash_code % self.array_size

  

  def assign(self, key, value):

    array_index=self.compress(self.hash(key))

    payload = Node([key, value])

    #self.array[array_index] = [key, value]

    list_at_array = self.array[array_index]

    for node in list_at_array:

      if node.value[0] == key: #as node has the above definition of payload = Node([key, value]) it basically says we have a node with value = [key, value]

        node.value[1] = value

    list_at_array.insert(payload)

    

  def retrieve(self, key):

    array_index = self.compress(self.hash(key)) 

    list_at_index = self.array[array_index]

    for node in list_at_index:

      if node.value[0] == key:

        return node.value[1]

      else:

        return None  

    if payload[0] == key:

      return payload[1]

    elif payload[0] == None or payload[0]  !=key:

      return None

blossom = HashMap(len(flower_definitions))

for flower in flower_definitions:

  blossom.assign(flower[0],flower[1])

print(flower_definitions)

This is because list_at_array is not a list of the nodes. Look at what you’re importing from blossom_lib.py. It is a list of lists where the sublists are the individual flowers. Therefore, list_at_array is actually representative of a single flower and therefore its items are not nodes (meaning they have no value property). The same thing applies in your retrieve() method.


Additionally, what is the use for this code? None of it will ever be executed since the function will always reach a return statement in the previous if-else block.

I still don’t get why we have a normal list at list_at_array.
My logic: list_at_array = self.array[array_index], where array_index marks the position in the array where we add the key-value pair. The array is a number of LinkedLists - whose items are nodes - with the size of all the flowers that are stored within flower_definitions. Hence, list_at_array selects the first entry of the selected LinkedList object - by definition a node.
If we now just decide that we add a key-value pair to the LinkedList called list_at_array then we basically tell the LinkedList object to behave like a normal list?

Thanks a lot!

I would be very grateful if you or anyone could help me solve this problem :slight_smile: I spent several hours and still not able to crack it. Thanks a lot.

Sorry for the delay, was busy. Let me try to clarify my previous response, it may have been a bit confusing.

self.array is a list of linked lists and list_at_array is one of those linked lists. list_at_array will contain zero or more nodes. Each of those nodes is representative of a single flower. The compressed hash of each flower’s key (i.e. the flower name) is used to determine which linked list the flower, or node, will be put into. If the linked list is empty, the flower is inserted. If the flower’s key can already be found in the linked list, the value of that node in the linked list is updated. If a collision occurs, we add on a new node to the linked list.

If you look at the LinkedList class in linked_list.py, you’ll see the following dunder method defined. You can read more on __iter__ here, but this method below essentially allows the linked list to be iterated over like a normal list would.

  def __iter__(self):
    current_node = self.head_node
    while(current_node):
      yield current_node.get_value()
      current_node = current_node.get_next_node()

When we add a key-value pair to list_at_array, we are using the .insert() method, which you can also find in linked_list.py. This inserts the new node as seen in the previous lessons on linked lists.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.