Creating a list of stacks in python - python

so I am trying to create a list of stack objects in Python. I have first created a class Stack that has simple methods that a Stack should have. I have then created another class called Stacks. I am trying to create a list of stacks. If a stack has more than 3 elements, it creates a new stack but I get an error when I try to display the elements. Could someone point out what I might be doing wrong here please?
class Stack:
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 size(self):
return len(self.items)
def printStack(self):
for item in reversed(self.items):
print (item)
class Stacks:
def __init__(self):
self.stacks = []
self.noOfStacks = 0
self.itemsOnStack = 0
def dev(self):
self.stacks.append(Stack())
# if len(self.stacks) != 0:
# self.noOfStacks += 1
def push(self, item):
if self.itemsOnStack > 3:
self.dev()
else:
self.itemsOnStack += 1
self.stacks[self.noOfStacks].push(item)
def pop(self, stackNo):
return self.stacks(noOfStacks).pop()
def size(self):
return len(self.stacks)
def printtack(self, index):
print (len(self.stacks(index)))
self.stacks(index).printStack()
stacky = Stacks()
stacky.dev()
stacky.push(3)
stacky.printtack(0)

Indexing lists in Python works by [] not (). Try
def printtack(self, index):
self.stacks[index].printStack()

One thing to note as kshikama said indexing should be done using [] not (),the other problem is using the len() method in the stack class u most override the __len__() method or as u have given use the size() method
class Stack:
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 size(self):
return len(self.items)
def printStack(self):
for item in reversed(self.items):
print (item)
class Stacks:
def __init__(self):
self.stacks = []
self.noOfStacks = 0
self.itemsOnStack = 0
def dev(self):
self.stacks.append(Stack())
#if len(self.stacks) != 0:
#self.noOfStacks += 1
def push(self, item):
if self.itemsOnStack > 3:
self.dev()
else:
self.itemsOnStack += 1
self.stacks[self.noOfStacks].push(item)
def pop(self, stackNo):
return self.stacks(noOfStacks).pop()
def size(self):
return len(self.stacks)
def printtack(self, index):
print (self.stacks[index].size())
self.stacks[index].printStack()
stacky = Stacks()
stacky.dev()
stacky.push(3)
stacky.printtack(0)
OUTPUT
1
3

Related

Stack in Python: print a list

I have stack code:
class Stack:
def __init__(self):
self.__data = []
def empty(self):
return len(self.__data) == 0
def size(self):
return len(self.__data)
def push(self, x):
self.__data.append(x)
def pop(self):
return self.__data.pop()
and adds numbers 1, 2:
stack = Stack()
stack.push(1)
stack.push(2)
and I don't know how to print __data list?
so that it shows 1,2 in the list?
[1,2]
As __data is a private attribute of stack object, it cannot be accessed outside the class. Instead define an instance method to print the stack list as shown below.
class Stack:
def print_stack(self):
print(self.__data)
Now if you call print_stack() on an instance. It will print the __data list.
You can use __str__ method to print the values using print() or __repr__ for direct representation.
class Stack:
def __init__(self):
self.data = []
def empty(self):
return len(self.data) == 0
def size(self):
return len(self.data)
def push(self, x):
self.data.append(x)
def pop(self):
return self.data.pop()
def __str__(self):
return str(self.data)
def __repr__(self):
return str(self.data)
>>> stack = Stack()
>>> stack.push(1)
>>> stack.push(2)
>>> print(stack) ## using __str__
# [1, 2]
>>> stack ## using __repr__
# [1, 2]
I have one more question. My code:
class Stack:
def __init__(self):
self.data = []
def empty(self):
return len(self.data) == 0
def size(self):
return len(self.data)
def push(self, x):
self.data.append(x)
def pop(self):
if len(self.data) == 0:
print("underflow")
else:
return self.data.pop()
def __str__(self):
return str(self.data)
stack = Stack()
stack.push(1)
stack.push(2)
print(stack)
I print the list as I wanted:
[1,2]
Now i wonder if i can work on this list? That is, as always on the lists:
In this case:
list = stack
list[0]
1
Can you recommend some simple courses where do Class is explained? I feel confused and my questions seem simple...

Implementing a queue in Python - two isempty() methods giving different answers

I'm doing some basic Python programming practice exercises and tried to implement a queue (using lists). Unfortunately, I'm getting behavior for my isempty() function that I don't understand. When running the code below, the last two lines give different answers: A yields False, while B yields True. Why doesn't A also yield False?
class Queue:
def __init__(self):
self.items = []
def push(self,item):
self.items.insert(0,item)
def pop(self):
return self.items.pop()
def size(self):
return len(self.items)
def isempty(self):
return self.size == 0
q = Queue()
q.push("a")
q.push("b")
print(q.pop())
print(q.isempty())
print(q.pop())
print(q.isempty()) # shouldn't this (A)...
print(q.size()==0) # ...and this (B) yield the same answer?
Just change your isempty() method to:
def isempty(self):
return self.size() == 0
Your implementation of Queue.isempty() is checking to see if the method size is equal to the integer 0, which will never be true.
class Queue:
def __init__(self):
self.items = []
def push(self,item):
self.items.insert(0,item)
def pop(self):
return self.items.pop()
def size(self):
return len(self.items)
def isempty(self):
return self.size == 0
q = Queue()
print(q.size)
Produces:
<bound method Queue.size of <__main__.Queue object at 0x02F4EA10>>
The easiest solution is to use Christopher Shroba's suggestion to modify your Queue.isempty() implementation to use the list's size method.

