Adding a attribute to an instance - python-3.x

I have the below code...
import math
class Circle:
"""Class to create Circle objects"""
def __init__(self, radius=1):
"""Circle initializer"""
self.radius = radius
#property
def area(self):
"""Calculate and return the area of the Circle"""
return math.pi * self.radius ** 2
#property
def diameter(self):
"""Calculate and return the diameter of the Circle"""
return self.radius * 2
#diameter.setter
def diameter(self, diameter):
"""Set the diameter"""
self.radius = diameter / 2
def __str__(self):
return 'Circle of radius {}'.format(self.radius)
def __repr__(self):
return "Circle(radius={})".format(self.radius)
I want to add an attribute radius_log to the instance. It is a list which would contain radius values which have belonged to the circle as well as the current radius value as the last item in the list. The other properties must still work. I know I have to make the radius a property and add a setter property for the radius. Below is an example output...
circle = Circle()
circle
Circle(radius=1)
circle.radius_log
[1]
circle.radius = 2
circle.diameter = 3
circle
Circle(radius=1.5)
circle.radius_log
[1, 2, 1.5]
circle2 = Circle(radius=2)
circle2.radius_log
[2]
Any ideas on how to do this?

Change radius to property and add new property radius_log.
Inside radius property setter you will add value to _property_log list in every change. This log will be exposed through radius_log property:
import math
class Circle:
"""Class to create Circle objects"""
def __init__(self, radius=1):
"""Circle initializer"""
self.radius = radius
#property
def radius(self):
return self._radius
#radius.setter
def radius(self, value):
self._radius = getattr(self, '_radius', None)
if self._radius == value:
return
self._radius_log = getattr(self, '_radius_log', [])
self._radius_log.append(value)
self._radius = value
#property
def radius_log(self):
return self._radius_log[:]
#property
def area(self):
"""Calculate and return the area of the Circle"""
return math.pi * self.radius ** 2
#property
def diameter(self):
"""Calculate and return the diameter of the Circle"""
return self.radius * 2
#diameter.setter
def diameter(self, diameter):
"""Set the diameter"""
self.radius = diameter / 2
def __str__(self):
return 'Circle of radius {}'.format(self.radius)
def __repr__(self):
return "Circle(radius={})".format(self.radius)
circle = Circle()
print(circle)
print(circle.radius_log)
circle.radius = 2
circle.diameter = 3
print(circle)
print(circle.radius_log)
circle2 = Circle(radius=2)
print(circle2.radius_log)
This prints:
Circle of radius 1
[1]
Circle of radius 1.5
[1, 2, 1.5]
[2]

Related

Factory design pattern using __init_subclass__ python3

I didn't find any info about the implementation of the factory design pattern using __init_subclass__ to register the product and the class. What do you think about?
https://peps.python.org/pep-0487/
class Shape:
product = None
shapes_classes = {}
def __init_subclass__(cls, **kwargs):
cls.shapes_classes[cls.product] = cls
#classmethod
def create_shape(cls, product, *args, **kwargs):
return cls.shapes_classes[product](*args, **kwargs)
def __str__(self):
return f'I am {self.__class__.__name__} shape'
def area(self):
raise NotImplemented
class Triangle(Shape):
product = 'triangle'
def __init__(self, base, height):
self.base = base
self.height = height
def area(self):
return self.height * self.base / 2
class Square(Shape):
product = 'square'
def __init__(self, base, ):
self.base = base
def area(self):
return self.base ** 2
#Usage:
Shape.shapes_classes
{'triangle': __main__.Triangle, 'square': __main__.Square}
triangle = Shape.create_shape(product='triangle',base=3,height=4)
square=Shape.create_shape(product='square',base=3)
print(triangle)
I am Triangle shape
print(square)
I am Square shape
triangle.area()
6.0
square.area()
9

TypeError : Circle() takes no arguments

