StackList and StackArrays python - python

so i am a bit confused as to how to attack the StackList and Node portion of this homework.. I barely have any programming experience, and after a full day of struggling I finally understood StackArray. But I also need to understand how I can implement the same functions into a LinkedList... Here are the instructions in case I cant be clear ..
The goal of this project is to implement the Stack Abstract Data Type using the built in List construct in
Python and the Stack ADT using the simple linked data structure covered in class.
As discussed in class you are to allocate a list of size stack_capacity and use this to store the items in the
stack. Since Lists in python expand when more storage is needed you will have to provide a mechanism to
prevent the list inside your stack from growing. This really prevents the stack from growing if the user only
accesses it through the given interface but that is fine for the purposes of this exercise. (This prevents the stack
from using more space that a user might want. Think of this as a requirement for an application on a small
device than has very limited storage.) In the case when a user attempts to push an item on to a full stack, your
push function (method) should raise an IndexError. Similarly if a user tries to pop an empty, your pop function
(method) should raise an IndexError.
tly
class StackArray:
"""Implements an efficient last-in first-out Abstract Data Type using a Python List"""
def __init__(self, capacity):
"""Creates and empty stack with a capacity"""
self.capacity = capacity # this is example for list implementation
self.items = [None]*capacity # this is example for list implementation
self.num_items = 0 # this is example for list implementation
def is_empty(self):
"""Returns true if the stack self is empty and false otherwise"""
def is_full(self):
"""Returns true if the stack self is full and false otherwise"""
def push(self, item):
def pop(self):
def peek(self):
def size(self):
"""Returns the number of elements currently in the stack, not the capacity"""
Submit to two files:
• stacks.py containing a list based implementation of stack and a linked implementation of stack. The
classes must be called: StackArray and StackLinked . Both implementations should follow the above
specification and be thoroughly tested.
• test_stacks.py contains your set of tests to ensure you classes work correctly
So far this is what I have come up with
class StackArray:
"""Implements an efficient last-in first-out Abstract Data Type using a Python List"""
def __init__(self, capacity):
"""Creates and empty stack with a capacity"""
self.capacity = capacity # this is example for list implementation
self.items = [None]*capacity # this is example for list implementation
self.num_items = 0 # this is example for list implementation
def is_empty(self):
"""Returns true if the stack self is empty and false otherwise"""
return self.num_items == 0
def is_full(self):
"""Returns true if the stack self is full and false otherwise"""
return self.num_items == self.capacity
def push(self, item):
self.num_items += 1
self.items[self.num_items - 1] = item
def pop(self):
return self.items.pop(0)
def peek(self):
return self.items[0]
def size(self):
"""Returns the number of elements currently in the stack, not the capacity"""
return self.num_items
class Node:
# ? ?
# nodes have 2 parts to them data and pointer. Pointer always points to the data of previous
class StackLinkList:
def __init__(self, capacity):
"""Creates and empty stack with a capacity"""
self.capacity = capacity # this is example for list implementation
self.items = [None] * capacity # this is example for list implementation
self.num_items = 0 # this is example for list implementation
def is_empty(self):
"""Returns true if the stack self is empty and false otherwise"""
def is_full(self):
"""Returns true if the stack self is full and false otherwise"""
def push(self, item):
def pop(self):
def peek(self):
def size(self):
"""Returns the number of elements currently in the stack, not the capacity"""
And these are my testcases
import unittest
from stacks import *
class TestCase(unittest.TestCase):
# testing an empty Array
def test_if_empty(self):
s1 = StackArray(3) #[none,none,none]
self.assertTrue(s1.is_empty()) # Should be True
def test_if_not_empty(self):
s1 = StackArray(4) #[none,none,none,none]
s1.push(2) #[2,none,none,none]
s1.push(3) #[2,3,none,none]
s1.push(4) #[2,3,4,none]
self.assertFalse(s1.is_empty()) # this is saying that the statement that the string is empty is false
def test_if_full(self):
s1 = StackArray(3) #[none,none,none]
s1.push(5) #[5,none,none]
s1.push(4) #[5,4,none]
s1.push(3) #[5,4,3]
self.assertTrue(s1.is_full()) #this is checking to see if its true that the stack is full
def test_if_not_full(self):
s1 = StackArray(2) # [none,none]
s1.push(2) # [2,none]
self.assertFalse(s1.is_full()) # it is false that the stack is full
def test_IfWeCanPush(self):
s1 = StackArray(3) #[none,none,none]
s1.push(2) #[2,none]
s1.push(3) #[2,3]
self.assertFalse(s1.is_full()) # it is false that the stack is full
def test_IfWeCantPush(self):
s1 = StackArray(3) #[none,none,none]
s1.push(2) #[2,none,none]
s1.push(3) #[2,3,none]
s1.push(3) #[2,3,3]
self.assertTrue(s1.is_full())
def test_ifWeCanPop(self):
s1 = StackArray(3) #[none,none,none]
s1.push(3) #[3,none,none]
s1.push(3) #[3,3,none]
s1.push(5) #[3,3,5]
# This gives us an array [3,3,5]
s1.pop() # now we have [3,5]
s1.pop() # now we have [5]
self.assertFalse(s1.is_empty())
self.assertEqual(s1.pop(),5)
def test_ifWeCantPop(self):
s1 = StackArray(2) # this gives us [none,none]
self.assertFalse(s1.pop())
def test_ifWeCanPeek(self):
s1 = StackArray(4)
s1.push(4)
s1.push(3)
s1.push(5)
s1.push(54)
self.assertEqual(s1.peek(),4) #this statement says that if we peek at the top of the stack it should be 4
def test_ifWeCanSeeTheSize(self):
s1 = StackArray(5)
s1.push(3)
self.assertEqual(s1.size(),1) # this statement checks that the size or number of items in the
# stack is 1 ... [ 3,none,none,none,none] only has one item which is 3
if (name == 'main'):
unittest.main()