implementing Search Tree in Python

I know there are already multiple question on this topics, but none of them has the solution to my problem.
I'm trying to build a Search Tree that has two options:
build the tree
get from the user a tree and search in it (e.g. as list, dictionary, ...)
My problem is with the second option, as it appears to be an AttributeError .
When I run my code with no given tree it works fine, but when I try it with a list an error message appears:
self.root.add(i)
AttributeError: 'NoneType' object has no attribute 'add'
My code:
import unittest
class Testfunction(unittest.TestCase):
def test(self):
init = SearchTree(['x', 'b', 'eee'])
init.add('left')
init.add('right')
init.tolist()
self.assertEqual(init.__contains__('left'),True )
self.assertEqual(init.add('xx'), None )
class Node:
def __init__(self, val):
self.value = val
self.left = None
self.right = None
def insert(self, item):
if self.value == item:
return False
elif self.value > item:
if self.left:
return self.left.insert(item)
else:
self.right = Node(item)
return True
def find(self, item):
if self.value == item:
return True
elif self.value > item:
if self.left:
return self.left.find(item)
else:
return False
else:
if self.right:
return self.right.find(item)
else:
return False
def tolist(self):
if self:
if self.left:
self.left.tolist()
if self.right:
self.right.tolist()
class SearchTree:
def __init__(self, items=None):
# if items . then should be inserted
self.items = items
self.root = None
if items:
for i in self.items:
self.root.add(i)
def __contains__(self, item):
if self.root:
return self.root.find(item)
else:
return False
def add(self, item):
if self.root:
return self.root.insert(item)
else:
self.root = Node(item)
def tolist(self):
self.root.tolist()
test = Testfunction()
test.test()
When you check the items, modify the line to use your built add.
if items:
for i in self.items:
# Instead of self.root.add(i)
self.add(i)

How to implement selection sort using forward iterators?

I'm working on a homework assignment where I shall implement selection sorting using forward iterators for both python lists and linked lists(single).
Here are some codes I have for iterators:
from abc import *
class ForwardIterator(metaclass=ABCMeta):
#abstractmethod
def getNext(self):
return
#abstractmethod
def getItem(self):
return
#abstractmethod
def getLoc(self):
return
#abstractmethod
def clone(self):
return
def __eq__(self, other):
return self.getLoc() == other.getLoc()
def __ne__(self, other):
return not (self == other)
def __next__(self):
if self.getLoc() == None:
raise StopIteration
else:
item = self.getItem()
self.getNext()
return item
class ForwardAssignableIterator(ForwardIterator):
#abstractmethod
def setItem(self, item):
"""Sets the item at the current position."""
return
class PythonListFAIterator(ForwardAssignableIterator):
def __init__(self, lst, startIndex):
self.lst = lst
self.curIndex = startIndex
def getNext(self):
self.curIndex += 1
def getItem(self):
if self.curIndex < len(self.lst):
return self.lst[self.curIndex]
else:
return None
def setItem(self, item):
if self.curIndex < len(self.lst):
self.lst[self.curIndex] = item
def getLoc(self):
if self.curIndex < len(self.lst):
return self.curIndex
else:
return None
def clone(self):
return PythonListFAIterator(self.lst, self.curIndex)
The LinkedListFAIterator is similar to PythonListFAIterator, plus getStartIterator, and __iter__ method.
I don't know how I can write codes to implement selection sort with one paraemter, a FAIterator (the forward iterator). Please help me. I know I shall find the minimum element and put it at the beginning of the list. I also know that I shall use the clone method to create multiple iterators to keep track of multiple locations at once. But I don't know how to write the code.
Please give me some hints.

Python Deque Array Ring Buffer

My goal for this is to:
use (capacity * ctypes.py_object)() to allocate a block of memory,
use geometric expansion with a factor of 2,
use circular buffer approach to handling indexes.
Can anyone point me in the right direction, I am very stuck. Thanks!
class deque:
capacity = 10
def __init__(self, size):
self._data = (capacity * ctypes.py_object)
self._size = 0
self._front = 0
def isEmpty(self):
return self._size == 0
def __len__(self):
return self._size
def __getitem__(self, index):
return self.list[index]
def addFront(self, item):
self.items.append(item)
def addRear(self, item):
self.items.insert(0, item)
def removeFront(self):
return self.items.pop()
def removeRear(self):
return self.items.pop(0)

Categories