I'm getting the error TypeError : Circle() takes no arguments when trying to run the code above. Does anyone know what I'm missing?
class Circle:
is_shape = True
radius,color=0,""
def __init__(self, color, radius):
self.color = color
self.radius = radius
def display(self):
print("radius:",self.radius)
print("color:",self.color)
first_circle = Circle("red",2)
first_circle.display()
Actually you have an indentation problem in your code. Your functions aren't defined under classes, that's why it shows your class Circle() takes no argument.
To correct this put your functions inside a class :
class Circle:
is_shape = True
radius, color = 0, ""
def __init__(self, color, radius):
self.color = color
self.radius = radius
def display(self):
print("radius:", self.radius)
print("color:", self.color)
first_circle = Circle("red", 2)
first_circle.display()

using the sum function to add points on a caretsian plane

The code is giving me an error. It's supposed to add points on a Cartesian plane.
class Cluster(object):
def __init__(self, x, y):
self.center = Point(x, y)
self.points = []
def update(self):
sum_ = sum(self.points, Point(0, 0))
len_ = float(len(self.points))
self.center = Point(sum_.x/len_, sum_.y/len_)
self.points = []
def add_point(self, point):
self.points.append(point)
sum_ = sum(self.points, Point(0, 0))
The sum() function only only works for types which support addition. A class can implement addition using the __add__ function. If this is indeed the problem you are facing, define in your Point class a function like:
class Point:
# ...
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)

Creating a default

I have a point class which has 2-d point instances. I also have a magnitude function inside which returns the magnitude of said points. Below is my code...
class Point:
# """2-D Point objects."""
def __init__(self, x, y):
# """Initialize the Point instance"""
self.x = x
self.y = y
def get_magnitude(self):
# """Return the magnitude of vector from (0,0) to self."""
return math.sqrt(self.x ** 2 + self.y ** 2)
def __str__(self):
return 'Point at ({}, {})'.format(self.x,self.y)
def __repr__(self):
return "Point(x={},y={})".format(self.x,self.y)
point = Point(x=3, y=4)
print(str(point))
print(repr(point))
print(point)
...After doing all of this, the final part of this is to implement a default point of (0,0). Any suggestions on how to do this? It should work like this...
point2 = Point()
print(point2)
Point(x=0, y=0)
point3 = Point(y=9)
print(point3)
Point(x=0, y=9)
You can pass in default arguments to an initializer, just like you would any other function.
def __init__(self, x=0, y=0):
# """Initialize the Point instance"""
self.x = x
self.y = y

How to change a normal method into a property method

I have the below code which is working.
class Point:
# """2-D Point objects."""
def __init__(self, x=0, y=0):
# """Initialize the Point instance"""
self.x = x
self.y = y
def get_magnitude(self):
# """Return the magnitude of vector from (0,0) to self."""
return math.sqrt(self.x ** 2 + self.y ** 2)
def __str__(self):
return 'Point at ({}, {})'.format(self.x,self.y)
def __repr__(self):
return "Point(x={},y={})".format(self.x,self.y)
point = Point(x=3, y=4)
print(str(point))
print(repr(point))
print(point)
point2 = Point()
print(point2)
point3 = Point(y=9)
print(point3)
I want to change the get_magnitude method into a property method named magnitude which works as shown below.
point = Point(3, 4)
point
Point(x=3, y=4)
point.magnitude
5.0
point3 = Point(y=9)
point3.magnitude
9.0
How would I do this?
import math
class Point:
"""2-D Point objects."""
def __init__(self, x=0, y=0):
"""Initialize the Point instance"""
self.x = x
self.y = y
#property
def magnitude(self):
"""Return the magnitude of vector from (0,0) to self."""
return math.sqrt(self.x ** 2 + self.y ** 2)
def __str__(self):
return 'Point at ({}, {})'.format(self.x,self.y)
def __repr__(self):
return "Point(x={},y={})".format(self.x,self.y)
point = Point(3, 4)
print(point)
print(point.magnitude)
point3 = Point(y=9)
print(point3.magnitude)
Prints:
Point at (3, 4)
5.0
9.0

Resources