Skip to content

Commit

Permalink
Restructured queue.py and stack.py (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
HarsheetKakar committed Mar 16, 2020
1 parent b0c3136 commit 34a2eaf
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 41 deletions.
49 changes: 20 additions & 29 deletions pydatastructs/miscellaneous_data_structures/queue.py
Original file line number Diff line number Diff line change
@@ -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__ = [
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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

Expand Down
64 changes: 60 additions & 4 deletions pydatastructs/miscellaneous_data_structures/stack.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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))

Expand All @@ -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):

Expand All @@ -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)
Expand All @@ -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)
25 changes: 18 additions & 7 deletions pydatastructs/miscellaneous_data_structures/tests/test_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]'
Expand All @@ -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
29 changes: 28 additions & 1 deletion pydatastructs/miscellaneous_data_structures/tests/test_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}))

0 comments on commit 34a2eaf

Please sign in to comment.