+++ /dev/null
-**.pdf
\ No newline at end of file
+++ /dev/null
-def check_temperature(temp_str: str) -> None:
- try:
- temp = int(temp_str)
- if temp < 0:
- print(f"Error: {temp}°C is too cold for plants (min 0°C)")
- elif temp > 40:
- print(f"Error: {temp}°C is too hot for plants (max 40°C)")
- else:
- print(f"Temperature {temp}°C is perfect for plants!")
- except ValueError:
- print(f"Error: '{temp_str}' is not a valid number")
-
-
-def test_temperature_input() -> None:
- def test_check(s: str):
- print(f"Testing temperature: {s}")
- check_temperature(s)
- print()
-
- print("=== Garden Temperature Checker ===\n")
- test_check("25")
- test_check("abc")
- test_check("100")
- test_check("-50")
- print("All tests completed - program didn't crash!")
-
-
-if __name__ == "__main__":
- test_temperature_input()
+++ /dev/null
-def garden_operations(exception: str):
- if exception == "ValueError":
- int("abc")
- if exception == "ZeroDivisionError":
- print(10 / 0)
- if exception == "FileNotFoundError":
- open("/dev/agilliar")
- if exception == "KeyError":
- {}["agilliar"]
- print("[WARNING] No exception was raised")
-
-
-def test_error_types() -> None:
- print("=== Garden Error Types Demo ===")
- for error in [
- "ValueError",
- "ZeroDivisionError",
- "FileNotFoundError",
- "KeyError",
- ]:
- print(f"\nTesting {error}...")
- try:
- garden_operations(error)
- except (
- ValueError,
- ZeroDivisionError,
- FileNotFoundError,
- KeyError,
- ) as e:
- print(f"Caught {type(e).__name__}: {e}")
- print("\nAll error types tested successfully!")
-
-
-if __name__ == "__main__":
- test_error_types()
+++ /dev/null
-class GardenError(Exception):
- def __str__(self) -> str:
- return f"General Garden Error: {super().__str__()}"
-
-
-class PlantError(GardenError):
- plant: str
-
- def __init__(self, plant: str) -> None:
- self.plant = plant
-
- def __str__(self) -> str:
- return f"The {self.plant} plant is wilting!"
-
-
-class WaterError(GardenError):
- def __init__(self):
- pass
-
- def __str__(self) -> str:
- return "Not enough water in the tank!"
-
-
-def test_custom_errors() -> None:
- print("=== Custom Garden Errors Demo ===")
-
- print("Testing PlantError...")
- try:
- raise PlantError("tomato")
- except PlantError as e:
- print(f"Caught PlantError: {e}")
- print()
-
- print("Testing WaterError...")
- try:
- raise WaterError()
- except WaterError as e:
- print(f"Caught WaterError: {e}")
- print()
-
- print("Testing catching all garden errors...")
- try:
- raise PlantError("tomato")
- except GardenError as e:
- print(f"Caught a garden error: {e}")
-
- try:
- raise WaterError()
- 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
-"""Exercise 3: Finally Block - Always Clean Up
-
-Demonstrates the use of try/except/finally blocks to ensure cleanup
-always happens, even when errors occur.
-"""
-
-
-def water_plants(plant_list: list) -> None:
- """
- Water plants while ensuring cleanup always happens.
-
- Args:
- plant_list: List of plant names to water
- """
- try:
- print("Opening watering system")
- for plant in plant_list:
- if plant is None:
- raise ValueError("Cannot water None - invalid plant!")
- print(f"Watering {plant}")
- except (ValueError, TypeError) as e:
- print(f"Error: {e}")
- finally:
- print("Closing watering system (cleanup)")
-
-
-def test_watering_system() -> None:
- """Test the watering system with normal and error scenarios."""
- print("=== Garden Watering System ===\n")
-
- print("Testing normal watering...")
- water_plants(["tomato", "lettuce", "carrots"])
- print("Watering completed successfully!\n")
-
- print("Testing with error...")
- water_plants(["tomato", None, "lettuce"])
- print("Cleanup always happens, even with errors!")
-
-
-if __name__ == "__main__":
- test_watering_system()
+++ /dev/null
-"""Exercise 4: Raising Your Own Errors
-
-Demonstrates how to use the raise keyword to signal problems
-in your garden program.
-"""
-
-
-def check_plant_health(
- plant_name: str, water_level: int, sunlight_hours: int
-) -> str:
- """
- Check plant health and raise errors for invalid inputs.
-
- Args:
- plant_name: Name of the plant
- water_level: Water level (1-10)
- sunlight_hours: Hours of sunlight (2-12)
-
- Returns:
- Success message if all parameters are valid
-
- Raises:
- ValueError: If any parameter is invalid
- """
- if not plant_name or plant_name == "":
- raise ValueError("Plant name cannot be empty!")
-
- if water_level < 1 or water_level > 10:
- raise ValueError(
- f"Water level {water_level} is too "
- f"{'high' if water_level > 10 else 'low'} "
- f"(max 10)"
- if water_level > 10
- else "(min 1)"
- )
-
- if sunlight_hours < 2 or sunlight_hours > 12:
- msg = f"Sunlight hours {sunlight_hours} is too "
- if sunlight_hours > 12:
- msg += "high (max 12)"
- else:
- msg += "low (min 2)"
- raise ValueError(msg)
-
- return f"Plant '{plant_name}' is healthy!"
-
-
-def test_plant_checks() -> None:
- """Test plant health checks with various inputs."""
- print("=== Garden Plant Health Checker ===\n")
-
- test_cases = [
- ("Testing good values...", "tomato", 5, 8),
- ("Testing empty plant name...", "", 5, 8),
- ("Testing bad water level...", "tomato", 15, 8),
- ("Testing bad sunlight hours...", "tomato", 5, 0),
- ]
-
- for test_name, plant, water, sunlight in test_cases:
- print(test_name)
- try:
- result = check_plant_health(plant, water, sunlight)
- print(f"✓ {result}")
- except ValueError as e:
- print(f"Error: {e}")
- print()
-
- print("All error raising tests completed!")
-
-
-if __name__ == "__main__":
- test_plant_checks()
+++ /dev/null
-"""Exercise 5: Garden Management System
-
-Combines all error handling techniques: custom exceptions, try/except/finally,
-raising errors, and resource cleanup.
-"""
-
-
-class GardenError(Exception):
- """Base exception for garden-related errors."""
-
- def __str__(self) -> str:
- return f"GardenError: {super().__str__()}"
-
-
-class PlantError(GardenError):
- """Exception for plant-specific problems."""
-
- def __init__(self, plant: str) -> None:
- self.plant = plant
-
- def __str__(self) -> str:
- return f"The {self.plant} plant is wilting!"
-
-
-class WaterError(GardenError):
- """Exception for water system problems."""
-
- def __str__(self) -> str:
- return "Not enough water in tank"
-
-
-class GardenManager:
- """Manages a garden with error handling for all operations."""
-
- def __init__(self):
- """Initialize the garden manager."""
- self.plants = {}
- self.watering_system_open = False
-
- def add_plant(
- self, plant_name: str, water_level: int = 5, sunlight_hours: int = 8
- ) -> None:
- """
- Add a plant to the garden.
-
- Args:
- plant_name: Name of the plant
- water_level: Initial water level (1-10)
- sunlight_hours: Hours of sunlight needed (2-12)
-
- Raises:
- ValueError: If plant name is empty
- GardenError: If invalid parameters
- """
- if not plant_name or plant_name == "":
- raise ValueError("Plant name cannot be empty!")
-
- if water_level < 1 or water_level > 10:
- raise GardenError(f"Water level {water_level} is invalid (1-10)")
-
- if sunlight_hours < 2 or sunlight_hours > 12:
- raise GardenError(
- f"Sunlight hours {sunlight_hours} is invalid (2-12)"
- )
-
- self.plants[plant_name] = {
- "water": water_level,
- "sunlight": sunlight_hours,
- }
-
- def water_plants(self, plant_names: list) -> None:
- """
- Water specific plants with proper cleanup.
-
- Args:
- plant_names: List of plant names to water
- """
- try:
- print("Opening watering system")
- self.watering_system_open = True
-
- for plant in plant_names:
- if plant in self.plants:
- print(f"Watering {plant} - success")
- else:
- raise PlantError(plant)
-
- except PlantError as e:
- print(f"Error: {e}")
-
- finally:
- print("Closing watering system (cleanup)")
- self.watering_system_open = False
-
- def check_plant_health(
- self,
- plant_name: str,
- water_level: int = None,
- sunlight_hours: int = None,
- ) -> None:
- """
- Check health of a plant with specific parameters.
-
- Args:
- plant_name: Name of the plant
- water_level: Water level to check (1-10)
- sunlight_hours: Sunlight hours to check (2-12)
- """
- if water_level and (water_level < 1 or water_level > 10):
- raise GardenError(
- f"Water level {water_level} is too "
- f"{'high' if water_level > 10 else 'low'} (max 10)"
- )
-
- if sunlight_hours and (sunlight_hours < 2 or sunlight_hours > 12):
- raise GardenError(
- f"Sunlight {sunlight_hours} is too "
- f"{'high' if sunlight_hours > 12 else 'low'} (max 12)"
- )
-
- if plant_name in self.plants:
- w = self.plants[plant_name]["water"]
- s = self.plants[plant_name]["sunlight"]
- print(f"{plant_name}: healthy (water: {w}, sun: {s})")
-
-
-def test_garden_management() -> None:
- """Test the complete garden management system."""
- print("=== Garden Management System ===\n")
-
- manager = GardenManager()
-
- print("Adding plants to garden...")
- test_plants = [
- ("tomato", 5, 8),
- ("lettuce", 6, 7),
- ("", 5, 8),
- ]
-
- for plant, water, sun in test_plants:
- try:
- manager.add_plant(plant, water, sun)
- print(f"Added {plant} successfully")
- except (ValueError, GardenError) as e:
- print(f"Error adding plant: {e}")
- print()
-
- print("Watering plants...")
- manager.water_plants(["tomato", "lettuce"])
- print()
-
- print("Checking plant health...")
- for plant in ["tomato", "lettuce"]:
- try:
- manager.check_plant_health(plant)
- except GardenError as e:
- print(f"Error checking {plant}: {e}")
- print()
-
- print("Testing error recovery...")
- try:
- raise WaterError()
- except GardenError as e:
- print(f"Caught GardenError: {e}")
-
- print("System recovered and continuing...")
- print("\nGarden management system test complete!")
-
-
-if __name__ == "__main__":
- test_garden_management()