]> Untitled Git - axy/ft/python02.git/commitdiff
so much slop, but whatever lgtm
author= <=>
Mon, 12 Jan 2026 11:54:41 +0000 (12:54 +0100)
committer= <=>
Mon, 12 Jan 2026 11:54:41 +0000 (12:54 +0100)
.gitignore [new file with mode: 0644]
ex0/ft_first_exception.py
ex1/ft_different_errors.py
ex2/ft_custom_errors.py
ex3/ft_finally_block.py [new file with mode: 0644]
ex4/ft_raise_errors.py [new file with mode: 0644]
ex5/ft_garden_management.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..7c938bb
--- /dev/null
@@ -0,0 +1 @@
+**.pdf
\ No newline at end of file
index b83fed9b0349c26c8a4f4326cf632a926215591f..3bb7ca427546ee1fc677022b86e05ef812757afd 100644 (file)
@@ -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__":
index e20d1b89d2e1b9f81ce0196c5b85a76de6633779..ab219f3a5c6c2a04876a2ffacd394768e7dc4838 100644 (file)
@@ -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",
index 265d117a037df504f9c6577fbd0f6755ae9c4696..eb6cc452587a053be9298262c3778c5aeb507069 100644 (file)
@@ -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 (file)
index 0000000..a8a0f73
--- /dev/null
@@ -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 (file)
index 0000000..73b3027
--- /dev/null
@@ -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 (file)
index 0000000..8aac568
--- /dev/null
@@ -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()