--- /dev/null
+__pycache__/
+*.pdf
+*.txt
+.gemini/
--- /dev/null
+def check_temperature(temp_str: str) -> int | None:
+ """
+ Checks if the temperature is valid for plants (0-40).
+ Returns the temperature if valid, None otherwise.
+ """
+ try:
+ temp = int(temp_str)
+ if temp < 0:
+ print(f"Error: {temp}°C is too cold for plants (min 0°C)")
+ return None
+ elif temp > 40:
+ print(f"Error: {temp}°C is too hot for plants (max 40°C)")
+ return None
+ else:
+ return temp
+ except ValueError:
+ print(f"Error: '{temp_str}' is not a valid number")
+ return None
+
+
+def test_temperature_input() -> None:
+ """
+ Demonstrates testing with various inputs.
+ """
+ print("=== Garden Temperature Checker ===")
+
+ inputs = ["25", "abc", "100", "-50"]
+
+ for inp in inputs:
+ print(f"Testing temperature: {inp}")
+ result = check_temperature(inp)
+ if result is not None:
+ print(f"Temperature {result}°C is perfect for plants!")
+
+ print("All tests completed - program didn't crash!")
+
+
+if __name__ == "__main__":
+ test_temperature_input()
--- /dev/null
+def garden_operations() -> None:
+ """
+ Demonstrates handling of different exception types in garden operations.
+ """
+ print("=== Garden Error Types Demo ===")
+
+ # ValueError
+ print("Testing ValueError...")
+ try:
+ int("abc")
+ except ValueError as e:
+ print(f"Caught ValueError: {e}")
+
+ # ZeroDivisionError
+ print("Testing ZeroDivisionError...")
+ try:
+ 10 / 0
+ except ZeroDivisionError as e:
+ print(f"Caught ZeroDivisionError: {e}")
+
+ # FileNotFoundError
+ print("Testing FileNotFoundError...")
+ try:
+ open("missing.txt", "r")
+ except FileNotFoundError:
+ print("Caught FileNotFoundError: No such file 'missing.txt'")
+
+ # KeyError
+ print("Testing KeyError...")
+ try:
+ d = {}
+ _ = d["missing_plant"]
+ except KeyError as e:
+ print(f"Caught KeyError: {e}")
+
+ # Multiple errors
+ print("Testing multiple errors together...")
+ try:
+ int("abc")
+ except (ValueError, ZeroDivisionError):
+ print("Caught an error, but program continues!")
+
+
+def test_error_types() -> None:
+ """
+ Runs the garden operations demonstration.
+ """
+ garden_operations()
+ print("All error types tested successfully!")
+
+
+if __name__ == "__main__":
+ test_error_types()
--- /dev/null
+class GardenError(Exception):
+ """Base class for garden-related errors."""
+
+ pass
+
+
+class PlantError(GardenError):
+ """Error related to plants."""
+
+ pass
+
+
+class WaterError(GardenError):
+ """Error related to watering."""
+
+ pass
+
+
+def test_custom_errors() -> None:
+ """
+ Demonstrates raising and catching custom exceptions.
+ """
+ print("=== Custom Garden Errors Demo ===")
+
+ print("Testing PlantError...")
+ try:
+ raise PlantError("The tomato plant is wilting!")
+ except PlantError as e:
+ print(f"Caught PlantError: {e}")
+
+ print("Testing WaterError...")
+ try:
+ raise WaterError("Not enough water in the tank!")
+ except WaterError as e:
+ print(f"Caught WaterError: {e}")
+
+ print("Testing catching all garden errors...")
+ try:
+ raise PlantError("The tomato plant is wilting!")
+ except GardenError as e:
+ print(f"Caught a garden error: {e}")
+
+ try:
+ raise WaterError("Not enough water in the tank!")
+ except GardenError as e:
+ print(f"Caught a garden error: {e}")
+
+ print("All custom error types work correctly!")
+
+
+if __name__ == "__main__":
+ test_custom_errors()
--- /dev/null
+def water_plants(plant_list: list) -> None:
+ """
+ Waters plants in the list, ensuring cleanup happens.
+ """
+ try:
+ print("Opening watering system")
+ for plant in plant_list:
+ if not isinstance(plant, str):
+ raise TypeError(f"Cannot water {plant} - invalid plant!")
+ print(f"Watering {plant}")
+ except TypeError as e:
+ print(f"Error: {e}")
+ finally:
+ print("Closing watering system (cleanup)")
+
+
+def test_watering_system() -> None:
+ """
+ Tests the watering system with valid and invalid lists.
+ """
+ print("=== Garden Watering System ===")
+
+ print("Testing normal watering...")
+ water_plants(["tomato", "lettuce", "carrots"])
+ print("Watering completed successfully!")
+
+ print("Testing with error...")
+ water_plants(["tomato", None, "carrots"])
+ print("Cleanup always happens, even with errors!")
+
+
+if __name__ == "__main__":
+ test_watering_system()
--- /dev/null
+def check_plant_health(
+ plant_name: str, water_level: int, sunlight_hours: int
+) -> str:
+ """
+ Checks if plant parameters are within valid ranges.
+ Raises ValueError if not.
+ """
+ if not plant_name:
+ raise ValueError("Plant name cannot be empty!")
+
+ if water_level < 1 or water_level > 10:
+ if water_level > 10:
+ raise ValueError(f"Water level {water_level} is too high (max 10)")
+ else:
+ raise ValueError(f"Water level {water_level} is too low (min 1)")
+
+ if sunlight_hours < 2 or sunlight_hours > 12:
+ if sunlight_hours < 2:
+ raise ValueError(
+ f"Sunlight hours {sunlight_hours} is too low (min 2)"
+ )
+ else:
+ raise ValueError(
+ f"Sunlight hours {sunlight_hours} is too high (max 12)"
+ )
+
+ return f"Plant '{plant_name}' is healthy!"
+
+
+def test_plant_checks() -> None:
+ """
+ Tests plant health check with various invalid inputs.
+ """
+ print("=== Garden Plant Health Checker ===")
+
+ print("Testing good values...")
+ try:
+ print(check_plant_health("tomato", 5, 8))
+ except ValueError as e:
+ print(f"Error: {e}")
+
+ print("Testing empty plant name...")
+ try:
+ check_plant_health("", 5, 8)
+ except ValueError as e:
+ print(f"Error: {e}")
+
+ print("Testing bad water level...")
+ try:
+ check_plant_health("lettuce", 15, 8)
+ except ValueError as e:
+ print(f"Error: {e}")
+
+ print("Testing bad sunlight hours...")
+ try:
+ check_plant_health("carrot", 5, 0)
+ except ValueError as e:
+ print(f"Error: {e}")
+
+ print("All error raising tests completed!")
+
+
+if __name__ == "__main__":
+ test_plant_checks()
--- /dev/null
+class GardenError(Exception):
+ """Base class for garden-related errors."""
+
+ pass
+
+
+class PlantError(GardenError):
+ """Error related to plants."""
+
+ pass
+
+
+class WaterError(GardenError):
+ """Error related to watering."""
+
+ pass
+
+
+class GardenManager:
+ """
+ Manages a garden with resilient error handling.
+ """
+
+ def __init__(self):
+ self.plants = []
+
+ def add_plant(self, name: str) -> None:
+ """
+ Adds a plant to the garden.
+ Raises PlantError if name is invalid.
+ """
+ if not name:
+ raise PlantError("Plant name cannot be empty!")
+ self.plants.append(name)
+ print(f"Added {name} successfully")
+
+ def water_plants(self) -> None:
+ """
+ Waters all plants in the garden.
+ Uses finally block for cleanup.
+ """
+ print("Opening watering system")
+ try:
+ for plant in self.plants:
+ print(f"Watering {plant} - success")
+ except Exception as e:
+ print(f"Error watering: {e}")
+ finally:
+ print("Closing watering system (cleanup)")
+
+ def check_plant_health(
+ self, name: str, water_level: int, sun_hours: int
+ ) -> None:
+ """
+ Checks health of a plant.
+ Raises GardenError (or subclasses) if conditions are bad.
+ """
+ try:
+ if name not in self.plants:
+ raise PlantError(f"Plant {name} not in garden")
+
+ if water_level < 0 or water_level > 10:
+ if water_level > 10:
+ raise WaterError(
+ f"Water level {water_level} is too high (max 10)"
+ )
+ else:
+ raise WaterError(
+ f"Water level {water_level} is too low (min 0)"
+ )
+
+ if sun_hours < 0:
+ raise GardenError("Sunlight cannot be negative")
+
+ print(f"{name}: healthy (water: {water_level}, sun: {sun_hours})")
+
+ except GardenError as e:
+ print(f"Error checking {name}: {e}")
+
+
+def test_garden_management() -> None:
+ """
+ Demonstrates the full garden management system.
+ """
+ print("=== Garden Management System ===")
+ manager = GardenManager()
+
+ print("Adding plants to garden...")
+ try:
+ manager.add_plant("tomato")
+ manager.add_plant("lettuce")
+ manager.add_plant("")
+ except PlantError as e:
+ print(f"Error adding plant: {e}")
+
+ print("Watering plants...")
+ manager.water_plants()
+
+ print("Checking plant health...")
+ manager.check_plant_health("tomato", 5, 8)
+ manager.check_plant_health("lettuce", 15, 8)
+
+ print("Testing error recovery...")
+ try:
+ # Simulate a critical error condition we want to catch explicitly
+ raise GardenError("Not enough water in tank")
+ except GardenError as e:
+ print(f"Caught GardenError: {e}")
+ print("System recovered and continuing...")
+
+ print("Garden management system test complete!")
+
+
+if __name__ == "__main__":
+ test_garden_management()