Python programming - Output issue in "Create a class function" - python

I'm from NON computer science background (Biochemist). In Python programming under "Create a class function", I didn't get the output for the following written function:
class circle (object):
def __init__(self, 10, 'red'):
self.radius=10;
self.color='red'
I got syntax error like this:
File "<ipython-input-1-ab699251caa9>", line 2
def_init_(self,10,'red'):
^
SyntaxError: invalid syntax

you cant pass pure value you need to pass it with variables
class circle (object):
def __init__(self,number=10,color='red'):
self.radius=number
self.color=color

Function parameters must be variables, not numbers or strings. Change this:
class circle (object):
def __init__(self, 10, 'red'):
self.radius = 10
self.color = 'red'
to this:
class circle (object):
def __init__(self, radius, color):
self.radius = radius
self.color = color
This class can be instantiated with:
myCircleObject = circle(10, 'red')
or, if you want to make the association parameter-value more clear, you can instantiate with:
myCircleObject = circle(radius = 10, color = 'red')
You can also set default values for the parameters:
class circle (object):
def __init__(self, radius = 10, color = 'red'):
self.radius = radius
self.color = color
In this way, you can still instantiate the object as before but you can also init with:
myCircleObject = circle()
In this case, radius and color will have the default values specified in the signature (radius will be 10 and the color will be 'red').
Note that to avoid misinterpretations, parameters with default values can only be listed in the rightmost part. So if you want to specify a default value only for the parameter radius, you need to move it to the right:
class circle (object):
def __init__(self, color, radius = 10):
self.radius = radius
self.color = color

Related

Overwriting a passed on function from a parent class

Hey my task is to create a parentclass Shape and pass the functions on to the different shapes. Since a Circlearea calculation takes different parameters I am trying to overwrite the function. It throws following warning: "Signature of method 'Circel.get_area()' does not match Signature in the base method in Shape". Is that possible at all? How would I have to do it? Should it work anyway later on?
class Shape(ABC):
#abstractmethod
def get_area(self, x_l, y_l):
pass
def move(self, newx, newy):
pass
class Circle(Shape):
def __init__(self, rad, x_pos, y_pos):
self.rad = rad
self.pos = (x_pos, y_pos)
self.area = self.get_area(self, self.rad)
def get_area(self, rad):
return(self.rad*self.rad*2*m.pi)

Passing object attributes to its methods (Python)

It is apparently impossible to pass attributes of an object to its own methods:
def drawBox(color):
print("A new box of color ", color)
return
class Box:
def __init__(self, color):
self.defaultColor = color
self.color = color
def update(self, color = self.defaultColor):
self.color = color
drawBox(color)
This does not work:
Traceback (most recent call last):
File "<string>", line 5, in <module>
File "<string>", line 9, in Box
NameError: name 'self' is not defined
I found a way to bypass this issue like this:
def drawBox(color):
print("A new box of color ", color)
return
class Box:
def __init__(self, color):
self.defaultColor = color
self.color = color
def update(self, color = None):
if color == None:
self.color = self.defaultColor
else:
self.color = color
drawBox(color)
Is there a better (more elegant?) way to do this?
The reason you can't use self.color as a default parameter value is that the default is evaluated at the time the method is defined (not at the time that it's called), and at the time the method is defined, there is no self object yet.
Assuming that a valid color is always a truthy value, I would write this as:
class Box:
def __init__(self, color):
self.default_color = self.color = color
def draw(self):
print(f"A new box of color {self.color}")
def update(self, color=None):
self.color = color or self.default_color
self.draw()

python3 class __init__ inheritance without defining parameters again

Is it possible to inherit a class and use its init function without declaring all parameters again in the child class?
I have a class with lots of parameters, but I don't want to use a list (**args). I wouldn't see my actual parameters:
class Table(object):
def __init_(self, name, height ...):
self.name = name
self.height = height
class RoundTable(Table):
def __init__(self, radius):
self.radius = radius
table = RoundTable(name = "Placeholder",
height = 10,
radius = 20)
Use the super class before assigning specfic args
def __init__(self,radius,*args,**kwargs):
super().__init__(*args,**kwargs)
self.radius = radius
Edit : I'm assuming you mean class and not a function

