Queue Sandbox
# -*- coding: utf-8 -*-
"""qandstack.ipynb
Automatically generated by Colaboratory.
Original file is located at
    https://colab.research.google.com/drive/1Nr_QNCQNn2BqTil9swxDWfpsBcdumEbQ
# Queues and Stacks
## Queue
- think of a queue as a line of people queing up to be served
- FIFO (First In First Out)
## Stack
- think of a stack as a stack of recipts on a nail or pin
- LIFO (Last In First Out)
What data structure could be of use as an underlying data storage for a stack or queue?
"""
# lets write a simple stack
class Stack:
    def __init__(self):
        self.storage = []
    def push(self, item):
        """
    push the item on to the top of the stack
    """
        self.storage.append(item)
    def pop(self):
        """
    pop the item from the top of the stack returning said item if there is anything on the stack.
    otherwise return "The Stack is Empty"
    """
        if len(self.storage) > 0:
            return self.storage.pop()
        return "The Stack is Empty"
    def peek(self):
        if len(self.storage) > 0:
            return self.storage[-1]
        return "The Stack is Empty"
s = Stack()
s.push(10)
s.push(20)
s.push(30)
l = []
l.append(s.pop())
l.append(s.pop())
l.append(s.pop())
print(l)
# lets write a simple queue
class Queue:
    def __init__(self):
        self.storage = []
    def enqueue(self, item):
        """
    enqueues the item in to the queue
    """
        self.storage.append(item)
    def dequeue(self):
        """
    dequeue the item from the front of the queue returning said item if there is anything on the queue.
    otherwise return "The Queue is Empty"
    """
        if len(self.storage) > 0:
            return self.storage.pop(0)
        return "The Queue is Empty"
q = Queue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
l2 = []
l2.append(q.dequeue())
l2.append(q.dequeue())
l2.append(q.dequeue())
print(l2)
# lets write a more performant queue
"""
  F      R
[10]-> [20]-> None
"""
class LLNode:
    def __init__(self, data):
        self.data = data
        self.next = None
    def __repr__(self):
        return f"[{self.data}]"
class LLQueue:
    def __init__(self):
        self.front = None
        self.rear = None
    def enqueue(self, item):
        new_node = LLNode(item)
        if self.rear is None:
            self.front = new_node
            self.rear = new_node
        else:
            self.rear.next = new_node
            self.rear = new_node
    def dequeue(self):
        old_front = "The Queue is Empty"
        if self.front is not None:
            old_front = self.front
            self.front = old_front.next
        if self.front is None:
            self.rear = None
        return old_front
q = LLQueue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
l2 = []
l2.append(q.dequeue())
l2.append(q.dequeue())
l2.append(q.dequeue())
l2.append(q.dequeue())
print(l2)
"""# Break
# CODE 8119
"""
# lets write a more performant stack
class LLNode:
    def __init__(self, data):
        self.data = data
        self.next = None
    def __repr__(self):
        return f"[{self.data}]"
class LLStack:
    def __init__(self):
        self.top = None
    def push(self, data):
        new_node = LLNode(data)
        new_node.next = self.top
        self.top = new_node
    def pop(self):
        if self.top is not None:
            poped_node = self.top
            self.top = poped_node.next
            return poped_node
        else:
            return "The Stack is Empty"
"""# Demos"""
"""
You've encountered a situation where you want to easily be able to pull the
largest integer from a stack.
You already have a `Stack` class that you've implemented using a dynamic array.
Use this `Stack` class to implement a new class `MaxStack` with a method
`get_max()` that returns the largest element in the stack. `get_max()` should
not remove the item.
*Note: Your stacks will contain only integers. You should be able to get a
runtime of O(1) for push(), pop(), and get_max().*
"""
class Stack:
    def __init__(self):
        """Initialize an empty stack"""
        self.items = []
    def push(self, item):
        """Push a new item onto the stack"""
        self.items.append(item)
    def pop(self):
        """Remove and return the last item"""
        # If the stack is empty, return None
        # (it would also be reasonable to throw an exception)
        if not self.items:
            return None
        return self.items.pop()
    def peek(self):
        """Return the last item without removing it"""
        if not self.items:
            return None
        return self.items[-1]