Related

Max stack in python - 2 stacks solution

I am trying to build a max stack in python, I am not sure what I am doing wrong.
Here is the question>
Design a max stack data structure that supports the stack operations
and supports finding the stack's maximum element.
Implement the MaxStack class:
MaxStack() Initializes the stack object.
void push(int x) Pushes element x onto the stack.
int pop() Removes the element on top of the stack and returns it.
int top() Gets the element on the top of the stack without removing it.
int peekMax() Retrieves the maximum element in the stack without removing it.
int popMax() Retrieves the maximum element in the stack and removes it.
If there is more than one maximum element, only remove the top-most one.
class MaxStack:
def __init__(self):
self.stack = []
self.stack_max = []
def push(self, x: int) -> None:
self.stack.append(x)
if not self.stack_max or x > self.stack_max[-1][0]:
self.stack_max.append([x, 1])
elif x == self.stack_max[-1][0]:
self.stack_max[-1][1] += 1
else:
self.stack_max.append(self.stack_max[-1])
def pop(self) -> int:
if not self.stack_max or self.stack:
return
if self.stack_max[-1][0] == self.stack[-1]:
self.stack_max[-1][1] -= 1
if self.stack_max[-1][1] == 0:
del self.stack_max[-1]
return self.stack.pop()
def top(self) -> int:
return self.stack[-1]
def peekMax(self) -> int:
if self.stack_max:
return self.stack_max[-1][0]
def popMax(self) -> int:
if self.stack_max:
return self.stack_max.pop()[0]
Example code:
obj = MaxStack()
obj.push(6)
param_2 = obj.pop()
param_3 = obj.top()
param_4 = obj.peekMax()
param_5 = obj.popMax()
Input :
["MaxStack","push","push","push","top","popMax","top","peekMax","pop","top"] [[],[5],[1],[5],[],[],[],[],[],[]]
Output:
[null,null,null,null,5,5,5,5,None,5]
Expected:
[null,null,null,null,5,5,1,5,1,5]
Reference: Leetcode 716. Max Stack
class MaxStack:
def __init__(self,value):#taking some value to avoid empty obj
self.stack=[value]
self.max_=[value,0]
self.length=1
def push(self,value):
self.stack.append(value)
self.length+=1
if value>self.max_[0]:
self.max_[0],self.max_[1]=value,self.length-1
def pop(self):
if self.length==0:
return
elif self.stack[-1]==self.max_[0]:
self.popMax()
else:
self.stack.pop()
self.length-=1
def top(self):
print(self.stack[-1])
def peekMax(self):
print(self.max_[0])
def popMax(self):
if self.length==0 or self.max_[1]==-1:
return
self.stack.pop(self.max_[1])
self.length-=1
self.max_[0],self.max_[1]=-1,-1
for i in range(self.length):
if self.stack[i]>self.max_[0]:
self.max_[0],self.max_[1] = self.stack[i],i
Sorry for the improper indentations, I tried a lot to fix it. Anyways this should work and I wanted to try it out on leetcode but it needs a login. Let me know if there is any issue.
To me, it seems a little confusing to track the count in the tuple of the value, when you could just continue adding to the max stack and counting them from the list if you need that.
class MaxStack:
def __init__(self):
self.stack = []
self.maxes = []
def push(self, n):
self.stack.append(n)
if not self.maxes or n >= max(self.maxes):
self.maxes.append(n)
def pop(self):
if self.stack:
val = self.stack.pop()
if val in self.maxes:
self.maxes.remove(val)
def top(self):
if self.stack:
return self.stack[-1]
def peek_max(self):
if self.maxes:
return self.maxes[-1]
def pop_max(self):
if self.maxes:
return self.maxes.pop()
Then if you need the count of the number of each, just use count():
def max_count(self):
if self.maxes:
return self.maxes.count(max(self.maxes))

