I am new to Python language. i am trying to implement stack operation using classes and objects. This is the code i have written till now:
class StackOperation:
def __init__(self):
front = 0
MyStack = [None]*5
def PushValue(self, value):
MyStack[front] = value
front += 1
def PopValue(self):
return MyStack[front -= 1]
def PrintStack(self):
for i in range(len(MyStack)):
print MyStack[i]
stack = StackOperation()
stack.PushValue(10)
print stack.PopValue()
But this code gives me an error when i'm trying to run it. The error says:
"NameError: global name 'MyStack' is not defined"
I'm not sure what mistake i have made.
I would be great full if someone could help me.
Your MyStack and front are not instance variable that's why you can't access it. You have to make it instance variable using self.
class StackOperation:
def __init__(self):
self.front = 0
self.MyStack = [None]*5
def PushValue(self, value):
self.MyStack[self.front] = value
self.front += 1
def PopValue(self):
return self.MyStack[self.front]
def PrintStack(self):
for i in range(len(self.MyStack)):
print self.MyStack[i]
stack = StackOperation()
stack.PushValue(10)
print stack.PopValue()
You'd better use them as instance variable but not global variable since they are all in the same class. Like this:
#!/usr/bin/python
# -*- coding: utf-8 -*-
class StackOperation:
def __init__(self):
self.front = 0
self.MyStack = [None]*5
def PushValue(self, value):
self.MyStack[self.front] = value
self.front += 1
def PopValue(self):
return self.MyStack[self.front]
def PrintStack(self):
for i in range(len(self.MyStack)):
print self.MyStack[i]
stack = StackOperation()
stack.PushValue(10)
print stack.PopValue()
Related
I have my code setup this way:
class Test():
def __init__(self):
self.offset = [0,0]
#property
def offset(self):
return self._offset
#offset.setter
def offset(self,offset):
print("set")
self._offset = offset
test = Test()
test.offset[1] -= 1
but the setter is being called only once even though I am changing my variable twice, anyone is able to help ?
test.offset[1] -= 1
This line of your code is calling the getter not the setter. You get the list from the test object and then you alter its contents.
Same as if you wrote:
v = test.offset # get the list
v[1] -= 1 # alter the contents of the list
I was kinda playing around with Object Oriented Programming in python and ran into an error i havent encountered before..:
class Main:
def __init__(self, a , b):
self.a = a
self.b = b
def even(self):
start = self.a
slut = self.b
while start <= slut:
if start % 2 == 0:
yield start
start += 1
def odd(self):
start = self.a
slut = self.b
while start <= slut:
if start % 2 != 0:
yield start
start += 1
def display():
evens = list(num.even())
odds = list(num.odd())
print(f"{evens}'\n'{odds}")
num = Main(20, 50)
Main.display()
Take a look at the last class method, where there shouldent be a 'self' as a parameter for the program to Work..Why is that? I thought every class method should include a 'self' as a parameter? The program wont work with it
There should be a self parameter, if it's intended to be an instance method, and you would get an error if you tried to use it as so, i.e., num.display().
However, you are calling it via the class, and Main.display simply returns the function itself, not an instance of method, so it works as-is.
Given that you use a specific instance of Main (namely, num) in the body, you should replace that with self:
def display(self):
evens = list(self.even())
odds = list(self.odd())
print(f"{evens}'\n'{odds}")
and invoke it with
num.display()
I'm having some problems initialising the parent class inside one subclass in Python 2. What I'm trying to do is override parent class attributes with properties in the child class.
Somehow, when I don't use the method _update_rect(self) in the child class setters (e.g. _set_grab(self, ps_value) and _set_grab(self, ps_value)), everything works as expected. But as soon as I use it the initialization of the parent class fails (the print '+++ END GfxObject initialisation' is not reached) and I get AttributeError: 'GfxRect' object has no attribute '_s_grab'.
As I said at the beginning, the code looks correct to me and the problematic method _update_rect only uses real attributes of itself so I have no idea where the error comes. I could avoid using inheritance in the child class as a workaround but I really want to understand what the problem is.
Regards and thanks in advance.
# Extra code to simplify test code
#=================================
class pygame:
class Rect:
def __init__(self, x, y, w, h):
self.x = x
self.y = y
self.w = w
self.h = h
# Classes
#========
class GfxObject(object):
"""
Generic Graphical Object which is the parent class of all the sub-classes below.
"""
def __init__(self):
self.i_x = 0
self.i_y = 0
self.s_grab = 'nw'
class GfxRect(GfxObject):
"""
Class to draw a rectangle.
"""
def __init__(self):
print '--- START GfxObject initialisation'
super(GfxRect, self).__init__()
print '+++ END GfxObject initialisation'
self._i_x = 0
self._s_grab = 'nw'
self._o_rect = None
print self
self._update_rect()
def __str__(self):
return unicode(self).encode('utf8')
def __unicode__(self):
u_out = u'<GfxRect>\n'
u_out += u' .i_x: %s\n' % self.i_x
u_out += u' ._i_x: %s\n' % self._i_x
u_out += u' .s_grab: %s\n' % self.s_grab
u_out += u' ._s_grab: %s\n' % self._s_grab
return u_out
def _get_grab(self):
return self._s_grab
def _get_x(self):
return self._i_x
def _set_grab(self, ps_value):
self._s_grab = ps_value
#self._update_rect()
self._b_redraw = True
def _set_x(self, i_value):
self._i_x = i_value
self._update_rect()
self._b_redraw = True
def _update_rect(self):
"""
Method to update the pygame rectangle object.
:return:
"""
# [1/?] Calculating the deltas for (x,y) based on the grab position
#------------------------------------------------------------------
if self._s_grab == 'nw':
i_dx = 0
elif self._s_grab == 'n':
i_dx = -800 / 2
else:
raise ValueError('Invalid grab value "%s"' % self._s_grab)
# [2/?] Applying the deltas
#--------------------------
i_x = self._i_x + i_dx
self._o_rect = pygame.Rect(i_x, 0, 800, 600)
i_x = property(fget=_get_x, fset=_set_x)
s_grab = property(fget=_get_grab, fset=_set_grab)
# Main code
#==========
if __name__ == '__main__':
o_progbar = GfxRect()
UPDATE: Moving the initialisation of the parent class in the child class after the internal properties seems to fix the problem which it's even more weird for me.
Before (doesn't work)
def __init__(self):
print '--- START GfxObject initialisation'
super(GfxRect, self).__init__()
print '+++ END GfxObject initialisation'
self._i_x = 0
self._s_grab = 'nw'
self._o_rect = None
self._update_rect()
After (works)
def __init__(self):
self._i_x = 0
self._s_grab = 'nw'
self._o_rect = None
print '--- START GfxObject initialisation'
super(GfxRect, self).__init__()
print '+++ END GfxObject initialisation'
self._update_rect()
...but something wrong seems to be happening under the hood. If I add print 'child class "_update_rect" called' to the _update_rect method, I get this output when running the script:
--- START GfxObject initialisation
child class "_update_rect" called <-- ERROR!?
child class "_update_rect" called <-- ERROR!?
+++ END GfxObject initialisation
child class "_update_rect" called <-- this is correct
...
Which means the parent class is calling the child methods when being initialised!?
UPDATE 2: It seems this is the workflow when initialising the child class.
[1] Child.__init__()
[2] Parent.__init__()
[3] self.i_x = 0
[4] Child._set_x(0)
[5] Child._update_rect()
[6] Child._s_grab = 'foo'
The problem appears in step [6] because ._s_grab attribute hasn't been created yet since the initialisation of the Child class is still initialising the Parent class. To me, it's counter-intuitive (and I would say that it's even a bug) the step [3]-[4] when setting the attribute .i_x of the Parent class triggers the property of the Child class.
By moving the initialisation of the parent class at the end of the child class or adding the missing attribute as a Parent class global (not to the instances), the problem disappear.
Your issue is that you're trying to initialise non-existing class properties/variables (you're calling self.i_x, but you've initialised self._i_x, for example) with a method call.
Changing GfxObject to:
class GfxObject(object):
"""
Generic Graphical Object which is the parent class of all the sub-classes below.
"""
def __init__(self):
self._i_x = 0
self._i_y = 0
self._s_grab = 'nw'
Executed script on my machine. Result output:
$ python2 issue.py
--- START GfxObject initialisation
+++ END GfxObject initialisation
<GfxRect>
.i_x: 0
._i_x: 0
.s_grab: nw
._s_grab: nw
EDIT
Funny thing, once I moved i_x and s_grab from GfxObject()'s init, your code worked as a charm. Basically I only changed that class to this:
class GfxObject(object):
"""
Generic Graphical Object which is the parent class of all the sub-classes below.
"""
i_x = None
s_grab = None
def __init__(self):
# self.i_x = None
# self.s_grab = None
#self.s_grab = 'nw'
pass
So, it seems that you're expperiencing same issue I had with Python3 and #property decorator - if I didn't set an object to None or some other value before defining it as a property, it threw no attribute/not defined errors first time I'd try to use that getter/setter.
I am struggling to make this simple code work. I've just started to learn OOP. I looked at other examples but none could point in the right direction. The error is
TypeError: SetStrength() missing 1 required positional argument: 'strength'
import random
class Character:
"""A game character that has strength and skill"""
#constructor
def __init__(self):
#set the attributes with an initial value
self._name = ''
self._strength = 0
self._skill = 0
def SetName(self, name):
self._name = name
def SetStrength(self, strength):
self._strength = calculateAttribute()
def SetSkill(self, skill):
self._skill = calculateAttribute()
def GetName(self):
return self._name
def GetStrength(self):
return self._strength
def GetSkill(self):
return self._skill
def report(self):
return{'name':self._name,'strength': self._strength, 'skill':self._skill}
def calculateAttribute():
return (random.randrange(1,13)//random.randrange(1, 5)) + 10
def main():
player1 = Character()
player1.SetName('James')
player1.SetStrength()
player1.SetSkill()
print(player1.report())
if __name__ == "__main__":
main()
That method is defined as def SetStrength(self, strength):. That means that, in addition to the self which is passed automatically, you need to provide an additional argument - in this case, the new strength value you'd like to set. It works very similarly to setName, which you call with an argument on the previous line.
That said, the code you're working with is Java/C++/etc. code translated into Python, which balloons the size of the code for no good reason.
You should remove the expected argument "strength" of your function "SetStrength". Same for "skill" and "SetSkill".
Try this:
def SetStrength(self):
self._strength = calculateAttribute()
def SetSkill(self):
self._skill = calculateAttribute()
for some reason when I try to add an object to a dictionary in a class, where the dictionary belongs to another class and objects are added/removed by class functions it always seems to fail adding.
Heres the datahandler :
class datastore():
def __init__(self, dict=None):
self.objectStore = {}
self.stringStore = {}
if dict is not None:
self.objectStore = dict
def __addobj__(self,obj,name):
print("adddedval")
self.objectStore[name] = obj
def __getobject__(self,name):
_data = self.objectStore.get(name)
return _data
def __ripobj__(self,name,append):
if isinstance(append, object):
self.objectStore[name] = append
def __returnstore__(self):
return self.objectStore
def __lst__(self):
return self.objectStore.items()
and heres the trigger code to try to add the item :
if self.cmd=="addtkinstance-dev":
print("Adding a tk.Tk() instance to dataStore")
#$$ below broken $$#
_get = datastore.__dict__["__returnstore__"](self.dat)
_get["test-obj"] = tk.Tk()
datastore.__init__(self.dat, dict=_get)
#--------------------------------------------#
tool(tk.Tk(), "test-obj", datastore())
and also heres the init for the class that trys to add the object
class cmdproc(tk.Tk, datastore):
def __init__(self,lst,variable_mem,restable):
self.pinst = stutils(lst,restable,variable_mem)
self.vinst = varutils(variable_mem,lst,restable)
self.tki = tkhandler()
self.dat = datastore(dict=None)
datastore.__init__(self, dict=datastore.__returnstore__(self.dat))
tk.Tk.__init__(self)
self.lst = lst
self.vdat = variable_mem
self.restable = restable
please help this is seriously baffling me
(note that tkhandler dosn't have to do with anything)