Stack data structure in Python using lists - python

For the stack class below
class stack(list):
def __init__(self):
self.stack = []
self.top = -1
def isempty(self):
return self.stack == []
def push(self,x):
S.top = S.top + 1
return self.stack.append(x)
S = stack()
S.isempty() #True
S.push(5) #[5]
S.push(100) #[5,100]
print(S) # Returns empty stack []
Why does it not return the updated [5,100]?

The problem that you're asking about is that you're inheriting from list, even though you're not trying to act like a list. All this is doing is causing confusion. In particular, you're letting the list superclass define how your objects get displayed, and since you never do anything like self.append, only self.stack.append, that means it's always going to display like an empty list.
Once you fix that, your objects will always print something like this:
<__main__.stack at 0x11d919dd8>
If you want to customize that, you need to write a __repr__ method, and decide what you want it to look like.
class stack:
def __init__(self):
self.stack = []
self.top = -1
def __repr__(self):
return f'<stack({self.stack})>'
def isempty(self):
return self.stack == []
def push(self,x):
S.top = S.top + 1
return self.stack.append(x)
There are additional bugs in your code—you've still got a method that mutates the global S instead of self, and you're returning the result of list.append, which always returns None, and maybe more beyond—but these two changes will together solve the specific problem you're asking about.

Related

Nested classes — can't understand their functionality

I'm learning about classes in Python, particularly about nested classes.
I'm trying to execute the below code and I get an error: int object is not callable, but
I don't understand why!
All I want is to create an object that identify Man, and he has hands, and the hands have their own size, length, etc...
I want to be able to set the hand size and get its value in the most elegant and easy way as possible and nothing work for me... I tried the below code and I really thought it would work but it didn't and now I know that "I Don't know" what to do for real.
class Man:
def __init__(self, name):
self.name = name
self.hand = self.Hand_Object() # Here we reference an Object called
# "hand" to the subvlass "Hand_Object".
def length(self , length):
self.length = length
def handsize(self, size=None): # This "handsize()" function will call the
# subclass function "length()" out from the
# Hand_Object vlass when it will be issued
# in the program.
if size==None:
return = self.hand.length()
else:
self.hand.length(size) # The "length()" function of the "Hand_Object"
# class requires a variable, so when we call
# that function we need to add a variable to it.
class Hand_Object:
def length(self, length=None):
if length == None:
return self.length
else:
self.length = length
def fingers(self, fingers):
self.fingers = fingers
myman = Man('shlomi')
myman.handsize(6)
print(myman.handsize()) # Here I get the error.
The issue is the line self.length = length in Hand_Object. You're overwriting the function length with an integer. You should call the function and the variable something different.

Python 2.7, what's the benefit of this kind of initialization in class?