Subclassing in python of instantiated superclass

Is it possible to subclass in Python using an already instantiated superclass?
I don't exactly know how to frame the question so let me give an example. Suppose I have a class Rectangle and I want to build another class ColoredRectangle. But I don't want each ColoredRectangle of the same dimensions to be its own new Rectangle. So when I initiate ColoredRectangle I would pass it an already instantiated Rectangle.
Ie., I want
r = Rectangle([1,2])
r_red = ColoredRectangle(r, "red")
r_blue = ColoredRectangle(r, "blue")
But now r_red and r_blue should be able to get all rectangle methods and attributes. For example suppose Rectangle had an area() attribute.
r.area
2
r_red.area
2
r_red and r_blue should "point" to the same Rectangle. I know I could do this by writing:
class ColoredRectangle(Rectangle):
def __init__(self, rectangle, color):
self.color = color
self.rectangle = rectangle
But then I'd have to write
r_red.rectangle.area
which is ugly.
Inheritance
Inheritance is such a nice thing in python, and I don't think you have to resort to getattr hacks, if you want those, scroll down.
You can force the class dictionary to refer to another object:
class Rectangle(object):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
class ColoredRectangle(Rectangle):
def __init__(self, rect, color):
self.__dict__ = rect.__dict__
self.color = color
rect = Rectangle(3, 5)
crect = ColoredRectangle(rect, color="blue")
print crect.width, crect.height, crect.color
#3 5 blue
These two will refer to the same Rectangle object:
crect.width=10
print rect.width, rect.height
#10 5
This is an exellent talk on metaprogramming, and while it's title implies Python3 a lot of it also applies to python 2.x: David Beazley - Python3 Metaprogramming
getattr hacking
If for any reason however, you would want to have multiple ColoredRectangle refer to the same base Rectangle then these will conflict with each other:
eve = Rectangle(3, 5)
kain = ColoredRectangle(eve, color="blue")
abel = ColoredRectangle(eve, color="red")
print eve.color, kain.color, abel.color
#red red red
If you'd like different "proxy objects", which can get attributes from the base Rectangle but not interfere with each other, you have to resort to getattr hacking, which is fun too:
class ColoredRectangle(Rectangle):
def __init__(self, rect, color):
self.rect = rect
self.color = color
def __getattr__(self,attr):
return getattr(self.rect,attr)
eve = Rectangle(3, 5)
This will avoid the interference:
kain = ColoredRectangle(eve, color="blue")
abel = ColoredRectangle(eve, color="red")
print kain.color, abel.color
#blue red
About __getattr__ versus __getattribute__:
A key difference between getattr and getattribute is that
getattr is only invoked if the attribute wasn't found the usual ways. It's good for implementing a fallback for missing attributes,
and is probably the one of two you want. source
Because only non found attributes will be handled by __getattr__ you can also partially update your proxies, which might be confusing:
kain.width=10
print eve.area(), kain.area(), abel.area()
# 15 50 15
To avoid this you can override __setattr__:
def __setattr__(self, attr, value):
if attr == "color":
return super(ColoredRectangle,self).setattr(attr,value)
raise YourFavoriteException
What you seem to be asking to do is to redirect attribute accesses to the underlying Rectangle object. The __getattr__ method can do this for you.
class ColoredRectangle(object):
def __init__(self, rectangle, color):
self.color = color
self.rectangle = rectangle
def __getattr__(self,attr):
return getattr(self.rectangle,attr)
Owerwrite all attributes by rectangle attributes. They are in __dict__ property.
import copy
class Rectangle(object):
def __init__(self, area):
self.area = area
class ColoredRectangle(Rectangle):
def __init__(self, rectangle, color):
self.__dict__ = copy.deepcopy(rectangle.__dict__)
self.color = color

Class Inheritance, redefining __init__ on with taking a new argument

