Understanding Stacks and Queues in python - python

So i was given this question. Consider the Stack and the Queue class with standard set of operations. Using the Stack and Queue class, what items are contained in them just before the mysteryFunction is called AND just after the mysteryFunction is called?
Here is the code:
def mysteryFunction(s, q):
q.enqueue('csc148')
q.enqueue(True)
q.enqueue(q.front())
q.enqueue('abstract data type')
for i in range(q.size()):
s.push(q.dequeue())
while not s.is_empty():
q.enqueue(s.pop())
if __name__ == '__main__':
s=Stack()
q=Queue()
#About to call mysteryFunction
#What are contents of s and q at this point?
mysteryFunction(s, q)
#mysteryFunction has been called.
#What are contents of s and q at this point?
I'm having trouble understanding object oriented programming as i'm new to this topic. Is there any link that breaks down Stacks and Queues and what they do?

In general, stacks are LIFO and queues are FIFO.
In Python, you can use the collections module to experiment with stacks and queues:
>>> from collections import deque
>>> stack = deque()
>>> stack.append(10)
>>> stack.append(20)
>>> stack.append(30)
>>> stack
deque([10, 20, 30])
>>> stack.pop() # LIFO
30
>>> stack.pop()
20
>>>
>>> queue = deque()
>>> queue.append(10)
>>> queue.append(20)
>>> queue.append(30)
>>> queue
deque([10, 20, 30])
>>> queue.popleft() # FIFO
10
>>> queue.popleft()
20

See following links for more information:
Stack
Queue
Visually these two data structures can be seen in a following way:
Stack:
Description:
There are variations of this data structure. However, in simple terms - as one can observe in the image provided, when you add to this data structure you place on top of what is already there and when you remove you also take from the top. You can view it as a stack of books which you go through one by one starting from the top and all the way down.
Queue
Description:
There are also variations on this particular data structure, however in simple terms - as you can see in the image provided, when you add to this data structure the new element goes in the begining and when you remove its the last element from the list which is being removed. You can imagine it as a queue you got in a shop where you stand behind a lot of people waiting for your turn to come to the counter to pay for your items.

To test this line by line, here are implementations of the classes (wrappers around deque) that are used in the task:
from collections import deque
class Queue(deque):
enqueue = deque.append
dequeue = deque.popleft
def front(self):
return self[-1]
def size(self):
return len(self)
class Stack(deque):
push = deque.append
def is_empty(self):
return not self

