#!/usr/bin/env python3 class GardenError(Exception): def __init__(self, message="Unknown plant error"): self.message = message # Why self.message; why not just 'message' super().__init__(self.message) class PlantError(GardenError): pass class WaterError(GardenError): pass def water_plant(plant): if plant == plant.capitalize(): print(f"Watering {plant}: [OK]") else: raise PlantError(f"Invalid plant name to water: '{plant}'") def test_watering_system(plants): print("Open watering system") try: for plant in plants: water_plant(plant) except PlantError as err: print("Caught PlantError:", err) print("...ending tests and returning to main") finally: print("Closing watering system") if __name__ == "__main__": print("=== Garden Watering System ===") print() print("Testing valid plants...") test_watering_system(["Tomato", "Lettuce", "Carrots"]) print() print("Testing invalid plants...") test_watering_system(["Tomato", "lettuce", "Carrots"]) print() print("Cleanup always happens, even with errors!")