Stack DataStructure Reference Issue in Python

I am trying to build a stack adt with an additional method of findMin() which returns the minimum integer in a stack. I am doing this using 2 stacks I built in python(note outside of this class the stacks work fine).
from StackandQueueADT import Stack
class MinStack:
'This class has same functionality as a regular stack with 1 extra method that finds min of stack'
'it will use a min stack to keep track of min number'
def __init__(self):
self.myStack = Stack()
self.minStack=Stack()
def isEmpty(self)->bool:
if(self.myStack.isEmpty()):
return True
return False
def push(self,x)-> None:
if(self.isEmpty() or x <= self.minStack.peek()):
self.minStack.push(x)
self.myStack.push(x)
def pop(self)->int:
if(not self.minStack.isEmpty() and self.myStack.peek() == self.minStack.peek()):
print("what is happening with current stack Before?: " + str(self.myStack.peek()))
print("pop minstack: " + str(self.minStack.pop()))
print("what is happening with current stack After?: " + str(self.myStack.peek()))
return self.myStack.pop()
def peek(self)->int:
if(self.myStack.isEmpty()):
return -1
return self.myStack.peek()
def getMin(self)->int:
if(self.minStack.isEmpty()):
return -1
return self.minStack.peek()
The issue I am having is in the pop() method. Somehow if it goes in the if statement removing the element from the minstack it also removes the element from myStack as well. That is it removes the element from myStack before "return self.myStack.pop()" is called.
I used the following sample to test this out:
minStack = MinStack()
minStack.push(-2)
minStack.push(0)
minStack.push(-3)
print("pop: " + str(minStack.pop()))
In this example somehow -3 is popped from both minStack and myStack implicitly when I only popped it from minStack. Note testing each stack individually works fine but when doing it this way somehow it looks like the same reference is passed to both stacks.
If needed this is my stack class:
class Stack:
stack=[]
top = -1
def isEmpty(self):
if self.top==-1:
return True
return False
def push(self,data):
self.top = self.top+1
self.stack.insert(self.top,data)
def pop(self):
if self.isEmpty():
print("The stack is empty!,nothing to pop")
return None
value = self.stack[self.top]
self.stack.pop(self.top)
self.top = self.top-1
return value
def peek(self):
if self.isEmpty():
print("The stack is empty!")
return -1
return self.stack[self.top]
class Stack:
stack=[]
a = Stack()
b = Stack()
print("a's stack", a.stack) # a's stack []
a.stack.append(1)
print("b's stack", b.stack) # b's stack [1]
In python, variable defined under class is class level variable which is shared among all instances of the class. In your code self.minStack and self.myStack are different instances but they share same stack variable in Stack class.
When you access by self.stack/top it will create independent reference for that instance, but stack reference still refer to same list object. You might want to do
class Stack:
def __init__(self):
self.stack = []
self.top = -1
It's quite confusing and long topic to go thoroughly so I suggest you read about class variables.

dequeue in circularly linked list in python