class LogicGate(object):
def __init__(self, n):
self.label = n
self.output = None # ????????????
def getOutput(self):
self.output = self.performGateLogic()
return self.output
def getLabel(self):
return self.label
class BinaryGate(LogicGate):
def __init__(self, n): # ?????????????????
LogicGate.__init__(self, n)
self.pinA = None # ??????????????
self.pinB = None # ??????????????
def getPinA(self):
return int(raw_input('Enter Pin A input for gate' + self.getLabel() + '-->'))
def getPinB(self):
return int(raw_input('Enter Pin A input for gate' + self.getLabel() + '-->'))
class UnaryGate(LogicGate):
def __init__(self, n): # ??????????????
LogicGate.__init__(self, n)
self.pin = None # ?????????????
def getPin(self):
return int(raw_input('Enter Pin input for gate' + self.getLabel() + '-->'))
class AndGate(BinaryGate):
def __init__(self, n): # ????????????
BinaryGate.__init__(self, n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a == 1 and b == 1:
return 1
else:
return 0
This code belongs to Problem Solving with Algorithms and Date Structures.
When I remove the lines before the comment '# ????????', the code can run normally.
Why does the author write the code like this?
Whether is it a good code style?
Can I always remove these lines before the comment '# ????????' ?
The author writes the code like that because it is good practice to never have uninitialised members and class parents, static checkers moan if you do.
The reason that it is not good practice is for future maintainability - let us say that the base class, LogicGate, was to gain a new property - say propagation_delay and a new method that allowed simulations to called get_response_time which relied on the current output state and the required, possibly new, state. If all the code that was derived from that class did the correct initialisations then it would all work fine, without any changes. If you remove those lines and such a new method was introduced you would have to go back through all of the child classes adding them back in before your final class would work for that method, with the chance that you would miss one.
Daft as it sounds doing things properly now is actually future laziness - it only takes you seconds when you are creating a class to make sure everything is initialised - debugging an uninitialised class can take hours.
First:
The __init__ functions are the constructors of the classes, you can read about them here.
Second:
Your code will run without those lines but the question is why and is it ok to remove them?
For example if you remove the following init
class UnaryGate(LogicGate): # LogicGate is the superclass
def __init__(self, n):
LogicGate.__init__(self, n)
The constructor of the super-class LogicGate will be called directly.
Third:
Ok, so can we remove the self.xxx = None?
class BinaryGate(LogicGate):
def __init__(self, n):
LogicGate.__init__(self, n)
self.pinA = None
self.pinB = None
We could remove those 2 Lines too but consider this code
bg = BinaryGate("binaryGate1")
print bg.pinA
This would throw an error because pinA is undefined.
If you do not remove the self.pinA = None in __init__ the code will run and None will be printed.

Make a topological search function with given depth first search function

I am making a stack of vertices after a topological sort. I think the code I have written is correct but I do not know how to print out the stack.
This is my code:
def toposort (self):
stack = Stack()
top = []
for i in range(0,len(self.Vertices)):
self.Vertices[i].visited == False
for i in range(0,len(self.Vertices)):
if not (self.Vertices[i]).wasVisited():
self.dffs(self.getIndex(i),stack)
return stack
def dffs(self, v, stack):
self.Vertices[v].visited == True
for i in range(0,len(self.Vertices)):
if (self.adjMat[v][i] > 0) and (not (self.Vertices[i]).wasVisited()):
self.dffs(self.getIndex(self.Vertices[i]), stack)
print (self.Vertices[v])
stack.push(v)
and the output I get is: <main.Stack object at 0x104adf1d0>
I'm sure it is an easy fix but I just don't know how. My graph is a bunch of vertexes and labels with weights.
class Stack (object):
def __init__ (self):
self.stack = []
# add an item to the top of the stack
def push (self, item):
self.stack.append ( item )
# remove an item from the top of the stack
def pop (self):
return self.stack.pop()
# check what item is on top of the stack without removing it
def peek (self):
return self.stack[len(self.stack) - 1]
# check if a stack is empty
def isEmpty (self):
return (len(self.stack) == 0)
# return the number of elements in the stack
def size (self):
return (len(self.stack))
It seems like your actual question is "how do I print my Stack object". By default calling str() on a custom class just prints out the type name and its id, which isn't very helpful. To print out the contents instead, add the __str__() method to Stack:
def __str__(self):
return str(self.stack)

Python27: random() after a setstate() doesn't produce the same random number

I have been subclassing an Python's random number generator to make a generator that doesn't repeat results (it's going to be used to generate unique id's for a simulator) and I was just testing to see if it was consistent in it's behavior after it has been loaded from a previours state
Before people ask:
It's a singleton class
No there's nothing else that should be using that instance (a tear down sees to that)
Yes I tested it without the singleton instance to check
and yes when I create this subclass I do call a new instance ( super(nrRand,self).__init__())
And yes according to another post I should get consistent results see: Rolling back the random number generator in python?
Below is my test code:
def test_stateSavingConsitantcy(self):
start = int(self.r.random())
for i in xrange(start):
self.r.random()
state = self.r.getstate()
next = self.r.random()
self.r.setstate(state)
nnext = self.r.random()
self.assertEqual(next, nnext, "Number generation not constant got {0} expecting {1}".format(nnext,next))
Any help that can be provided would greatly appreciated
EDIT:
Here is my subclass as requested
class Singleton(type):
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton,self).__call__(*args,**kwargs)
return self._instances[self]
class nrRand(Random):
__metaclass__ = Singleton
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
super(nrRand,self).__init__()
self.previous = []
def random(self):
n = super(nrRand,self).random()
while n in self.previous:
n = super(nrRand,self).random()
self.previous.append(n)
return n
def seed(self,x):
if x is None:
x = long(time.time()*1000)
self.previous = []
count = x
nSeed = 0
while count < 0:
nSeed = super(nrRand,self).random()
count -= 1
super(nrRand,self).seed(nSeed)
while nSeed < 0:
super(nrRand,self).seed(nSeed)
count -= 1
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
def setstate(self,state):
self.previous = state[0]
super(nrRand,self).setstate(state[1])
getstate and setstate only manipulate the state the Random class knows about; neither method knows that you also need to roll back the set of previously-generated numbers. You're rolling back the state inherited from Random, but then the object sees that it's already produced the next number and skips it. If you want getstate and setstate to work properly, you'll have to override them to set the state of the set of already-generated numbers.
UPDATE:
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
This shouldn't directly use self.previous. Since you don't make a copy, you're returning the actual object used to keep track of what numbers have been produced. When the RNG produces a new number, the state returned by getstate reflects the new number. You need to copy self.previous, like so:
def getstate(self):
return (self.previous[:], super(nrRand, self).getstate())
I also recommend making a copy in setstate:
def setstate(self, state):
previous, parent_state = state
self.previous = previous[:]
super(nrRand, self).setstate(parent_state)

