import sys sys.path.insert(0, '../') from ll import LinkedList ll = LinkedList() ll.append(20) ll.prepend(19) ll.append(21) print("Is 21 present?", ll.find(21)) print("Is 22 present?", ll.find(22)) print(ll) print("Deleting", ll.delete(20)) print(ll) print("Deleting 23", ll.delete(23)) ll.insertAtPos(20, 1) print("After insertion of 20 at 1", ll) print("Cycle length", ll.detectCycleLen()) print("Creating a 3-cycle", ll.createcycle(19)) print("Next of 21:", ll.last.next) print("Cycle length", ll.detectCycleLen()) print("Chain length", ll.findlen()) ll.createcycle(20) print("Changing to 2-cycle", ll.last, "<->", ll.last.next) print("Cycle length", ll.detectCycleLen()) print("Chain length", ll.findlen()) print("LL now:", ll) ll.delete(19) print("Deleting head", ll) ll.delete(21) print("Deleting last", ll)
class TestLinkedListMethods(unittest.TestCase): def __init__(self, *args, **kwargs): n1 = Node(12) n2 = Node(55) n3 = Node(12) n1.next = n2 n2.next = n3 self.linked_list = LinkedList() self.linked_list.head = n1 self.linked_list.tail = n3 super(TestLinkedListMethods, self).__init__(*args, **kwargs) def test_add_in_tail(self): NODE_VAL = 128 self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.tail self.assertEqual(node.value, NODE_VAL) NODE_VAL = None self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.tail self.assertEqual(node.value, NODE_VAL) NODE_VAL = 'text' self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.tail self.assertEqual(node.value, NODE_VAL) NODE_VAL = ['test', 12] self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.tail self.assertEqual(node.value, NODE_VAL) def test_print_all_nodes(self): import io from contextlib import redirect_stdout f = io.StringIO() with redirect_stdout(f): self.linked_list.print_all_nodes() actual = f.getvalue() expected = "12\n55\n12\n" self.assertEqual(actual, expected) def test_find(self): # поиск значения NODE_VAL = 12 node = self.linked_list.find(NODE_VAL) self.assertEqual(node.value, NODE_VAL) # поиск несуществующего значения NODE_VAL = 128 node = self.linked_list.find(NODE_VAL) self.assertIsNone(node) # поиск по None NODE_VAL = None self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.find(NODE_VAL) self.assertEqual(node.value, NODE_VAL) # поиск по "сложному" типу данных NODE_VAL = ['test', 12] self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.find(NODE_VAL) self.assertEqual(node.value, NODE_VAL) # поиск по нулевому значению NODE_VAL = 0 self.linked_list.add_in_tail(Node(NODE_VAL)) node = self.linked_list.find(NODE_VAL) self.assertEqual(node.value, NODE_VAL) # поиск в пустом списке linked_list = LinkedList() node = linked_list.find(12) self.assertIsNone(node) # поиск в списке из одного узла linked_list.add_in_tail(Node(12)) node = linked_list.find(12) self.assertEqual(node.value, 12) node = linked_list.find(10) self.assertIsNone(node) def test_find_all(self): # поиск значения NODE_VAL = 12 nodes = self.linked_list.find_all(NODE_VAL) self.assertEqual(len(nodes), 2) for node in nodes: self.assertEqual(node.value, NODE_VAL) # поиск по "сложному" типу данных NODE_VAL = ['test', 12] self.linked_list.add_in_tail(Node(NODE_VAL)) nodes = self.linked_list.find_all(NODE_VAL) self.assertEqual(len(nodes), 1) for node in nodes: self.assertEqual(node.value, NODE_VAL) # поиск несуществующего значения NODE_VAL = 120 nodes = self.linked_list.find_all(NODE_VAL) self.assertEqual(len(nodes), 0) # получение всех узлов списка nodes = self.linked_list.find_all() self.assertEqual(len(nodes), 4) # поиск по None NODE_VAL = None nodes = self.linked_list.find_all(NODE_VAL) self.assertEqual(len(nodes), 4) # поиск по нулевому значению NODE_VAL = 0 self.linked_list.add_in_tail(Node(NODE_VAL)) nodes = self.linked_list.find_all(NODE_VAL) self.assertEqual(len(nodes), 1) # поиск в пустом списке linked_list = LinkedList() nodes = linked_list.find_all(12) self.assertEqual(len(nodes), 0) # поиск в списке из одного узла linked_list.add_in_tail(Node(12)) nodes = linked_list.find_all(12) self.assertEqual(len(nodes), 1) for node in nodes: self.assertEqual(node.value, 12) nodes = linked_list.find_all(10) self.assertEqual(len(nodes), 0) def test_delete(self): # удаление первого найденого элемента из нескольких найденных NODE_VALUE = 12 nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 2) self.linked_list.delete(NODE_VALUE) nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 1) self.assertEqual(self.linked_list.head.value, 55) self.assertEqual(self.linked_list.tail.value, 12) # удаление всех найденных элементов self.linked_list.add_in_tail(Node(NODE_VALUE)) nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 2) self.linked_list.delete(NODE_VALUE, True) nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 0) self.assertEqual(self.linked_list.tail.value, 55) # удаление единственного элемента в списке self.linked_list.delete(55) self.assertEqual(self.linked_list.len(), 0) self.assertIsNone(self.linked_list.head) self.assertIsNone(self.linked_list.tail) # удаление элемента из пустого списка self.assertEqual(self.linked_list.len(), 0) self.linked_list.delete(55) self.assertEqual(self.linked_list.len(), 0) self.assertIsNone(self.linked_list.head) self.assertIsNone(self.linked_list.tail) # удаление элемента из списка после чего остается только один элемент в списке self.linked_list.add_in_tail(Node(NODE_VALUE)) self.linked_list.add_in_tail(Node(55)) self.linked_list.delete(55) self.assertEqual(self.linked_list.head.value, 12) self.assertEqual(self.linked_list.tail.value, 12) self.assertIsNone(self.linked_list.head.next) self.assertIsNone(self.linked_list.tail.next) self.assertEqual(self.linked_list.len(), 1) self.linked_list.add_in_tail(Node(55)) self.linked_list.delete(NODE_VALUE) self.assertEqual(self.linked_list.head.value, 55) self.assertEqual(self.linked_list.tail.value, 55) self.assertIsNone(self.linked_list.head.next) self.assertIsNone(self.linked_list.tail.next) self.assertEqual(self.linked_list.len(), 1) # проверка на удаление элементов со значением 0 и проверка связей для всех узлов в памяти n1 = Node(0) n2 = Node(0) n3 = Node(1) n4 = Node(1) n5 = Node(2) n6 = Node(2) linked_list = LinkedList() linked_list.add_in_tail(n1) linked_list.add_in_tail(n2) linked_list.add_in_tail(n3) linked_list.add_in_tail(n4) linked_list.add_in_tail(n5) linked_list.add_in_tail(n6) linked_list.delete(1, True) linked_list.delete(2, True) linked_list.delete(0) self.assertEqual(linked_list.head.value, 0) self.assertEqual(linked_list.tail.value, 0) self.assertIsNone(linked_list.head.next) self.assertIsNone(linked_list.tail.next) self.assertEqual(linked_list.len(), 1) self.assertIsNone(n1.next) self.assertIsNone(n2.next) self.assertIsNone(n3.next) self.assertIsNone(n4.next) self.assertIsNone(n5.next) self.assertIsNone(n6.next) def test_len(self): count_nodes = self.linked_list.len() self.assertEqual(count_nodes, 3) NODE_VALUE = 12 self.linked_list.delete(NODE_VALUE, True) count_nodes = self.linked_list.len() self.assertEqual(count_nodes, 1) def test_clean(self): self.linked_list.clean() self.assertIsNone(self.linked_list.head) self.assertIsNone(self.linked_list.tail) self.assertEqual(self.linked_list.len(), 0) def test_insert(self): # вставка в список со многими элементами в начало списка self.linked_list.insert(None, Node(1200)) self.assertEqual(self.linked_list.head.value, 1200) self.assertEqual(self.linked_list.head.next.value, 12) self.assertEqual(self.linked_list.len(), 4) self.assertEqual(self.linked_list.tail.value, 12) # вставка в список со многими элементами в конец списка linked_list = LinkedList() linked_list.add_in_tail(Node(1)) linked_list.add_in_tail(Node(2)) linked_list.add_in_tail(Node(3)) linked_list.insert(linked_list.tail, Node(1200)) self.assertEqual(linked_list.head.value, 1) self.assertEqual(linked_list.head.next.value, 2) self.assertEqual(linked_list.len(), 4) self.assertEqual(linked_list.tail.value, 1200) # вставка в список со многими элементами node = self.linked_list.find(55) self.linked_list.insert(node, Node(66)) self.assertEqual(node.next.value, 66) self.assertEqual(self.linked_list.len(), 5) self.assertEqual(self.linked_list.head.value, 1200) self.assertEqual(self.linked_list.tail.value, 12) # вставка в список отличного от типа Node элемента NODE_VALUE = 100 self.linked_list.insert(node, NODE_VALUE) self.assertEqual(self.linked_list.len(), 5) self.assertEqual(self.linked_list.head.value, 1200) self.assertEqual(self.linked_list.tail.value, 12) # вставка в список после несуществующего элемента linked_list = LinkedList() NODE_VALUE = 100 linked_list.add_in_tail(Node(1)) linked_list.add_in_tail(Node(2)) linked_list.add_in_tail(Node(3)) linked_list.insert(Node(1500), Node(NODE_VALUE)) self.assertEqual(linked_list.len(), 3) self.assertEqual(linked_list.head.value, 1) self.assertEqual(linked_list.tail.value, 3) # вставка в пустой список linked_list = LinkedList() linked_list.insert(None, Node(NODE_VALUE)) node = linked_list.find(NODE_VALUE) self.assertEqual(linked_list.len(), 1) self.assertEqual(node.value, NODE_VALUE) self.assertEqual(node.next, None) self.assertEqual(linked_list.head.value, NODE_VALUE) self.assertEqual(linked_list.tail.value, NODE_VALUE) # вставка в пустой список после несуществующего элемента linked_list = LinkedList() linked_list.insert(Node(10), Node(10)) self.assertEqual(linked_list.len(), 0) self.assertIsNone(linked_list.head) self.assertIsNone(linked_list.tail) # вставка в список в начало с одним элементом и проверка на нулевое значение linked_list = LinkedList() linked_list.add_in_tail(Node(1)) linked_list.insert(None, Node(0)) node = linked_list.find(0) self.assertEqual(linked_list.len(), 2) self.assertEqual(node.value, 0) self.assertEqual(node.next.value, 1) self.assertEqual(linked_list.head.value, 0) self.assertEqual(linked_list.tail.value, 1) # вставка в список с одним элементом в конец списка linked_list = LinkedList() linked_list.add_in_tail(Node(1)) node = linked_list.find(1) linked_list.insert(node, Node(0)) node = linked_list.find(0) self.assertEqual(linked_list.len(), 2) self.assertEqual(node.value, 0) self.assertIsNone(node.next) self.assertEqual(linked_list.head.value, 1) self.assertEqual(linked_list.tail.value, 0) def test_validate_node(self): self.assertTrue(self.linked_list._validate_node(Node(123))) self.assertFalse(self.linked_list._validate_node(123)) self.assertFalse(self.linked_list._validate_node('test'))
class Channel: """ This class provides Go like implementation for channels except for the operators used. Much like Go channels, the calls over channels are blocking meaning, sending and receiving over a channel is blocked until a condition is met. There are 3 methods exposed publicly: 1. Send - sends a message over the channel 2. Receive - receives a message from the channel 3. Close - closes the channel Channels can also be iterated over using a for loop. """ __MAX_WAIT_TIME = 30.0 def __init__(self, _type, size=-1): """ initializing for channels""" self.__buffer = LinkedList() self.__capacity = size self.__closed = False self.__cond = Condition() self.__type = _type self.__zero_value_map = { int: 0, float: 0.0, str: '', tuple: (), list: [], dict: {}, set: set() } @property def capacity(self): return self.__capacity def __len__(self): """ Calculates the number of messages in the channel :return number of messages in the channel """ with self.__cond: return self.__buffer.size def __is_empty(self): """ checks whether a channel is empty :return True if a channel is empty, False otherwise """ return len(self) == 0 def __is_full(self): """ checks whether a channel is full. A channel with size -1 is never full. :return True if a channel is full, False otherwise """ with self.__cond: return self.__buffer.size == self.__capacity def __flushed_buffer(self): """ Checks whether the channel has been closed and emptied. :returns True if the channel has been closed and emptied, false otherwise """ with self.__cond: return self.__closed and self.__buffer.head is None def __zero_value(self): """ Calculates the zero value of the type of the channel. Zero Values are values or expressions of a particular type which evaluate to False as a boolean. Zero values for default python types are stored in a dictionary :return: zero value of the default python types, None for other types """ try: return self.__zero_value_map[self.__type] except KeyError: return None def __iter__(self): """ Iterate over the channel and depopulate it. Exits when the buffer has been flushed :returns each message in the buffer. """ while not self.__flushed_buffer(): message, ok = self.__depopulate() if not ok: return yield message def __check_type(self, _input): """ Ensure type check for channels. :param _input: input to be checked :raises TypeMismatchException if input object is not an instance of type defined during initialization of the channel """ if not isinstance(_input, self.__type): raise TypeMismatchException( "Input Type does not match the type of channel") def __wait(self): """ Waits for a specified amount of time. This is necessary when waiting for a thread to finish sending or receiving over the channel """ with self.__cond: self.__cond.wait(self.__class__.__MAX_WAIT_TIME) def __is_closed(self): """ Checks whether a channel closed :return True a channel is closed, False otherwise """ with self.__cond: return self.__closed def __populate(self, message): """ Populates the channel with an message. If channel is at capacity, waits till channel is depopulated at least once. Also notifies all threads waiting to receive on the other end of the channel :param message: message to be added to the buffer """ self.__check_type(message) if self.__capacity != -1 and self.__is_full(): while not self.__is_closed() and self.__is_full(): self.__wait() if self.__is_closed(): return with self.__cond: self.__buffer.insert(message) self.__cond.notifyAll() def __depopulate(self): """ Depopulates the channel and returns the message. If channel is empty, waits till channel is populated at least once. If the channel is closed before depopulating, a special object is returned. Also notifies all threads waiting to send on the other end of the channel. :return tuple of (message, True) if channel is open, tuple of (None, False) otherwise """ while not self.__is_closed() and self.__is_empty(): self.__wait() if self.__flushed_buffer(): return None, False with self.__cond: message = self.__buffer.delete() self.__cond.notifyAll() return message, True def send(self, message): """ Sends a message across the channel. Raises an exception if it is called on a closed channel :param message: message to be sent on the channel :raises ChannelClosedException if send is called on a closed channel """ if self.__is_closed(): raise ChannelClosedException( "Invalid operation send on closed channel") self.__populate(message) def receive(self): """ Receives a message from the channel :returns a message from the buffer """ message, ok = self.__depopulate() if not ok: return self.__zero_value(), False return message, True def close(self): """ Closes the channel. :raises ChannelClosedException if it is called on a closed channel """ with self.__cond: if self.__closed: raise ChannelClosedException("Cannot close a closed channel") self.__closed = True self.__cond.notifyAll()
def test_delete(self): # удаление первого найденого элемента из нескольких найденных NODE_VALUE = 12 nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 2) self.linked_list.delete(NODE_VALUE) nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 1) self.assertEqual(self.linked_list.head.value, 55) self.assertEqual(self.linked_list.tail.value, 12) # удаление всех найденных элементов self.linked_list.add_in_tail(Node(NODE_VALUE)) nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 2) self.linked_list.delete(NODE_VALUE, True) nodes = self.linked_list.find_all(NODE_VALUE) self.assertEqual(len(nodes), 0) self.assertEqual(self.linked_list.tail.value, 55) # удаление единственного элемента в списке self.linked_list.delete(55) self.assertEqual(self.linked_list.len(), 0) self.assertIsNone(self.linked_list.head) self.assertIsNone(self.linked_list.tail) # удаление элемента из пустого списка self.assertEqual(self.linked_list.len(), 0) self.linked_list.delete(55) self.assertEqual(self.linked_list.len(), 0) self.assertIsNone(self.linked_list.head) self.assertIsNone(self.linked_list.tail) # удаление элемента из списка после чего остается только один элемент в списке self.linked_list.add_in_tail(Node(NODE_VALUE)) self.linked_list.add_in_tail(Node(55)) self.linked_list.delete(55) self.assertEqual(self.linked_list.head.value, 12) self.assertEqual(self.linked_list.tail.value, 12) self.assertIsNone(self.linked_list.head.next) self.assertIsNone(self.linked_list.tail.next) self.assertEqual(self.linked_list.len(), 1) self.linked_list.add_in_tail(Node(55)) self.linked_list.delete(NODE_VALUE) self.assertEqual(self.linked_list.head.value, 55) self.assertEqual(self.linked_list.tail.value, 55) self.assertIsNone(self.linked_list.head.next) self.assertIsNone(self.linked_list.tail.next) self.assertEqual(self.linked_list.len(), 1) # проверка на удаление элементов со значением 0 и проверка связей для всех узлов в памяти n1 = Node(0) n2 = Node(0) n3 = Node(1) n4 = Node(1) n5 = Node(2) n6 = Node(2) linked_list = LinkedList() linked_list.add_in_tail(n1) linked_list.add_in_tail(n2) linked_list.add_in_tail(n3) linked_list.add_in_tail(n4) linked_list.add_in_tail(n5) linked_list.add_in_tail(n6) linked_list.delete(1, True) linked_list.delete(2, True) linked_list.delete(0) self.assertEqual(linked_list.head.value, 0) self.assertEqual(linked_list.tail.value, 0) self.assertIsNone(linked_list.head.next) self.assertIsNone(linked_list.tail.next) self.assertEqual(linked_list.len(), 1) self.assertIsNone(n1.next) self.assertIsNone(n2.next) self.assertIsNone(n3.next) self.assertIsNone(n4.next) self.assertIsNone(n5.next) self.assertIsNone(n6.next)