I am working on the implementation of Queue with a circularly linked list in python. Below is the pictorial representation of circularly LinkedList
I was able to implement most of the code except the dequeue routine. In dequeue routine, one has to keep track of the previous node reference as well as the next node reference with respect to current node. In double linked list, it's easy to implement. However, I have no idea how to implement this concept in single linked list.
class CircularQueue:
''' Queue implementation using a Circularly linked list for storage '''
class _Node:
__slots__ == '_element','_next'
def __init__(self,element,next):
self._element = element
self._next = next
def __init__(self):
'''Create an empty queue'''
self._current = None
self._size = 0
def __len__(self):
return self._size
def is_empty(self):
return self._size == 0
def enqueue(self,e):
node = self._Node(e,None)
if self.is_empty():
newest._next = newest
else:
curr_node = self._current._next
node._next = curr_node
self._current = node
self._size += 1
def dequeue(self):
if self.is_empty():
raise Empty('Stack is empty')
It would be more helpful if anyone can give me thoughts on how to move forward in dequeue routine.
Since your linked list is unidirectional, an element does only have a reference to it's successor, but never to it's predecessor, which you would need both in order to easily close the hole in the list once you dequeue an element.
I see two possibilities: You could either make the linked list bidirectional, therefore adding a reference to the previous element. I cleaned up your implementation a bit, I hope you still can make something of this:
""" Queue implementation using a Circularly linked list for storage """
class _Node:
def __init__(self, element, next=None, previous=None):
self.element = element
if next is None:
next = self
self.next = next
if previous is None:
previous = self
self.previous = previous
class CircularQueue:
def __init__(self):
self._current = None
self._size = 0
def __len__(self):
return self._size
def get_head(self):
return self._current.element
def is_empty(self):
return self._size == 0
def next(self):
self._current = self._current.next
return self._current.element
def previous(self):
self._current = self._current.pevious
return self._current
def enqueue(self, element):
""" Adds an element at the current position, ahead of the current element """
if self.is_empty():
new_node = _Node(element)
else:
new_node = _Node(element, self._current.next, self._current)
self._current.next = new_node
self._current = new_node
self._size += 1
We can now check if our code is correct:
cq = CircularQueue()
cq.enqueue("A")
cq.enqueue("B")
cq.enqueue("C")
print(cq.get_head())
print(cq.next())
print(cq.next())
print(cq.next())
And you will see C, A, B and C printed in succession.
A bilateral queue enables us to implement a dequeue method like this:
def dequeue(self, element_key=None):
if self.is_empty():
raise KeyError('Stack is empty')
if element_key is None:
self._current.next.previous = self._current.previous
self._current.previous.next = self._current.next
return self.next()
else:
current = self._current
while self._current.element != element_key:
self.next()
if self._current == current:
raise KeyError('Element not found')
self.dequeue()
And if we test it...
print("dequeuing 'B'")
cq.dequeue("B")
print(cq.get_head())
print(cq.next())
print(cq.next())
print(cq.next())
... we should see that "dequeuing 'B'" and C, A, C & again A are printed, which makes us happy. :)
Using a unilateral approach is possible too; you might end up having less work handling references while you would have run through your entire circle (in the worst case). First, you'd skip to the next element in the queue until the next element of the current one's is the one you want to dequeue, then set the current's elements next reference to the dequeued one's next, and you are basically done.

Implementing Stacks and Queues using a Linked List

I'm trying to go over some previous homework problems in my computer science class with regards to Linked List. This question is really bothering me on how I should go about this, where it wants me to implement a "Stack" and a "Queue" class to go along using my Linked List class I made a while back. That is all the question states, so would I have to use my ListNode class which is this.
class ListNode(object):
def __init__(self, item = None, link = None):
'''creates a ListNode with the specified data value and link
post: creates a ListNode with the specified data value and link'''
self.item = item
self.link = link
How would I go about making a stack class that can push and pop? Would my code look like this or will I be way off?
from ListNode import ListNode
class LinkedStack(object):
def __init__(self, ListNode.item):
stack = []
def push(self,item):
self.append(ListNode.item)
self.size += 1
def isEmpty(self):
return not self
I just based that code off examples I have seen on this web page. Any help to make a simple stack class based off a linked list? For some reason it wants me to test my code using this class that was given to me which was this.
def isPalindrome(phrase):
forward = Queue()
reverse = Stack()
extractLetters(phrase, forward, reverse)
return sameSequence(forward, reverse)
#------------------------------------------------------------
def extractLetters(phrase, q, s):
for ch in phrase:
if ch.isalpha():
ch = ch.lower()
q.enqueue(ch)
s.push(ch)
#------------------------------------------------------------
def sameSequence(q, s):
while q.size() > 0:
ch1 = q.dequeue()
ch2 = s.pop()
if ch1 != ch2:
return False
return True
Thanks to whoever helps me in advance!
one way to create stack using python list is using list's append & pop functions.
Example stack class:
class stack(object):
def __init__(self):
self.data = []
def pop(self):
if self.isEmpty():
print "Nothing to remove from stack"
return None
return self.data.pop()
def push(self, item):
self.data.append(item)
def isEmpty(self):
if len(self.data) == 0:
return True
return False
s = stack()
s.push(1)
s.push(2)
s.push(3)
print s.pop()
print s.pop()
print s.pop()
print s.pop()
Output:
3
2
1
Nothing to remove from stack
None

