def _construct_from_list(self, ref_list):
     """
     **Reconstructs** the linked list from a list of values
     @param ref_list: reference list for constructing the linked list
     """
     self._head_node = Node(ref_list[0])
     [self.add_value_to_the_end(item) for item in ref_list[1:]]
 def __init__(self, value=None, ref_list='', by_list=False):
     """
     Can be constructed in two ways, when by_list is true, it constructs with ref_list otherwise it constructs with
     value
     @param value: value of head node
     @param ref_list: reference list for reconstructing the linked list
     @param by_list: <bool> whether we use reference list to construct
     """
     self._head_node = Node(value=value)
     if by_list is True:
         self._construct_from_list(ref_list)
 def add_value_to_head(self, value):
     """
     Add the value to the head of linked list
     @param value, value to te be added
     """
     new_node = Node(value)
     if not self._head_node:
         self._head_node = new_node
         return
     new_node.set_link_node(self._head_node)
     self._head_node = new_node
 def setUp(self):
     self.example_value_1 = 'example value 1'
     self.example_value_2 = 'example value 2'
     self.example_value_3 = 'example value 3'
     self.example_value_list = [1, '2', 3.0, 4]
     self.example_node_1 = Node(value=self.example_value_1)
     self.example_node_2 = Node(value=self.example_value_2)
     self.example_node_3 = Node(value=self.example_value_3)
     self.example_linked_list = LinkedList(self.example_value_1)
     self.example_stringified_list = 'example value 2\nexample value 1\n'
     self.example_stringified_list_2 = 'example value 1\nexample value 2\n'
     self.example_stringified_list_3 = '1\n2\n3.0\n4\n'
     self.example_empty_list = LinkedList()
     self.example_empty_list._head_node = None
     pass
 def insert_beginning(self, new_value):
     """
     Inserts the new node with new value to the beginning of the linked list
     @param new_value: value of the inserting new node
     """
     new_node = Node(value=new_value, link_node=self._head_node)
     self._head_node = new_node
class TestNode(unittest.TestCase):
    def setUp(self):
        self.example_node = 'node_1'
        self.example_value = 'example_value'
        self.example_link_node = 'example_link_node'
        self.example_node_with_properties = Node(
            value=self.example_value, link_node=self.example_link_node)

    @staticmethod
    def _create_node():
        """
        Create a Node instance
        @return: <Node> Node instance
        """
        return Node('example value')

    def test_set_link_node(self):
        """
        test interview.utils.node :: Node :: set_link_node
        """
        tests = [{
            "node": self.example_node,
            "returned": self.example_node,
        }]
        for test in tests:
            node = test.get("node")
            expected = test.get("returned")
            returned_node = self._create_node()
            returned_node.set_link_node(node)
            returned = returned_node._link_node
            self.assertEqual(expected, returned)

    def test_get_link_node(self):
        """
        test interview.utils.node :: Node :: get_link_node
        """
        expected = self.example_link_node
        returned = self.example_node_with_properties.get_link_node()
        self.assertEqual(expected, returned)

    def test_get_value(self):
        """
        test interview.utils.node :: Node :: get_value
        """
        expected = self.example_value
        returned = self.example_node_with_properties.get_value()
        self.assertEqual(expected, returned)
 def add_value(self, position, value):
     """
     Add note to the specified position,
     if position is larger than the length of linked list, place the new node to the end
     @param position: <int> the position where the node should be placed, order is from 0
     @param value: <value> the value to be added
     """
     if position == 0:
         self.add_value_to_head(value)
         return
     new_node = Node(value)
     count = 1
     current = self._head_node
     while current is not None:
         if count == position:
             new_node.set_link_node(current.get_link_node())
             current.set_link_node(new_node)
             return
         current = current.get_link_node()
         count += 1
     self.add_value_to_the_end(value)
 def add_value_to_the_end(self, value):
     """
     Add the value to the end of linked list
     @param value: value to be added
     """
     new_node = Node(value)
     if not self._head_node:
         self._head_node = new_node
         return
     current = self._head_node
     while current.get_link_node():
         current = current.get_link_node()
     current.set_link_node(new_node)
class LinkedList:
    def __init__(self, value=None, ref_list='', by_list=False):
        """
        Can be constructed in two ways, when by_list is true, it constructs with ref_list otherwise it constructs with
        value
        @param value: value of head node
        @param ref_list: reference list for reconstructing the linked list
        @param by_list: <bool> whether we use reference list to construct
        """
        self._head_node = Node(value=value)
        if by_list is True:
            self._construct_from_list(ref_list)

    def _construct_from_list(self, ref_list):
        """
        **Reconstructs** the linked list from a list of values
        @param ref_list: reference list for constructing the linked list
        """
        self._head_node = Node(ref_list[0])
        [self.add_value_to_the_end(item) for item in ref_list[1:]]

    def add_value(self, position, value):
        """
        Add note to the specified position,
        if position is larger than the length of linked list, place the new node to the end
        @param position: <int> the position where the node should be placed, order is from 0
        @param value: <value> the value to be added
        """
        if position == 0:
            self.add_value_to_head(value)
            return
        new_node = Node(value)
        count = 1
        current = self._head_node
        while current is not None:
            if count == position:
                new_node.set_link_node(current.get_link_node())
                current.set_link_node(new_node)
                return
            current = current.get_link_node()
            count += 1
        self.add_value_to_the_end(value)

    def add_value_to_head(self, value):
        """
        Add the value to the head of linked list
        @param value, value to te be added
        """
        new_node = Node(value)
        if not self._head_node:
            self._head_node = new_node
            return
        new_node.set_link_node(self._head_node)
        self._head_node = new_node

    def add_value_to_the_end(self, value):
        """
        Add the value to the end of linked list
        @param value: value to be added
        """
        new_node = Node(value)
        if not self._head_node:
            self._head_node = new_node
            return
        current = self._head_node
        while current.get_link_node():
            current = current.get_link_node()
        current.set_link_node(new_node)

    def get_head_node(self):
        """
        Gets the first node of the linked list
        @return: <Node> fist node
        """
        return self._head_node

    def insert_beginning(self, new_value):
        """
        Inserts the new node with new value to the beginning of the linked list
        @param new_value: value of the inserting new node
        """
        new_node = Node(value=new_value, link_node=self._head_node)
        self._head_node = new_node

    def remove_first_node_by_value(self, value):
        """
        Removes node by its **value**
        This will remove the first nodes by the value
        With Python, node will be removed automatically by garbage collection if no reference was pointing to it
        @param value: value of node(s) we want to remove
        """
        if self._head_node.get_value() == value:
            self._head_node = self._head_node.get_link_node()
            return
        current = self._head_node
        next_node = current.get_link_node()
        while next_node:
            if next_node.get_value() == value:
                current.set_link_node(next_node.get_link_node())
                return
            current = current.get_link_node()
            next_node = current.get_link_node(
            ) if current is not None else None

    def stringify_list(self):
        """
        Appends values of each node to a string separated by line
        @return: <str> appended string
        """
        current = self._head_node
        result_string = ''
        while current:
            result_string += str(current.get_value()) + '\n'
            current = current.get_link_node()
        return result_string
 def setUp(self):
     self.example_node = 'node_1'
     self.example_value = 'example_value'
     self.example_link_node = 'example_link_node'
     self.example_node_with_properties = Node(
         value=self.example_value, link_node=self.example_link_node)
 def _create_node():
     """
     Create a Node instance
     @return: <Node> Node instance
     """
     return Node('example value')