How to access the stored array in class - python

I want to access the array i have filled throughout the for loop,however what i get it is still empty array when call fill_particles().particles, is there any way to get rid of this problem? here is my code.
class particle(object):
def __init__(self,x,y,z):
self.x=x
self.y=y
self.z=z
class fill_particles():
def __init__(self):
self.particles=[]
def fill(self):
for i in range(5):
self.particles.append(particle(i,i+1,i+2))

You need to instantiate the class and call fill(). Here's a working example, along with extra functions for display purposes:
class Particle(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __repr__(self):
return f'Particle(x={self.x}, y={self.y}, z={self.z})'
class Particles:
def __init__(self):
self.particles = []
def fill(self):
for i in range(5):
self.particles.append(Particle(i, i + 1, i + 2))
def __repr__(self):
return f'Particles({self.particles!r})'
particles = Particles()
print(particles)
particles.fill()
print(particles)
Output:
Particles([])
Particles([Particle(x=0, y=1, z=2), Particle(x=1, y=2, z=3), Particle(x=2, y=3, z=4), Particle(x=3, y=4, z=5), Particle(x=4, y=5, z=6)])

Related

How to initialize one parent at a time in multiple inheritance?

Suppose I have the following class inheriting from classes A and B:
class A:
def __init__(self):
self.x = 2
class B:
def __init__(self,u):
self.y = u + 2
class C(A,B):
def __init__(self):
#self.y should be 4 here
How do I initialize B only after initializing A? Using super(C,self).__init__() doesn't let me use attributes of A into B.
You don't HAVE to use super.
class A:
def __init__(self):
self.x = 2
class B:
def __init__(self,u):
self.y = u + 2
class C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self, self.x)
Now, that does mean some pretty tight coupling, in that C has to be way too aware of what A.__init__ does.
Just do this:
class A:
def __init__(self):
print("A was initialized")
self.x = 2
def getX(self):
return self.x
class B:
def __init__(self, u):
print("B was initialized")
self.u = u +2
class C(A,B):
def __init__(self, **kw):
A.__init__(self)
B.__init__(self, self.getX())
Alternatively, with super:
class A:
def __init__(self):
self.x = 2
class B:
def __init__(self,u):
self.y = u + 2
class C(A,B):
def __init__(self):
super().__init__()
super(A, self).__init__(self.x)
If you want to pass attributes in between classes use something like a return statement. Then in your B class use whatever the A class returned.

reusing a variable defined in a python class

Let's say I define a class. I have a fun method, where I create self.x. I want to use self.x in a different method (reuse). How could I do that? Because I tried what I wrote and didn't work. Thanks!
class test:
def __init__(self,t):
self.t = t
def fun(self):
self.x = self.t+1
def reuse(self):
self.y = self.x
You need to create all the variables in the __init__ method.
Try this:
class test:
def __init__(self,t):
self.t = t
self.x = 0
self.y = 0
def fun(self):
self.x = self.t+1
def reuse(self):
self.y = self.x

How to apply class methods to my own class' property in Python