How to create new class instances dynamically at runtime in python?

I am trying to solve this problem:
Imagine a (literal) stack of plates. If the stack gets too high, it
might topple. There- fore, in real life, we would likely start a new
stack when the previous stack exceeds some threshold. Implement a data
structure SetOfStacks that mimics this. SetOf- Stacks should be
composed of several stacks, and should create a new stack once the
previous one exceeds capacity. SetOfStacks.push() and
SetOfStacks.pop() should behave identically to a single stack (that
is, pop() should return the same values as it would if there were just
a single stack). Bonus: Implement a function popAt(int index) which
performs a pop operation on a specific sub-stack.
So I wrote the code:
#!/bin/env python
from types import *
class Stack:
def __init__(self):
self.items = []
self.capacity = 3
self.stackscount = 0
def create(self):
id = self.stackscount + 1
id = str(id) + "_stack"
# How to create a new instance of Stack class at runtime ?
# the __init__ must be run too.
def push(self, item):
if self.size() <= self.capacity:
self.items.append(item)
else:
self.create()
def pop(self):
return self.items.pop()
def popAt(self):
pass
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
s = Stack()
s.push(10)
How do I create a new s type object dynamically at runtime? I searched on the internet and found that using new.instance or new.classobj is the solution but when I did so my new object did not seem to have items from __init__ function. In python3, type() seems to be the answer but the docs doesn't have any examples.
You've confused yourself by referring to a "type object". In Python that means the class itself, not its instances.
To create new Stack objects, simply do what you're already doing: call the Stack class. You can append them to a list:
stacks = [Stack() for _ in range(5)]
However, as jon points out, that won't solve your problem since you haven't defined the SetOfStacks class.
You could simply use a parent-child relation : when a Stack is full, it creates a child and delegate next pushes to it. It could lead to :
class Stack:
def __init__(self, parent = None, id=None):
self.stackscount = 0
self.capacity = 3
self.items = []
self.parent = parent
self.id = id
self.child = None
def create(self):
id = self.stackscount + 1
id = str(id) + "_stack"
return Stack(self, id)
def push(self, item):
if self.size() <= self.capacity:
self.items.append(item)
else:
if self.child is None:
self.child = self.create()
self.child.push(item)
def pop(self):
if self.child is not None:
item = self.child.pop()
if len(self.child.items) == 0:
self.child = None
else:
item = self.items.pop()
return item
def popAt(self):
pass
def peek(self):
if self.child is not None:
item = self.child.peek()
else:
item = self.items[len(self.items)-1]
return item
def size(self):
l = len(self.items)
if self.child is not None:
l += self.child.size()
return l
s = Stack()
s.push(10)
popAt is still to be implemented, but I tested it and it correctly creates new stacks when pushing and empties and removes them when popping.
The implementation of popAt will require some evolutions to current pop implementation, to allow removing an intermediate stack :
def pop(self):
if self.child is not None:
item = self.child.pop()
if len(self.child.items) == 0:
self.child = self.child.child
if self.child is not None:
self.child.parent = self
else:
item = self.items.pop()
return item
def popAt(self, stacknumber):
s = self
for i in range(stacknumber):
s = s.child
if s is None:
return None
if len(s.items) == 0:
return None
item = s.items.pop()
if len(s.items) == 0 and s.parent is not None:
s.parent.child = s.child
if s.child is not None:
s.child.parent = s.parent
return item
The type() function is indeed what you are looking for. Documentation can be found here: https://docs.python.org/2/library/functions.html#type
You can call it like this:
# Bases is a tuple of parent classes to inherit
bases = Stack,
# Dict contains extra properties for the class, for example if you want to add a class variable or function
dict_ = {}
# Construct the class
YourClass = type('YourClass', bases, dict_)
# Create an instance of the class
your_instance = YourClass()
It looks like you are just looking at instance creation though:
class Stack(object):
def create(self):
id = self.stackscount + 1
id = str(id) + "_stack"
# How to create a new instance of Stack class at runtime ?
# the __init__ must be run too.
stack = Stack()

Categories

Resources