I'm new to Python, I still have issues with the semantics of class inheritance.
The following is the relevant class from the module games.py module that I am importing:
class Text(Sprite):
"""
Alphanumeric values displayed on the screen.
"""
def __init__(self, value, size, color, angle=0,
x=0, y=0,
top=None, bottom=None, left=None, right=None,
dx=0, dy=0,
interval=1, is_collideable=True):
self._size = size
self._color = color
self._value = value
self._font = pygame.font.Font(None, self._size)
Sprite.__init__(self, self._create_surface(), angle,
x, y,
top, bottom, left, right,
dx, dy,
interval, is_collideable)
and the following is from where I'm trying to call it in my own program:
self.scorebox = games.Text (value = self.scorevar,
pygame.font.Font(ardarlingopentype, 50),
color = color.white,
x = 550,
y = 50)
As you can see the syntax is wrong, but how do I go about fixing this such that I can inherit the class Text from my own program and make FONT an accessible argument that I can change?
Thanks.
Your problem is, that you you are ordering the arguments incorrectly: there are positional and keyword arguments. All keywords arguments must succeed the positional arguments.
This would work:
self.scorebox = games.Text (
pygame.font.Font(ardarlingopentype, 50),
value = self.scorevar,
color = color.white,
x = 550,
y = 50
)
Not sure(note that you can't used not named arguments after named and/or mix them - you have used not named argument after 'value') but seems that you need to modify code the following way:
class Text(Sprite):
"""
Alphanumeric values displayed on the screen.
"""
def __init__(self, value, size, color, angle=0,
x=0, y=0,
top=None, bottom=None, left=None, right=None, font=None,
dx=0, dy=0,
interval=1, is_collideable=True):
self._size = size
self._color = color
self._value = value
if font:
self.font_ = font
else:
self._font = pygame.font.Font(None, self._size)
Sprite.__init__(self, self._create_surface(), angle,
x, y,
top, bottom, left, right,
dx, dy,
interval, is_collideable)
And then:
import pygame
import games
self.scorebox = games.Text (value = self.scorevar,
size = 50,
color = color.white,
x = 550,
y = 50)
OR:
import pygame
import games
self.scorebox = games.Text (value = self.scorevar,
size = 50,
font = pygame.font.Font(ardarlingopentype, 50),
color = color.white,
x = 550,
y = 50)
So guys I wrote to the developers of the Livewires package; and I was fortunate enough to receive a reply from one of them.
First, make a backup copy of games.py and put it somewhere safe. That
way if you do make a mistake, you can always recover the original
code.
Now our games.py is written on top of the PyGame library, which does
provide a way of setting the font. As you might have guessed, it's to
do with that line reading:
> self._font = pygame.font.Font(None, self._size)
The documentation is available online at
http://www.pygame.org/docs/ref/font.html#pygame.font.Font but I'll
just quickly summarise here. pygame.font.Font() creates a new PyGame
font object, which PyGame uses to tell it how to draw text. The
"None" parameter tells it to use the default font, but you can replace
that with the full name of a font file instead. The easiest way to do
that is to modify the Text classes initialiser to pass it as an
optional parameter.
class Text(Sprite):
def __init__(self, value, size, color, angle=0,
> x=0, y=0,
> top=None, bottom=None, left=None, right=None,
> dx=0, dy=0,
> interval=1, is_collideable=True,
> fontfile=None):
> self._size = size
> self._color = color
> self._value = value
> self._font = pygame.font.Font(fontfile, self._size)
> Sprite.__init__(self, self._create_surface(), angle,
> x, y,
> top, bottom, left, right,
> dx, dy,
> interval, is_collideable)
You would then create your Text object by calling 'Text(blah blah
blah, fontfile="/some/font/file/name.ttf")' or whatever the filename
is. Any other Text objects that don't specify a "fontfile" will
automatically use "None" instead, which will give them the default
font exactly as before.
So what's the fully-qualified pathname of the font file for
"TimesNewRoman"? I have no idea what it would be on your computer.
Fortunately PyGame provides a way of not having to know:
pygame.font.match_font(). You can use that in your own program
(rather than modifying games.py any more), but you will have to either
"import pygame.font" for yourself or call it
"games.pygame.font.match_font()" -- either should work equally well.

Categories