Trouble in Poject: Blossom in Computer Science Path course


#1

blossom_lib.py

flower_definitions = [['begonia', 'cautiousness'], ['chrysanthemum', 'cheerfulness'], ['carnation', 'memories'], ['daisy', 'innocence'], ['hyacinth', 'playfulness'], ['lavender', 'devotion'], ['magnolia', 'dignity'], ['morning glory', 'unrequited love'], ['periwinkle', 'new friendship'], ['poppy', 'rest'], ['rose', 'love'], ['snapdragon', 'grace'], ['sunflower', 'longevity'], ['wisteria', 'good luck']]

linked_list.py

class Node:
  def __init__(self, value):
    self.value = value
    
  def get_value(self):
    return self.value
  
  def get_next_node(self):
    return self.next_node
  
  def set_next_node(self, next_node):
    self.next_node = next_node

class LinkedList:
  def __init__(self, head_node=None):
    self.head_node = head_node
  
  def insert(self, new_node):
    current_node = self.head_node

    if not current_node:
      self.head_node = new_node

    while(current_node):
      next_node = current_node.get_next_node()
      if not next_node:
        current_node.set_next_node(new_node)

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

script.py

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(self.array_size)]
    
  def hash(self, key):
    hash_code = sum(key.encode())
    return hash_code
  
  def compress(self, hash_code):
    return hash_code % self.array_size
  
  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 node in list_at_array:
      if node[0] == key:
        node[1] = value
        return
    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]
    print(key)
    for node in list_at_index:
      if node[0] == key:
       	print(node[0], node[1])
        return node[1]
    return None
  
blossom = HashMap(len(flower_definitions))
for flower in flower_definitions:
  blossom.assign(flower[0], flower[1])
  
print(blossom.retrieve('daisy'))
print(blossom.retrieve('begonia'))

In Computer Science Path, this code (script.py is written by me, and code academy provided with linked_list.py and blossom_lib.py) belongs to project: “Blossom” in Complex Data Structures, Learn HashMap.

Here, you can see my code(script.py), I am confused why it is not working?

I tried to debug it, and found that linked_list.py have an iter method. I did some research and found that its a generator method, since it uses ‘yield’. I think there is a problem somewhere in it, since it is not iterating correctly. I found that it should have a next method too. Please someone suggest what is wrong here? Am I right about next method, if so, then how to implement it? Or my code (script.py) have some problem?


#2

A generator creates an iterator when called, you do not need to implement __next__, that’s what the generator does for you

You say it isn’t iterating correctly, if you consider how it should iterate and what happens instead then you’ve probably got your answer to what is wrong about it.


#3

@ionatan Thank you for your answer. I appreciate your response.

I put again a lot of time on it. Still did not get why it is wrong. The problem is in assign() method in HashMap class in script.py. It have a for loop:

for node in list_at_array:
      if node[0] == key:
        node[1] = value
        return

list_at_array is an instance of LinkedList class and should iterate with a for loop because of __iter__() method in that class. But when I add a print statement on node like below:

for node in list_at_array:
      print(node)
      if node[0] == key:
        node[1] = value
        return

If list_at_array do not have a node, then its okay; but if it does have a node then it get stuck at that node (i.e. the first node of list_at_array) for infinity, i.e. it prints that value infinitely, hence do not get to the next node. That’s why I think its not iterating correctly.

I appreciate any thought on this.


#4

By comparing what should happen and what does happen you find the difference and that difference is the change that you need to make. Fix the part that is supposed to traverse nodes.


#5

Hi, after some research on what the yield keyword actually does and further debugging I finally figured out what’s wrong. There are actually 3 errors in linked_list.py:

Firstly, there isn’t a next_node attribute in the constructor, which caused an error for me, not sure if you’ve encountered it.

class Node:
  def __init__(self, value):
    self.value = value
    self.next_node = None

Second, current_node was not being updated in the while loop.

  def insert(self, new_node):
    current_node = self.head_node

    if not current_node:
      self.head_node = new_node

    while(current_node):
      next_node = current_node.get_next_node()
      if not next_node:
        current_node.set_next_node(new_node)
      current_node = next_node

And finally, like the while loop above, the while loop in the iter method is not updating current_node as well.

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

Explanation on “yield” can be found here: https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/


#6

@bryan2402 Thank you so much. This solves my problem completely.

I noticed the first part today and corrected it, but did not see the second one inside insert() method, while loop. Also I was trying to write __next()__ method instead of the last line you added in __iter__() method. I like the last line in your __iter__() better than writing another method. So I will go with that. Thank you for your time.


#7

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