diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index e7e176fd0..d995d5107 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -1,5 +1,5 @@ from pydatastructs.linear_data_structures import DynamicOneDimensionalArray, SinglyLinkedList -from pydatastructs.utils.misc_util import NoneType, LinkedListNode +from pydatastructs.utils.misc_util import NoneType, LinkedListNode, _check_type from copy import deepcopy as dc __all__ = [ @@ -46,10 +46,9 @@ def __new__(cls, implementation='array', **kwargs): return ArrayQueue( kwargs.get('items', None), kwargs.get('dtype', int)) - elif implementation == 'linkedlist': + elif implementation == 'linked_list': return LinkedListQueue( - kwargs.get('items', None), - kwargs.get('dtype', NoneType) + kwargs.get('items', None) ) raise NotImplementedError( "%s hasn't been implemented yet."%(implementation)) @@ -94,7 +93,7 @@ def append(self, x): def popleft(self): if self.is_empty: - raise ValueError("Queue is empty.") + raise IndexError("Queue is empty.") return_value = dc(self.items[self.front]) front_temp = self.front if self.front == self.rear: @@ -128,53 +127,45 @@ def __str__(self): class LinkedListQueue(Queue): - __slots__ = ['front', 'rear', 'size', '_dtype'] + __slots__ = ['queue'] - def __new__(cls, items=None, dtype=NoneType): + def __new__(cls, items=None): obj = object.__new__(cls) obj.queue = SinglyLinkedList() - obj._dtype = dtype if items is None: pass elif type(items) in (list, tuple): - if len(items) != 0 and dtype is NoneType: - obj._dtype = type(items[0]) for x in items: - if type(x) == obj._dtype: - obj.queue.append(x) - else: - raise TypeError("Expected %s but got %s"%(obj._dtype, type(x))) + obj.append(x) else: raise TypeError("Expected type: list/tuple") - obj.front = obj.queue.head - obj.rear = obj.queue.tail - obj.size = obj.queue.size return obj def append(self, x): - if self._dtype is NoneType: - self._dtype = type(x) - elif type(x) is not self._dtype: - raise TypeError("Expected %s but got %s"%(self._dtype, type(x))) - self.size += 1 self.queue.append(x) - if self.front is None: - self.front = self.queue.head - self.rear = self.queue.tail def popleft(self): if self.is_empty: - raise ValueError("Queue is empty.") - self.size -= 1 + raise IndexError("Queue is empty.") return_value = self.queue.pop_left() - self.front = self.queue.head - self.rear = self.queue.tail return return_value @property def is_empty(self): return self.size == 0 + @property + def front(self): + return self.queue.head + + @property + def rear(self): + return self.queue.tail + + @property + def size(self): + return self.queue.size + def __len__(self): return self.size diff --git a/pydatastructs/miscellaneous_data_structures/stack.py b/pydatastructs/miscellaneous_data_structures/stack.py index dc44e3895..2aa2febe6 100644 --- a/pydatastructs/miscellaneous_data_structures/stack.py +++ b/pydatastructs/miscellaneous_data_structures/stack.py @@ -1,4 +1,4 @@ -from pydatastructs.linear_data_structures import DynamicOneDimensionalArray +from pydatastructs.linear_data_structures import DynamicOneDimensionalArray, SinglyLinkedList from pydatastructs.utils.misc_util import _check_type, NoneType from copy import deepcopy as dc @@ -51,6 +51,10 @@ def __new__(cls, implementation='array', **kwargs): return ArrayStack( kwargs.get('items', None), kwargs.get('dtype', int)) + if implementation == 'linked_list': + return LinkedListStack( + kwargs.get('items',None) + ) raise NotImplementedError( "%s hasn't been implemented yet."%(implementation)) @@ -64,11 +68,13 @@ def pop(self, *args, **kwargs): @property def is_empty(self): - return None + raise NotImplementedError( + "This is an abstract method.") @property def peek(self): - return None + raise NotImplementedError( + "This is an abstract method.") class ArrayStack(Stack): @@ -90,7 +96,7 @@ def push(self, x): def pop(self): if self.is_empty: - raise ValueError("Stack is empty") + raise IndexError("Stack is empty") top_element = dc(self.items[self.items._last_pos_filled]) self.items.delete(self.items._last_pos_filled) @@ -104,8 +110,58 @@ def is_empty(self): def peek(self): return self.items[self.items._last_pos_filled] + def __len__(self): + return self.items._num + def __str__(self): """ Used for printing. """ return str(self.items._data) + + +class LinkedListStack(Stack): + + __slots__ = ['stack'] + + def __new__(cls, items=None): + obj = object.__new__(cls) + obj.stack = SinglyLinkedList() + if items is None: + pass + elif type(items) in (list, tuple): + for x in items: + obj.push(x) + else: + raise TypeError("Expected type: list/tuple") + return obj + + def push(self, x): + self.stack.append_left(x) + + def pop(self): + if self.is_empty: + raise IndexError("Stack is empty") + return self.stack.pop_left() + + @property + def is_empty(self): + return self.__len__() == 0 + + @property + def peek(self): + return self.top.data + + @property + def top(self): + return self.stack.head + + @property + def size(self): + return self.stack.size + + def __len__(self): + return self.stack.size + + def __str__(self): + return str(self.stack) diff --git a/pydatastructs/miscellaneous_data_structures/tests/test_queue.py b/pydatastructs/miscellaneous_data_structures/tests/test_queue.py index 49d52fe11..3600b8e62 100644 --- a/pydatastructs/miscellaneous_data_structures/tests/test_queue.py +++ b/pydatastructs/miscellaneous_data_structures/tests/test_queue.py @@ -17,14 +17,12 @@ def test_Queue(): assert len(q1) == 0 q1 = Queue() - raises(ValueError, lambda: q1.popleft()) + raises(IndexError, lambda: q1.popleft()) - q1 = Queue(implementation='linkedlist') + q1 = Queue(implementation='linked_list') q1.append(1) - assert raises(TypeError, lambda: q1.append('a')) - assert raises(TypeError, lambda: Queue(implementation='linkedlist', items=[0], dtype=str)) - assert raises(TypeError, lambda: Queue(implementation='linkedlist', items={0, 1})) - q1 = Queue(implementation='linkedlist', items = [0, 1]) + assert raises(TypeError, lambda: Queue(implementation='linked_list', items={0, 1})) + q1 = Queue(implementation='linked_list', items = [0, 1]) q1.append(2) q1.append(3) assert str(q1) == '[0, 1, 2, 3]' @@ -35,4 +33,17 @@ def test_Queue(): assert q1.popleft().data == 2 assert q1.popleft().data == 3 assert len(q1) == 0 - raises(ValueError, lambda: q1.popleft()) + raises(IndexError, lambda: q1.popleft()) + + q1 = Queue(implementation='linked_list',items=['a',None,type,{}]) + assert len(q1) == 4 + assert q1.size == 4 + + front = q1.front + assert front.data == q1.popleft().data + + rear = q1.rear + for _ in range(len(q1)-1): + q1.popleft() + + assert rear.data == q1.popleft().data diff --git a/pydatastructs/miscellaneous_data_structures/tests/test_stack.py b/pydatastructs/miscellaneous_data_structures/tests/test_stack.py index d8ee561ec..a35f9b664 100644 --- a/pydatastructs/miscellaneous_data_structures/tests/test_stack.py +++ b/pydatastructs/miscellaneous_data_structures/tests/test_stack.py @@ -14,7 +14,34 @@ def test_Stack(): assert s.pop() == 2 assert s.pop() == 1 assert s.is_empty is True - assert raises(ValueError, lambda : s.pop()) + assert raises(IndexError, lambda : s.pop()) _s = Stack(items=[1, 2, 3]) assert str(_s) == '[1, 2, 3]' + assert len(_s) == 3 assert raises(NotImplementedError, lambda: Stack(implementation='')) + + s = Stack(implementation='linked_list') + s.push(1) + s.push(2) + s.push(3) + assert s.peek == 3 + assert str(s) == '[3, 2, 1]' + assert s.pop().data == 3 + assert s.pop().data == 2 + assert s.pop().data == 1 + assert s.is_empty is True + assert raises(IndexError, lambda : s.pop()) + _s = Stack(implementation='linked_list',items=[1, 2, 3]) + assert str(_s) == '[3, 2, 1]' + assert len(_s) == 3 + + s = Stack(implementation='linked_list',items=['a',None,type,{}]) + assert len(s) == 4 + assert s.size == 4 + + top = s.top + assert top.data == s.pop().data + + peek = s.peek + assert peek == s.pop().data + assert raises(TypeError, lambda: Stack(implementation='linked_list', items={0, 1}))