0

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?

1 Answer 1

1

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]
Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to make this code work without init referencing self._radius? I want to have the two methods for getting and setting the radius be the only methods to read/modify this attribute.
@user10019227 Yes, it's possible. I updated my answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.