class Rectangle: """ The keyword class is used to define a class. The name of the class is Rectange. """ def __init__(self, length, width, color='black'): """ Initializes a Rectangle object with a given length, width and color """ self.length = length self.width = width self.color = color """ The special method __init__ is known as the constructor of a class. When the statement "rect_1 = Rectange(length=15, width=4, color='red') is called, the __init__ will be invoked. All methods in a class has one extra parameter. The first paramenter is the object itself, which usually uses the name 'self'. For example, consider when rect_1.getColor() is called. There is no argument. However, there is one parameter, self, whicch is referencing rect_1. """ def area(self): """ Calculates and returns the area of the rectangle. """ return self.length * self.width def perimeter(self): """ Calculates and returns the perimeter of the rectangle. """ return 2 * (self.length + self.width) def get_color(self): return self.color def __str__(self): return f"Rectangle(length: {self.length}, width: {self.width}, color: {self.color})" """ __str__ is another standard method, which is invoked when an rectangle object must be converted to a string. For example, for the statement print(f"rect_2: {rect_2}") is executed, __str__ will be invoked in {rect_2} """ if __name__ == "__main__": # Example usage: # Create a Rectangle object rect_1 = Rectangle(length=15, width=4, color='red') # Access attributes print(f"rect_1's length: {rect_1.length}") print(f"rect_1's width: {rect_1.width}") print(f"rect_1's color: {rect_1.color}") # Call methods print(f"rect_1's area: {rect_1.area()}") print(f"rect_1's perimeter: {rect_1.perimeter()}") print(f"rect_1's color: {rect_1.get_color()}") # When a rectange needs to be converted to a string, __str__ is invoked. print(f"rect_1: {rect_1}") rect_2 = Rectangle(length=8, width=4) print(f"rect_2: {rect_2}") print(f"rect_2's area: {rect_2.area()}") print(f"rect_2's color: {rect_2.get_color()}")