class MaxStack:
    def __init__(self):
        # Your code here
        self.stack = Stack()
        self.maxes_stack = Stack()
    def push(self, item):
        """Add a new item onto the top of our stack."""
        # Your code here
        self.stack.push(item)
        if self.maxes_stack.peek() is None or item >= self.maxes_stack.peek():
            self.maxes_stack.push(item)
    def pop(self):
        """Remove and return the top item from our stack."""
        # Your code here
        item = self.stack.pop()
        if item == self.maxes_stack.peek():
            self.maxes_stack.pop()
        return item
    def get_max(self):
        """The last item in maxes_stack is the max item in our stack."""
        # Your code here
        return self.maxes_stack.peek()
ms = MaxStack()
ms.push(20)
ms.push(30)
ms.push(9)
ms.push(102)
ms.push(33)
ms.push(1)
ms.pop()
ms.pop()
ms.pop()
print(ms.get_max())
"""# Optionals"""
"""
Your goal is to define a `Queue` class that uses two stacks. Your `Queue` class
should have an `enqueue()` method and a `dequeue()` method that ensures a
"first in first out" (FIFO) order.
As you write your methods, you should optimize for time on the `enqueue()` and
`dequeue()` method calls.
The Stack class that you will use has been provided to you.
"""
class Song:
    def __init__(self, name, link):
        self.name = name
        self.link = link
    def __repr__(self):
        return f"{self.name}: {self.link}"
s1 = Song("Bob The Builder", "http://www.gogle.co.uk/")
s2 = Song("Eclipse - Pink Floyd 1", "http://www.yashoo.com")
s3 = Song("Bob The Builder 2", "http://www.gogle.co.uk/")
s4 = Song("Eclipse - Pink Floyd 2", "http://www.yashoo.com")
s5 = Song("Bob The Builder 3", "http://www.gogle.co.uk/")
s6 = Song("Eclipse - Pink Floyd 3", "http://www.yashoo.com")
s7 = Song("Bob The Builder", "http://www.gogle.co.uk/")
s8 = Song("Eclipse - Pink Floyd Uncut", "http://www.yashoo.com")
class Stack:
    def __init__(self):
        self.data = []
    def push(self, item):
        self.data.append(item)
    def pop(self):
        if len(self.data) > 0:
            return self.data.pop()
        return "The stack is empty"
class QueueTwoStacks:
    def __init__(self):
        # Your code here
        self.in_stack = Stack()
        self.out_stack = Stack()
    def enqueue(self, item):
        # Your code here
        self.in_stack.push(item)
    def dequeue(self):
        # Your code here
        if len(self.out_stack.data) == 0:
            while len(self.in_stack.data) > 0:
                stack_item = self.in_stack.pop()
                self.out_stack.push(stack_item)
            if len(self.out_stack.data) == 0:
                return "can not dequeue from an empty queue"
        return self.out_stack.pop()
# q = QueueTwoStacks()
# q.enqueue(20)
# q.enqueue(220)
# q.enqueue(201)
# q.enqueue(120)
# q.enqueue(230)
# q.enqueue(320)
# q.enqueue(3)
# l3 = []
# l3.append(q.dequeue())
# l3.append(q.dequeue())
# l3.append(q.dequeue())
# l3.append(q.dequeue())
# l3.append(q.dequeue())
# l3.append(q.dequeue())
# l3.append(q.dequeue())
q = QueueTwoStacks()
q.enqueue(s1)
q.enqueue(s2)
q.enqueue(s3)
q.enqueue(s4)
q.enqueue(s5)
q.enqueue(s6)
q.enqueue(s7)
l3 = []
l3.append(q.dequeue())
l3.append(q.dequeue())
l3.append(q.dequeue())
l3.append(q.dequeue())
l3.append(q.dequeue())
l3.append(q.dequeue())
l3.append(q.dequeue())
print(l3)Last updated