Implementing Property Setters in Python
This challenge focuses on creating custom property setters in Python using the @property decorator. Property setters allow you to control how attributes are assigned to an object, enabling validation, side effects, or other logic during the assignment process. This is a fundamental concept for building robust and maintainable object-oriented code.
Problem Description
You are tasked with creating a Rectangle class that has a width and height attribute. You need to implement property setters for both width and height that enforce the following constraints:
- Both
widthandheightmust be positive numbers (greater than 0). - If a non-positive value is provided, raise a
ValueErrorwith a descriptive message. - The setters should store the validated values internally.
The class should also have a get_area method that calculates and returns the area of the rectangle (width * height).
Key Requirements:
- Use the
@propertydecorator to define thewidthandheightattributes as properties. - Implement setter methods for
widthandheightthat perform validation. - Raise a
ValueErrorif validation fails. - The
get_areamethod should correctly calculate the area using the validatedwidthandheight.
Expected Behavior:
When a new Rectangle object is created, setting width or height should trigger the setter methods. If the provided value is valid, it should be stored. If the value is invalid, a ValueError should be raised. The get_area method should return the correct area based on the stored width and height.
Edge Cases to Consider:
- Setting
widthorheightto 0. - Setting
widthorheightto negative numbers. - Setting
widthorheightto non-numeric values (e.g., strings). While the problem doesn't explicitly require handling non-numeric types, consider how your solution would behave.
Examples
Example 1:
Input:
rect = Rectangle(5, 10)
rect.width = -2
Output:
ValueError: Width must be a positive number.
Explanation: Attempting to set the width to a negative value raises a ValueError as expected.
Example 2:
Input:
rect = Rectangle(5, 10)
rect.height = 8
print(rect.width)
print(rect.height)
print(rect.get_area())
Output:
5
8
40
Explanation: Setting the height to a valid value (8) updates the height attribute, and the area is correctly calculated as 40.
Example 3:
Input:
rect = Rectangle(5, 10)
try:
rect.width = 0
except ValueError as e:
print(e)
Output:
Width must be a positive number.
Explanation: Setting the width to 0 raises a ValueError because 0 is not a positive number.
Constraints
- The
widthandheightattributes must be numeric (int or float). - The
widthandheightmust be greater than 0. - The
Rectangleclass must be defined. - The code must be valid Python 3.
- The solution should be concise and readable.
Notes
- The
@propertydecorator is key to creating properties. - Remember to define both the getter and setter methods for each property.
- Use
raise ValueError("Descriptive message")to signal invalid input. - Consider using type checking (although not strictly required) to improve robustness.