Lesson · 40 min · Free
Nutrition Agent: Capstone Part 3
Nutrition Agent: Capstone Part 3 body { font-family: sans-serif; line-height: 1.6; margin: 20px; } h1 { color: #2c3e50; } h2 { color: #34495e; border-bottom: 2px solid #ccc; padding-bottom: 5px; margin-top: 30px; } p { m
Nutrition Agent: Capstone Part 3
Welcome to the final installment of the Nutrition Agent Capstone project! In this part, we'll consolidate our understanding of Python programming by integrating various concepts learned throughout the course. Our focus will be on refining the data processing, implementing more sophisticated decision-making logic, and preparing our agent for potential real-world applications in a simulated pharmacy or biotech environment. We will emphasize robust error handling, modularity, and the application of data structures to manage complex nutritional information efficiently. For pharmacy and biotech students, the ability to process and interpret health-related data is paramount. This capstone project aims to simulate a simplified version of such a task, where our "Nutrition Agent" must make recommendations based on predefined criteria. In this lesson, we will particularly look at how to structure our code for better readability and maintainability, which is crucial for collaborative projects and long-term software development in a professional setting.
Refining Data Structures and Logic for Nutritional Recommendations
In previous parts, we might have used basic lists or dictionaries. For a more robust system, especially when dealing with varied nutritional data, it's beneficial to think about how we can represent complex relationships. Consider a scenario where a patient has multiple dietary restrictions or specific health goals. A simple dictionary might become cumbersome. We can leverage nested data structures, or even custom classes (though we'll stick to built-in types for this basic course), to represent this information more effectively. Let's refine our approach to handling patient profiles and food item data. We'll use a list of dictionaries for food items, where each dictionary contains detailed information. Similarly, patient profiles will be dictionaries. Our recommendation logic will then iterate through these structures, applying conditional checks to filter and suggest appropriate food items. We'll also introduce a basic function to simulate checking for allergies or specific nutritional needs. # Example 1: Refined Food Database and Patient Profile food_database = [ {"name": "Quinoa Salad", "category": "Grain", "calories": 300, "protein_g": 15, "allergens": ["nuts"], "suitable_for_diabetic": True}, {"name": "Chicken Breast", "category": "Protein", "calories": 250, "protein_g": 40, "allergens": [], "suitable_for_diabetic": True}, {"name": "Fruit Smoothie", "category": "Beverage", "calories": 180, "protein_g": 5, "allergens": [], "suitable_for_diabetic": False}, {"name": "Lentil Soup", "category": "Legume", "calories": 220, "protein_g": 12, "allergens": [], "suitable_for_diabetic": True}, {"name": "Whole Wheat Bread", "category": "Grain", "calories": 150, "protein_g": 6, "allergens": ["gluten"], "suitable_for_diabetic": True} ] patient_profile = { "name": "Alice", "allergies": ["nuts", "gluten"], "dietary_needs": ["low_sugar"], # 'low_sugar' implies suitable_for_diabetic = True "calorie_target": 2000 } def recommend_food(patient, food_db): recommendations = [] print(f"Generating recommendations for {patient['name']}:") for food in food_db: is_suitable = True # Check for allergies for allergen in patient['allergies']: if allergen in food['allergens']: is_suitable = False # print(f" - {food['name']} skipped due to {allergen} allergy.") break if not is_suitable: continue # Check for dietary needs (e.g., low sugar for diabetic patients) if "low_sugar" in patient['dietary_needs'] and not food['suitable_for_diabetic']: is_suitable = False # print(f" - {food['name']} skipped as not suitable for low sugar diet.") if is_suitable: recommendations.append(food['name']) return recommendations # Get recommendations recommended_items = recommend_food(patient_profile, food_database) print(f"Recommended food items: {', '.join(recommended_items)}") # Expected Output: # Generating recommendations for Alice: # Recommended food items: Chicken Breast, Lentil Soup Notice how the recommend_food function encapsulates the logic for filtering. This modular approach makes our code easier to read, debug, and extend. If we need to add a new dietary restriction, we only need to modify this function. Error handling, though not explicitly shown in the basic example above, would involve checks for empty databases or missing keys in dictionaries, preventing our program from crashing unexpectedly. For instance, we could use .get() with a default value when accessing dictionary keys, or wrap critical sections in try-except blocks. Let's consider adding a simple error handling mechanism to ensure our function is robust against malformed food entries, although for this level, we'll keep it basic to focus on the core logic. # Example 2: Adding Basic Error Handling and Calorie Tracking def recommend_food_with_tracking(patient, food_db): recommendations = [] current_calories = 0 print(f"\nGenerating recommendations for {patient['name']} with calorie tracking:") for food in food_db: is_suitable = True # Basic error handling for missing keys try: food_name = food['name'] food_allergens = food.get('allergens', []) # Use .get() for safer access food_calories = food.get('calories', 0) food_diabetic_suitability = food.get('suitable_for_diabetic', False) except KeyError as e: print(f"Warning: Malformed food entry encountered (missing key: {e}). Skipping entry.") continue # Check for allergies for allergen in patient['allergies']: if allergen in food_allergens: is_suitable = False break if not is_suitable: continue # Check for dietary needs if "low_sugar" in patient['dietary_needs'] and not food_diabetic_suitability: is_suitable = False if is_suitable: # Simulate adding to diet and tracking calories if (current_calories + food_calories) The second example introduces a basic calorie tracking mechanism and demonstrates using .get() for dictionary access to provide default values if a key is missing, making our code more resilient. This is a common pattern in professional software development, especially when dealing with data from external sources that might not always be perfectly formatted.
Key Takeaways
Modularity: Breaking down complex problems into smaller, manageable functions improves code readability and maintainability. Data Structures: Using appropriate data structures (like lists of dictionaries) is crucial for organizing and accessing complex, interconnected data efficiently. Conditional Logic: Sophisticated if-elif-else statements are essential for implementing decision-making processes, such as filtering food based on dietary needs or allergies. Basic Error Handling: Employing techniques like .get() for dictionary access or try-except blocks makes your programs more robust against unexpected data or situations. Iterative Refinement: Software development is an iterative process. Starting with basic functionality and progressively adding features and robustness is a standard practice.
Practice Exercise: Enhancing the Nutrition Agent
Expand the recommend_food_with_tracking function to include a new dietary need: "high_protein". For patients with this need, your function should prioritize foods with a protein_g value greater than 20. If multiple items meet the criteria, the agent should recommend the one with the highest protein first, until the calorie target is met. You may need to modify the patient_profile and food_database to test this new feature effectively. Consider how you would sort the recommended items before adding them to the patient's diet.
Watch the full lesson — free
This topic is part of Python Programming - Basics, a complete AI-narrated video course. Press play once and watch the entire lecture like a movie.
Start the course free →