Repository navigation
Expand file tree
/
Copy pathStack.py
More file actions
162 lines (127 loc) · 4.3 KB
/
Copy pathStack.py
File metadata and controls
162 lines (127 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import ctypes
class EmptyStackError(Exception):
"""
Exception raised when attempting to perform an operation on an empty stack.
"""
pass
class Stack:
"""
A stack implementation using a dynamic array.
"""
def __init__(self, size):
"""
Initializes a new instance of the Stack class.
Args:
size (int): The initial capacity of the stack.
"""
self.cap = size # Current capacity of the stack
self.top = 0 # Index of the top element
self.stack = self.make_array(size) # Internal array to store the elements
def make_array(self, size):
"""
Creates a new array of a given size using the ctypes module.
Args:
size (int): The size of the array.
Returns:
A ctypes array of the specified size.
"""
return (size * ctypes.py_object)()
def resize(self, size):
"""
Resizes the internal array to a new size.
Args:
size (int): The new size of the array.
"""
temp = self.make_array(size) # Create a new array with the specified size
for i in range(self.top):
temp[i] = self.stack[i] # Copy elements from the old array to the new array
self.stack = temp # Replace the old array with the new array
self.cap = size # Update the capacity
def push(self, elt):
"""
Pushes an element onto the top of the stack. If the stack is full, it doubles the capacity.
Args:
elt: The element to be pushed.
"""
if self.top == self.cap:
self.resize(self.cap * 2) # Double the capacity if the stack is full
self.stack[self.top] = elt
self.top += 1
def is_empty(self):
"""
Checks if the stack is empty.
Returns:
bool: True if the stack is empty, False otherwise.
"""
return self.top == 0
def pop(self):
"""
Removes and returns the top element from the stack. If the stack is empty, raises an EmptyStackError.
Returns:
The top element of the stack.
Raises:
EmptyStackError: If the stack is empty.
"""
if self.is_empty():
raise EmptyStackError("Stack is empty")
del_item = self.stack[self.top - 1]
self.stack[self.top - 1] = None
self.top -= 1
if self.top < self.cap // 4:
self.resize(
self.cap // 2
) # Halve the capacity if the number of elements is less than one-fourth of the capacity
return del_item
def __len__(self):
"""
Returns the number of elements in the stack.
Returns:
int: The number of elements in the stack.
"""
return self.top
def top_element(self):
"""
Returns the top element of the stack without removing it.
Returns:
The top element of the stack.
Raises:
EmptyStackError: If the stack is empty.
"""
if self.is_empty():
raise EmptyStackError("Stack is empty")
return self.stack[self.top - 1]
def __str__(self):
"""
Returns a string representation of the stack.
Returns:
str: A string representation of the stack.
"""
string = "<"
for i in range(self.top):
string += str(self.stack[i]) + ","
return string + ">"
def __getitem__(self, idx):
"""
Returns the element at the specified index.
Args:
idx (int): The index of the element to retrieve.
Returns:
The element at the specified index.
Raises:
IndexError: If the index is out of bounds.
"""
if idx >= self.top:
raise IndexError("Index out of bound")
return self.stack[idx]
def __setitem__(self, idx, elt):
"""
Sets the element at the specified index to a new value.
Args:
idx (int): The index of the element to set.
elt: The new value to assign to the element.
Raises:
IndexError: If the index is out of bounds.
"""
if idx >= self.top:
raise IndexError("Index out of bound")
self.stack[idx] = elt