Python: referencing class object list of lists

I am fairly new to python. I have tried to define a class, I then want to create an instance from a file, then refer to specific pieces of it, but cannot seem to. This is Python 3.3.0
Here's the class....
class Teams():
def __init__(self, ID = None, Team = None, R = None, W = None, L = None):
self._items = [ [] for i in range(5) ]
self.Count = 0
def addTeam(self, ID, Team, R=None, W = 0, L = 0):
self._items[0].append(ID)
self._items[1].append(Team)
self._items[2].append(R)
self._items[3].append(W)
self._items[4].append(L)
self.Count += 1
def addTeamsFromFile(self, filename):
inputFile = open(filename, 'r')
for line in inputFile:
words = line.split(',')
self.addTeam(words[0], words[1], words[2], words[3], words[4])
def __len__(self):
return self.Count
Here's the code in Main
startFileName = 'file_test.txt'
filename = startFileName
###########
myTestData = Teams()
myTestData.addTeamsFromFile(startFileName)
sample data in file
100,AAAA,106,5,0
200,BBBB,88,3,2
300,CCCC,45,1,4
400,DDDD,67,3,2
500,EEEE,90,4,1
I think I am good to here (not 100% sure), but now how do I reference this data to see... am i not creating the class correctly? How do I see if one instance is larger than another...
ie, myTestData[2][2] > myTestData[3][2] <----- this is where I get confused, as this doesn't work
Why don't you create a Team class like this :
class Team():
def __init__(self, ID, Team, R=None, W = 0, L = 0)
# set up fields here
Then in Teams
class Teams():
def __init__(self):
self._teams = []
def addTeam (self, ID, Team, R=None, W = 0, L = 0)
team = Team (ID, Team, R=None, W = 0, L = 0)
self._teams.append (team)
Now If i got it right you want to overwrite the > operator's behaviour.
To do that overload __gt__(self, other) [link]
So it will be
class Team ():
# init code from above for Team
def __gt__ (self, otherTeam):
return self.ID > otherTeam.ID # for example
Also be sure to convert those strings to numbers because you compare strings not numbers. Use int function for that.
The immediate problem you're running into is that your code to access the team data doesn't account for your myTestData value being an object rather than a list. You can fix it by doing:
myTestData._items[2][2] > myTestData._items[3][2]
Though, if you plan on doing that much, I'd suggest renaming _items to something that's obviously supposed to be public. You might also want to make the addTeamsFromFile method convert some of the values it reads to integers (rather than leaving them as strings) before passing them to the addTeam method.
An alternative would be to make your Teams class support direct member access. You can do that by creating a method named __getitem__ (and __setitem__ if you want to be able to assign values directly). Something like:
def __getitem__(self, index):
return self._items[index]
#Aleksandar's answer about making a class for the team data items is also a good one. In fact, it might be more useful to have a class for the individual teams than it is to have a class containing several. You could replace the Teams class with a list of Team instances. It depends on what you're going to be doing with it I guess.

Categories