I created a class called Thing for Pygame, which will later be subclassed to develop more specific classes and objects. This class needs to store among other attributes, the position, and size of the object.
However, Pygame has this very powerful class called Rect that can already do that, and has many useful built-in methods and properties. I could use a single Rect attribute in my Thing class, but it stores position in integers, and I'm looking to store it in floats (a Thing might need to move less than one pixel per frame).
This I what I had in mind.
class Thing:
def __init__(self, pos, size):
self.x: float = pos[0]
self.y: float = pos[1]
self.size = size
#property
def rect(self):
return pygame.Rect((self.x, self.y), self.size)
#rect.setter
def rect(self, var: pygame.Rect):
self.x = var.x
self.y = var.y
self.size = var.size
This would allow me to get and set the Thing's Rect, but I wouldn't be able to use the Rect's built-in setters as desired:
foo = Thing((10, 10), (20, 20))
foo.draw(win)
foo.x += 100
foo.draw(win)
# This has no effect
foo.rect.y += 100
foo.draw(win)
temp = foo.rect
temp.x -= 100
foo.rect = temp
foo.draw(win)
The desired behavior for the above code would be to have the square move right, down, then left.
Is there a way to either:
Have a Rect as a Thing attribute, but update x and y whenever it's changed?
Apply methods to Rect property
Some other solution you can think of
TL;DR: If I have a Rect as a property, I can't do self.rect.center = (500,500)
Thanks in advance!
Your class should inherit from pygame.Rect. That is the only way to get the Rect methods automatically. However by doing this you will inherits also the int typecasting of the coordinates since that is in the original implementation of pygame.Rect. I'm afraid inheritance won't solve your problem.
You know what the Rect methods are supposed to do (The documentation is well written), so I'm afraid the only way is to reimplement them (or at least reimplement those you need) for your own Thing class, to mimic the Rect behaviour with float numbers.
I did something similar: here is a portion of the class I wrote (I won't show it all because is too long) to give you an idea:
class FlRect:
"""Similar to pygame.Rect but uses float numbers.
The class stores internally only coordinates, width and height.
Other attributes are rendered through properties, with getter and setter:
x, y: coordinates of the top-left corner of the rectangle.
top, bottom: y coordinates of the top and bottom edges respectively.
left, right: x coordinates of the left and right edges respectively.
centerx, centery: coordinates of the centre of the rectangle.
width, height: self-explanatory.
"""
def __init__(self, x, y, w, h):
"""Initialization:
x, y - coordinates of top-left corner of the rectangle
w, h - width and height
"""
self._x = x
self._y = y
self._w = w
self._h = h
#property
def x(self):
return self._x
#x.setter
def x(self, value):
self._x = value
#property
def y(self):
return self._y
#y.setter
def y(self, value):
self._y = value
#property
def width(self):
return self._w
#width.setter
def width(self, value):
self._w = value
#property
def height(self):
return self._h
#height.setter
def height(self, value):
self._h = value
#property
def top(self):
return self._y
#top.setter
def top(self, value):
self._y = value
#property
def bottom(self):
return self._y + self._h
#bottom.setter
def bottom(self, value):
self._y = value - self._h
#property
def left(self):
return self._x
#left.setter
def left(self, value):
self._x = value
#property
def right(self):
return self._x + self._w
#right.setter
def right(self, value):
self._x = value - self._w
#property
def centerx(self):
return self._x + (self._w / 2)
#centerx.setter
def centerx(self, value):
self._x = value - (self._w / 2)
#property
def centery(self):
return self._y + (self._h / 2)
#centery.setter
def centery(self, value):
self._h = value - (self._h / 2)
def get_rect(self):
"""Return a pygame.Rect object with rounded coordinates"""
return Rect(round(self._x), round(self._y), round(self._w), round(self._h))
Of course this is not going to be as efficient as pygame.Rect, since this is written in python and the pygame Rect class is in C.

How should I implement, and what should I call, a common base class for Area and Point?

So I want a Point and an Area classes similar to how C# has Point and Size. Here are simple implementations of the two classes:
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
# Many other magic methods too!
class Area:
def __init__(self, width=0, height=0):
self.width = width
self.height = height
def __add__(self, other):
return Area(self.width + other.width, self.height + other.height)
# Many other magic methods too!
As you can see, the two classes are exact duplicates, except one has x, y while the other has width, height.
What would be a good solution for implementing some kind of base class for these two?
If you don't mind using immutable objects, you could subclass tuple to craete a base class for all of the two dimensional stuff:
class _2dTuple(tuple):
def __new__(cls, hor=0, ver=0):
super().__new__(cls, (hor, ver))
def __add__(self, other):
return type(self)(self[0] + other[0], self[1] + other[1])
Now when you subclass your _2dTuple, you can just create property getters for your x, y and width, height:
class Point(_2dTuple):
#property
def x(self):
return self[0]
#property
def y(self):
return self[1]
class Area(_2dTuple):
#property
def width(self):
return self[0]
#property
def height(self):
return self[1]

Python 3x class methods

I'm currently learning the basics of classes, and I came up with some basic code as follows:
class shape(object):
def __init__(self, num_sides, type):
self.num_sides = num_sides
self.type = type
class square(shape):
def __init__(self, side_length):
self.num_sides = 4
self.type = 'regular quadrilateral'
self.side_length = side_length
def perim():
return side_length * 4
def area():
return side_length ** 2
class circle(shape):
def __init__(self, radius):
self.num_sides = 1
self.type = 'ellipsis'
self.radius = radius
Now, when I type the following:
shape1 = square(5)
shape1.perim()
I get the following output:
<bound method square.perim of <__main__.square object at 0x0000000003D5FB38>>
What is this? How can I get python to actually return the perimeter of the square?
Also, I have another question:
Do any class methods exist other than __init__() and __str__()? If so, can you please list them so I can go off and research them?
as shown, you are going to have some problems with this. If you are trying to have circle and square be subset set classes of shape, then the two sub classes need to be indented. Also, on class circle and square, you really do not need the (shape). also note the things I commented out as not needed.
This does not come out as I am posting it. the class shape (object):does not show up and the subclasses are not indented and I can not seem to make it show up
class shape(object):
def init(self, num_sides, type):
#self.num_sides = num_sides
self.type = type
class square:
def __init__(self, side_length):
#self.num_sides = 4
#self.type = 'regular quadrilateral'
self.side_length = side_length
def perim(self):
return self.side_length * 4
def area(self):
return self.side_length ** 2
class circle:
def __init__(self, radius):
#self.num_sides = 1
#self.type = 'ellipsis'
self.radius = radius
def area (self):
return 3.14 * self.radius ** 2
shape2 = circle (5)
print ('test of circle: ',shape2.area ())
shape1 = square(5)
print('test of square: ', shape1.perim())
Two things, indentation of the init of shape and add self. to the perim and area methods.
class shape(object):
def __init__(self, num_sides, type):
self.num_sides = num_sides
self.type = type
class square(shape):
def __init__(self, side_length):
self.num_sides = 4
self.type = 'regular quadrilateral'
self.side_length = side_length
def perim(self):
return self.side_length * 4
def area(self):
return self.side_length ** 2
class circle(shape):
def __init__(self, radius):
self.num_sides = 1
self.type = 'ellipsis'
self.radius = radius
shape1 = square(5)
print( shape1.perim())
Access instance variable with self
class square(shape):
def __init__(self, side_length):
self.num_sides = 4
self.type = 'regular quadrilateral'
self.side_length = side_length
def perim(self):
return self.side_length * 4
def area(self):
return self.side_length ** 2

Categories