STACK #LIFO
class stack(object):
def __init__(self):
self.items = []
def isEmpty(self):
return self.items==[]
def push(self,item):
self.items.append(item)
def pop (self):
return self.items.pop()
def peek(self):
return self.items[len(self.items) - 1]
def size(self):
return (len(self.items))
s = stack()
print (s.isEmpty())
>> True
s.push(1)
s.push('3')
s.peek()
>>'3'
s.size()
>> 2
Queue #FIFO
class Queue(object):
def __init__(self):
self.items = []
def isEmpty(self):
return self.items==[]
def enqueue(self,item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return (len(self.items))
q = Queue()
q.isEmpty()
>>True
q.enqueue(1)
q.enqueue(2)
q.dequeue()
>>1

The first code explains about the stack , we need to create a list and while pushing the element use append and fill the list , similar to what we have in array stack. While pop , pop out the end from where you pushed it.
class Stack:
def __init__(self):
self.stack = []
def push_element(self,dataval):
self.stack.append(dataval)
return self.stack
def pop_element(self):
if len(self.stack) ==0:
print("Stack is empty")
else:
self.stack.pop()
return self.stack
def peek_element(self):
return self.stack[0]
class Queue:
def __init__(self):
self.stack = []
def push_ele(self,data):
self.stack.append(data)
def pop_ele(self):
self.stack.pop(0)
def display(self):
print(self.stack)

class stack:
def __init__(self,n): #constructor
self.no = n # size of stack
self.Stack = [] # list for store stack items
self.top = -1
def push(self): # push method
if self.top == self.no - 1: # check full condition
print("Stack Overflow.....")
else:
n = int(input("enter an element :: "))
self.Stack.append(n) # in list add stack items use of append method
self.top += 1. # increment top by 1
def pop(self): # pop method
if self.top == -1: # check empty condition
print("Stack Underflow....")
else:
self.Stack.pop(). # delete item from top of stack using pop method
self.top -= 1 # decrement top by 1
def peep(self): #peep method
print(self.top,"\t",self.Stack[-1]) #display top item
def disp (self): # display method
if self.top == -1: # check empty condition
print("Stack Underflow....")
else:
print("TOP \tELEMENT")
for i in range(self.top,-1,-1): # print items and top
print(i," \t",self.Stack[i])
n = int(input("Enter Size :: ")) # size of stack
stk = stack(n) # object and pass n as size
while(True): # loop for choice as a switch case
print(" 1: PUSH ")
print(" 2: POP ")
print(" 3: PEEP ")
print(" 4: PRINT ")
print(" 5: EXIT ")
option = int(input("enter your choice :: "))
if option == 1:
stk.push()
elif option == 2:
stk.pop()
elif option == 3:
stk.peep()
elif option == 4:
stk.disp()
elif option == 5:
print("you are exit!!!!!")
break
else:
print("Incorrect option")

Related

Putting Stack in descending order using push and pop in python

accepts strings from user and generates stack till it gets the input "End"
Next, it should sort the given stack in a decent order
Finally, print the sorted stack
I cannot seem to get the logic right using only push and pop methods whereby push is a function putting elements to the top of the stack and pop is a function removing the top element of the stack and storing it. I am only allowed to use push and pop, the sorting algorithm is the only one I cant do.
from Stack import Stack
def display_(S_):
node = S_.list.head
while node != None:
print(node.data)
node = node.next
def Sorting_Stack(stack,k):
v = 0
ar = 0
temp = Stack()
for i in range(k):
v = stack.pop()
temp.push(v)
node = stack.list.head
tnode = temp.list.head
if tnode.data > node.data:
ar = temp.pop()
stack.push(ar)
display_(stack)
if __name__ == '__main__':
stack = Stack()
string = ""
k = 0
while string!='End':
string = input()
if string == 'End':
break
else:
stack.push(string)
k += 1
Sorting_Stack(stack, k)
#this is Stack.py--------
from Node import Node
from LinkedList import LinkedList
class Stack:
def __init__(self):
self.list = LinkedList()
def push(self, new_item):
# Create a new node to hold the item
new_node = Node(new_item)
# Insert the node as the list head (top of stack)
self.list.prepend(new_node)
def pop(self):
# Copy data from list's head node (stack's top node)
popped_item = self.list.head.data
# Remove list head
self.list.remove_after(None)
# Return the popped item
return popped_item
#Stack Class
class Stack:
def __init__(self):
self.stack = []
def push(self,item):
if item == 'End':
self.sort()
else:
self.stack.append(item)
def pop(self):
if len(self.stack) == 0:
print("Stack Is Empty")
else:
self.stack.pop()
def sort(self):
self.stack.sort()
print(self.stack)
logic For giving Inputs
s = Stack()
item = None
while item !='End':
print("Type 'End' For Ending the Stack Push Operation")
item = input("Enter Item: ")
s.push(item)
s.push(item)
Program will take inputs till we give input as 'End'.
After given 'End' as Input it will sort the stack and print it.

How do I "run" a function that is in a queue?

Basically I created a queue in Python with some functions (that the user put in the order he wants) and now I want to execute this functions in order, but I really didn't find what which order do that.
The queue:
class Queue:
def __init__(self):
self.elements = []
def enqueue(self, data):
self.elements.append(data)
return data
def dequeue(self):
return self.elements.pop(0)
def rear(self):
return self.elements[-1]
def front(self):
return self.elements[0]
def is_empty(self):
return len(self.elements) == 0
The functions:
if (escolha=='2'):
print("Type your hotkey. Ex: alt+tab+ [3 keys maximum]")
my_var = input("")
my_var = my_var.split('+')
def hotchave():
pyautogui.hotkey(str(my_var[0]),str(my_var[1]),str(my_var[2]))
queue.enqueue(hotchave)
if (escolha=='3'):
write=input('What will be written?: ')
def escrever():
pyautogui.write(write)
queue.enqueue(escrever)
I already tried things like return, front but didn't seem to work.
There's several different ways to do what you want, some of which require to modify your class. Since you say you would like to retrieve and run multiple functions from the queue, I would suggest making it possible to iterate its current contents, which can be done simply by adding an __iter__() method to the class.
The following shows how to do that, along with how to make use of it.
class Queue:
def __init__(self):
self.elements = []
def enqueue(self, data):
self.elements.append(data)
return data
def dequeue(self):
return self.elements.pop(0)
def rear(self):
return self.elements[-1]
def front(self):
return self.elements[0]
def is_empty(self):
return len(self.elements) == 0
def __iter__(self):
'''Iterate current contents.'''
return (elem for elem in self.elements)
Sample usage:
queue = Queue()
my_var = 'alt+shift+k'
my_var = my_var.split('+')
def hotchave():
print('vars:', str(my_var[0]), str(my_var[1]), str(my_var[2]))
queue.enqueue(hotchave)
write = 'This will be written'
def escrever():
print(write)
queue.enqueue(escrever)
# Execute commands in Queue.
for command in queue:
command()
print('-fini-')
Output:
vars: alt shift k
This will be written
-fini-

Queue implementation display function error

class Queue:
def __init__(self): '''initialization of function'''
self.items = []
def is_empty(self): '''Checking if queue is empty or not'''
return self.items == []
def enqueue(self, data): '''Adding value '''
self.items.append(data)
def dequeue(self): ''' Removing value'''
return self.items.pop(0)
def dis(self): '''Printing the stored item in queue'''
print(items)
After that initialization of Queue:
q = Queue()
while True:
print('enqueue <value>')
print('dequeue')
print('dis')
print('quit')
do = input('What would you like to do? ').split()
operation = do[0].strip().lower()
if operation == 'enqueue':
q.enqueue(int(do[1]))
elif operation == 'dequeue':
if q.is_empty():
print('Queue is empty.')
else:
print('Dequeued value: ', q.dequeue())
elif operation == 'dis':
q.dis()
elif operation == 'quit':
break
else:
print("Enter the correct operation")
I'm not able to display the items which are enqueued in the Queue. How could I use dis() method to display items in it?
Think you should print self.items (instead of items)
def dis(self): '''Printing the stored item in queue'''
print(self.items)
That'll output the list using standard formatting, not very pretty so you'll probably want to add some extra logic for pretty-printing.
If you want to restrict the queue size, you could do this by simply ignoring items past a certain limit. For this you'll need to implement a limit, along with logic for checking the limit. For example:
class Queue:
def __init__(self, size=8): '''initialization of function'''
self.items = []
self.size = size
def is_empty(self): '''Checking if queue is empty or not'''
return self.items == []
def enqueue(self, data): '''Adding value '''
if len(self.items) < self.size:
self.items.append(data)
else:
pass # behavior when queue is already full
def dequeue(self): ''' Removing value'''
return self.items.pop(0)
def dis(self): '''Printing the stored item in queue'''
print(items)
class Queue:
items=[]
size=5
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def enqueue(self, data):
self.items.append(data)
def dequeue(self):
return self.items.pop(0)
def dis(self):
print(self.items)
def is_full(self):
if (len(self.zitems)>5):
print("Queue is full")
else:
print("Not full")
Inizialize the items=[] and in dis method add self.items.Also, you could check if the size of the queue is full or not

printing stack in a new line within a class

I have a linked stack class and I'm having the problem of printing the elements in the stack, with each element in a new line. The str function in the linked stack class is printing every element in a new line which is what i wanted but it even prints an extra new line at the end.
class Node:
def __init__(self,item,the_next = None):
self.item = item
self.next = the_next
def __str__(self):
return str(self.item)
class LinkedStack:
def __init__(self):
self.top = None
self.count = 0
def __len__(self):
return self.count
def is_empty(self):
return self.count == 0
def isFull(self):
return False
def reset(self):
self.top = None
self.count = 0
def __str__(self): #im having the issue here whereby it prints a newline even after printing the last element
current = self.top
ans = ""
while not (current is None):
ans += str(current)
ans += '\n'
current = current.next
return ans
if __name__ == "__main__":
L = LinkedStack()
L.push(1)
L.push(2)
L.push(3)
print(L)
The output i get is:
3
2
1
#an extra newline printed here which is not wanted
I'm looking for a way to improvise the str function in the Linked Stack class in order to get rid of the redundant new line at the end. Any help is much appreciated.
Why not simply trim the return value of __str__ like so return ans[:-1] ? Since you always append a new line after adding an element to the string.
On a side note, it could be nicer to write your function like so:
def __str__(self):
strs = []
cur = self.top
while cur is not None:
strs = [str(cur)] + strs
cur = cur.next
return '\n'.join(strs)
You could move the addition of the newline until after you get the next item, and check it is not None before you then append it.
A further optimisation then is to move the break condition to that point:
while True:
ans += str(current)
current = current.next
if current is None:
break
ans += '\n'

Taking a queue of integers and making copies of that element

"Write a function named stutter that accepts a queue of integers as a parameter and replaces every element of the queue with two copies of that element in the original queue."
Example:
q1 = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
stutter(q1)
while not queue.isempty():
print(queue.dequeue(), end=' ')
should give answer as "1 1 2 2 3 3"
class Queue:
def __init__(self):
self.items = []
def is_empty(self):
return self.items == []
def enqueue(self, item):
self.items.insert(0,item)
def dequeue(self):
return self.items.pop()
def size(self):
return len(self.items)
def check_empty(self):
if self.items == []:
return True
def stutter(Q):
queue=Queue()
stack = Stack()
while not queue.isempty():
stack.push(queue.dequeue())
while not stack.isempty():
queue.enqueue(stack.pop())
That is the code that i have written, with that i can get it to print once and once only, i can't get it to duplicate and sort in order.
Try using this (can't test at the moment):
def stutter(queue):
# iterate all items
for _ in range(queue.size()):
# store item in local context
item = queue.dequeue()
# push two *references* to item into the queue
queue.enqueue(item)
queue.enqueue(item)
This will iterate all items once, immediately pushing two copes to the back of the queue. The first pushed items should be the first once this iteration is over.
Notice that objects will be not be duplicated,and there will be two references to the same object in the queue.
Tip: there is already a queue implementation in Python. You can use it by importing queue
In [17]:
def stutter(q):
for i in range(q.size()):
elm = q.dequeue()
q.enqueue(elm)
q.enqueue(elm)
In [18]:
q1 = Queue()
q1.enqueue(1)
q1.enqueue(2)
q1.enqueue(3)
stutter(q1)
print q1
[3, 3, 2, 2, 1, 1]
Note, I added a str method to the Queue class to see results.
class Queue:
# SAME AS BEFORE
def __str__(self):
return str(self.items)
You can also cheat because python does not have private instance variables. I would not recommend it as an option.
def stutter(q):
q.items = sorted([elm for elm in q.items] + [elm for elm in q.items])
If you want to return using the desired output:
q1 = Queue()
q1.enqueue(1)
q1.enqueue(2)
q1.enqueue(3)
stutter(q1)
print(' '.join([str(elm) for elm in q1.items]))
1 1 2 2 3 3

Categories