Skip to content

Commit c42e5eb

Browse files
authored
Added Stack (#14)
* Array implementation of stacks have been added. * `misc_util` has been added to avoid repeated code.
1 parent 43ee086 commit c42e5eb

File tree

15 files changed

+215
-40
lines changed

15 files changed

+215
-40
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ __pycache__/
44
*.pyo
55
.vscode/
66
.pytest_cache/
7+
pre_commit.ps1

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ python:
55
install:
66
- pip install -r requirements.txt
77
script:
8+
- python -m unittest discover pydatastructs
89
- pytest --doctest-modules

AUTHORS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
Gagandeep Singh<[email protected]>
2+
Kartikei Mittal<[email protected]>
3+

pydatastructs/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
from .linear_data_structures import *
22
from .trees import *
3+
from .miscellaneous_data_structures import *
4+
from .utils import *

pydatastructs/linear_data_structures/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
__all__ = []
22

3-
from . import arrays
3+
from . import (
4+
arrays,
5+
)
6+
47
from .arrays import (
58
OneDimensionalArray,
69
)

pydatastructs/linear_data_structures/arrays.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
from __future__ import print_function, division
2+
from pydatastructs.utils.misc_util import _check_type, NoneType
23

34
__all__ = [
45
'OneDimensionalArray'
56
]
67

7-
_check_type = lambda a, t: isinstance(a, t)
8-
NoneType = type(None)
9-
108
class Array(object):
119
'''
1210
Abstract class for arrays in pydatastructs.
@@ -105,7 +103,10 @@ def __getitem__(self, i):
105103
return self._data.__getitem__(i)
106104

107105
def __setitem__(self, idx, elem):
108-
self._data[idx] = self._dtype(elem)
106+
if elem is None:
107+
self._data[idx] = None
108+
else:
109+
self._data[idx] = self._dtype(elem)
109110

110111
def fill(self, elem):
111112
elem = self._dtype(elem)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
__all__ = []
2+
3+
from . import (
4+
stack,
5+
)
6+
7+
from .stack import (
8+
Stack,
9+
)
10+
__all__.extend(stack.__all__)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
from __future__ import print_function, division
3+
from pydatastructs.linear_data_structures import OneDimensionalArray
4+
from copy import deepcopy as dc
5+
6+
__all__ = [
7+
'Stack'
8+
]
9+
10+
_check_type = lambda a, t: isinstance(a, t)
11+
NoneType = type(None)
12+
13+
class Stack(object):
14+
"""Respresentation of stack data structure
15+
16+
Parameters
17+
==========
18+
19+
implementation : str
20+
Implementation to be used for stack.
21+
By default, 'array'
22+
Currently only supports 'array'
23+
implementation.
24+
maxsize : int
25+
The maximum size of the stack.
26+
For array implementation.
27+
top : int
28+
The top element of the stack.
29+
For array implementation.
30+
items : OneDimensionalArray
31+
Optional, by default, None
32+
The inital items in the stack.
33+
For array implementation.
34+
dtype : A valid python type
35+
Optional, by default int if item
36+
is None, otherwise takes the data
37+
type of OneDimensionalArray
38+
For array implementation.
39+
40+
Example
41+
=======
42+
43+
>>> from pydatastructs import Stack
44+
>>> s = Stack(maxsize=5, top=0)
45+
>>> s.push(1)
46+
>>> s.push(2)
47+
>>> s.push(3)
48+
>>> str(s)
49+
'[1, 2, 3, None, None]'
50+
>>> s.pop()
51+
3
52+
53+
References
54+
==========
55+
56+
.. [1] https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
57+
"""
58+
59+
def __new__(cls, implementation='array', **kwargs):
60+
if implementation == 'array':
61+
return ArrayStack(
62+
kwargs.get('maxsize', None),
63+
kwargs.get('top', None),
64+
kwargs.get('items', None),
65+
kwargs.get('dtype', int))
66+
raise NotImplementedError(
67+
"%s hasn't been implemented yet."%(implementation))
68+
69+
def push(self, *args, **kwargs):
70+
raise NotImplementedError(
71+
"This is an abstract method.")
72+
73+
def pop(self, *args, **kwargs):
74+
raise NotImplementedError(
75+
"This is an abstract method.")
76+
77+
class ArrayStack(Stack):
78+
79+
def __new__(cls, maxsize=None, top=0, items=None, dtype=int):
80+
if not _check_type(maxsize, int):
81+
raise ValueError("maxsize is missing.")
82+
if not _check_type(top, int):
83+
raise ValueError("top is missing.")
84+
if items == None:
85+
items = OneDimensionalArray(dtype, maxsize)
86+
if not _check_type(items, OneDimensionalArray):
87+
raise ValueError("items is not of type, OneDimensionalArray")
88+
if items._size > maxsize:
89+
raise ValueError("Overflow, size of items %s is greater "
90+
"than maxsize, %s"%(items._size, maxsize))
91+
obj = object.__new__(cls)
92+
obj.maxsize, obj.top, obj.items, obj.dtype = \
93+
maxsize, top, items, items._dtype
94+
return obj
95+
96+
def push(self, x):
97+
if self.top == self.maxsize:
98+
raise ValueError("Stack is full.")
99+
self.items[self.top] = self.dtype(x)
100+
self.top += 1
101+
102+
def pop(self):
103+
if self.top == 0:
104+
raise ValueError("Stack is already empty.")
105+
self.top -= 1
106+
r = self.items[self.top]
107+
self.items[self.top] = None
108+
return r
109+
110+
def __str__(self):
111+
"""
112+
Used for printing.
113+
"""
114+
return str(self.items._data)

pydatastructs/miscellaneous_data_structures/tests/__init__.py

Whitespace-only changes.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from pydatastructs.miscellaneous_data_structures import Stack
2+
from pydatastructs.linear_data_structures import OneDimensionalArray
3+
from pydatastructs.utils.raises_util import raises
4+
5+
def test_Stack():
6+
7+
s = Stack(maxsize=3, top=0)
8+
s.push(1)
9+
s.push(2)
10+
s.push(3)
11+
assert s.top == 3
12+
assert str(s) == '[1, 2, 3]'
13+
raises(ValueError, lambda: s.push(4))
14+
assert s.pop() == 3
15+
assert s.pop() == 2
16+
assert s.pop() == 1
17+
assert s.top == 0
18+
raises(ValueError, lambda: s.pop())
19+
raises(ValueError, lambda: Stack())
20+
raises(ValueError, lambda: Stack(maxsize=5, top=0, items=[1, 2, 3]))
21+
raises(ValueError, lambda: Stack(maxsize=5, top=0,
22+
items=OneDimensionalArray(6)))

pydatastructs/trees/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
__all__ = []
22

3-
from . import binary_trees
3+
from . import (
4+
binary_trees,
5+
space_partitioning_trees
6+
)
7+
48
from .binary_trees import (
59
Node, BinaryTree, BinarySearchTree
610
)
711
__all__.extend(binary_trees.__all__)
812

9-
from . import space_partitioning_trees
1013
from .space_partitioning_trees import (
1114
OneDimensionalSegmentTree
1215
)

pydatastructs/trees/binary_trees.py

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,12 @@
11
from __future__ import print_function, division
2+
from pydatastructs.utils import Node
23

34
__all__ = [
45
'Node',
56
'BinaryTree',
67
'BinarySearchTree'
78
]
89

9-
class Node(object):
10-
"""
11-
Represents node in trees.
12-
13-
Parameters
14-
==========
15-
16-
data
17-
Any valid data to be stored in the node.
18-
key
19-
Required for comparison operations.
20-
left: int
21-
Optional, index of the left child node.
22-
right: int
23-
Optional, index of the right child node.
24-
"""
25-
26-
__slots__ = ['key', 'data', 'left', 'right', 'is_root']
27-
28-
def __new__(cls, key, data):
29-
obj = object.__new__(cls)
30-
obj.data, obj.key = data, key
31-
obj.left, obj.right = None, None
32-
obj.is_root = False
33-
return obj
34-
35-
def __str__(self):
36-
"""
37-
Used for printing.
38-
"""
39-
return str((self.left, self.key, self.data, self.right))
40-
4110
class BinaryTree(object):
4211
"""
4312
Abstract binary tree.

pydatastructs/trees/space_partitioning_trees.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pydatastructs.trees.binary_trees import Node
1+
from pydatastructs.utils import Node
22
from collections import deque as Queue
33
from pydatastructs.linear_data_structures.arrays import _check_type
44

pydatastructs/utils/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
__all__ = []
2+
3+
from . import misc_util
4+
from .misc_util import (
5+
Node
6+
)
7+
__all__.extend(misc_util.__all__)

pydatastructs/utils/misc_util.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from __future__ import print_function, division
2+
3+
__all__ = [
4+
'Node'
5+
]
6+
7+
_check_type = lambda a, t: isinstance(a, t)
8+
NoneType = type(None)
9+
10+
class Node(object):
11+
"""
12+
Represents node in trees.
13+
14+
Parameters
15+
==========
16+
17+
data
18+
Any valid data to be stored in the node.
19+
key
20+
Required for comparison operations.
21+
left: int
22+
Optional, index of the left child node.
23+
right: int
24+
Optional, index of the right child node.
25+
"""
26+
27+
__slots__ = ['key', 'data', 'left', 'right', 'is_root']
28+
29+
def __new__(cls, key, data):
30+
obj = object.__new__(cls)
31+
obj.data, obj.key = data, key
32+
obj.left, obj.right = None, None
33+
obj.is_root = False
34+
return obj
35+
36+
def __str__(self):
37+
"""
38+
Used for printing.
39+
"""
40+
return str((self.left, self.key, self.data, self.right))

0 commit comments

Comments
 (0)