From: = <=> Date: Mon, 12 Jan 2026 11:54:41 +0000 (+0100) Subject: so much slop, but whatever lgtm X-Git-Url: https://git.uwuaxy.net/?a=commitdiff_plain;h=e52caec1246432586c1ddb5ef03b9a0e9cdb2db1;p=axy%2Fft%2Fpython02.git so much slop, but whatever lgtm --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c938bb --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**.pdf \ No newline at end of file diff --git a/ex0/ft_first_exception.py b/ex0/ft_first_exception.py index b83fed9..3bb7ca4 100644 --- a/ex0/ft_first_exception.py +++ b/ex0/ft_first_exception.py @@ -2,9 +2,9 @@ def check_temperature(temp_str: str) -> None: try: temp = int(temp_str) if temp < 0: - print(f"Error: {temp}°C is to cold for plants (min 0°C)") + print(f"Error: {temp}°C is too cold for plants (min 0°C)") elif temp > 40: - print(f"Error: {temp}°C is to hot for plants (max 40°C)") + 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: @@ -22,7 +22,7 @@ def test_temperature_input() -> None: test_check("abc") test_check("100") test_check("-50") - print("All test completed - program didn't crash!") + print("All tests completed - program didn't crash!") if __name__ == "__main__": diff --git a/ex1/ft_different_errors.py b/ex1/ft_different_errors.py index e20d1b8..ab219f3 100644 --- a/ex1/ft_different_errors.py +++ b/ex1/ft_different_errors.py @@ -11,7 +11,7 @@ def garden_operations(exception: str): def test_error_types() -> None: - print("=== Garden Error Type Demo ===") + print("=== Garden Error Types Demo ===") for error in [ "ValueError", "ZeroDivisionError", diff --git a/ex2/ft_custom_errors.py b/ex2/ft_custom_errors.py index 265d117..eb6cc45 100644 --- a/ex2/ft_custom_errors.py +++ b/ex2/ft_custom_errors.py @@ -21,5 +21,34 @@ class WaterError(GardenError): 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("Testing WaterError...") + try: + raise WaterError() + except WaterError as e: + print(f"Caught WaterError: {e}") + + 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__": - raise GardenError(12) + test_custom_errors() diff --git a/ex3/ft_finally_block.py b/ex3/ft_finally_block.py new file mode 100644 index 0000000..a8a0f73 --- /dev/null +++ b/ex3/ft_finally_block.py @@ -0,0 +1,41 @@ +"""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() diff --git a/ex4/ft_raise_errors.py b/ex4/ft_raise_errors.py new file mode 100644 index 0000000..73b3027 --- /dev/null +++ b/ex4/ft_raise_errors.py @@ -0,0 +1,72 @@ +"""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() diff --git a/ex5/ft_garden_management.py b/ex5/ft_garden_management.py new file mode 100644 index 0000000..8aac568 --- /dev/null +++ b/ex5/ft_garden_management.py @@ -0,0 +1,168 @@ +"""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("\nWatering plants...") + manager.water_plants(["tomato", "lettuce"]) + + print("\nChecking plant health...") + for plant in ["tomato", "lettuce"]: + try: + manager.check_plant_health(plant) + except GardenError as e: + print(f"Error checking {plant}: {e}") + + print("\nTesting 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()