Assignments

Modify the Ingredient and Recipe classes so that the following code works.


In [46]:
class Ingredient(object):
    """The ingredient object that contains nutritional information"""
    
    def __init__(self, name, data, protein=0, fat=0):
        if type(data) == dict:
            self.nutrition_store = data
        else:
            self.nutrition_store = {'carbs': data, 'protein':protein, 'fat': fat}
        self.name = name
        
    
    def __repr__(self):
        return 'Ingredient({0}, {1})'.format(self.name, self.nutrition_store)
    
    @property
    def nutrition(self):
        """Returns the nutritional information for the ingredient"""
        return self.nutrition_store  

class Recipe(object):
    """The Recipe object containing the ingredients"""
    
    def __init__(self, name, ingredients):
        self.name = name
        self.ingredients = ingredients
        
    def __repr__(self):
        temp_str = []
        for amount, ingredient in self.ingredients:
            temp_str.append('({0}, {1})'.format(amount, ingredient))
        return 'Recipe({0}, [{1}])'.format(self.name, ', '.join(temp_str))
        
        
    @property    
    def nutrition(self):
        """Returns the nutritional information for the recipe"""
        nutrition = {}
        for amount, ingredient in self.ingredients:
            for key in ingredient.nutrition:
                nutrition[key] = nutrition.get(key, 0) + amount * ingredient.nutrition[key]
        return nutrition

In [47]:
bread = Recipe('Bread', [(820, Ingredient('Flour', 0.77, 0.10, 0.01)), 
                         (30, Ingredient('Oil', 0, 0, 1)), 
                         (36, Ingredient('Sugar', 1, 0, 0)), 
                         (7, Ingredient('Yeast', 0.3125, 0.5, 0.0625)),
                         (560, Ingredient('Water', 0, 0, 0))])
print(bread.ingredients)
# Should be roughly [(820, Ingredient(Flour, 0.77, 0.1, 0.01)), (30, Ingredient(Oil, 0, 0, 1)), 
# (36, Ingredient(Sugar, 1, 0, 0)), (7, Ingredient(Yeast, 0.3125, 0.5, 0.0625)), (560, Ingredient(Water, 0, 0, 0))]


[(820, Ingredient(Flour, {'carbs': 0.77, 'fat': 0.01, 'protein': 0.1})), (30, Ingredient(Oil, {'carbs': 0, 'fat': 1, 'protein': 0})), (36, Ingredient(Sugar, {'carbs': 1, 'fat': 0, 'protein': 0})), (7, Ingredient(Yeast, {'carbs': 0.3125, 'fat': 0.0625, 'protein': 0.5})), (560, Ingredient(Water, {'carbs': 0, 'fat': 0, 'protein': 0}))]

In [48]:
print(bread.nutrition)
#Should be roughly {'carbs': 669.5875, 'protein': 85.5, 'fat': 38.6375} the order is not important


{'carbs': 669.5875, 'fat': 38.6375, 'protein': 85.5}

In [49]:
#Points to note:
# - The different call to Ingredient, you can use isinstance or type to change the 
#   behaviour depending on the arguments supplied
# - Cholesterol as an extra nutrient, your implementation should accept any nutrient
# - Use of Recipe (bread) as an ingredient
basic_french_toast = Recipe('Basic French Toast', [(300, Ingredient('Egg', {'carbs': 0.0077, 'protein': 0.1258, 
                                                                            'fat': 0.0994, 'cholesterol': 0.00423})), 
                                                  (0.25, bread)])
print(basic_french_toast.ingredients)
# Should be roughly:
# [(300, Ingredient(Egg, 0.0077, 0.1258, 0.0994)), (0.25, Recipe(Bread, [(820, Ingredient(Flour, 0.77, 0.1, 0.01)), 
# (30, Ingredient(Oil, 0, 0, 1)), (36, Ingredient(Sugar, 1, 0, 0)), (7, Ingredient(Yeast, 0.3125, 0.5, 0.0625)), 
# (560, Ingredient(Water, 0, 0, 0))]))]
# Note the formatting for the Recipe object, a __repr__ method will be needed


[(300, Ingredient(Egg, {'carbs': 0.0077, 'fat': 0.0994, 'protein': 0.1258, 'cholesterol': 0.00423})), (0.25, Recipe(Bread, [(820, Ingredient(Flour, {'carbs': 0.77, 'fat': 0.01, 'protein': 0.1})), (30, Ingredient(Oil, {'carbs': 0, 'fat': 1, 'protein': 0})), (36, Ingredient(Sugar, {'carbs': 1, 'fat': 0, 'protein': 0})), (7, Ingredient(Yeast, {'carbs': 0.3125, 'fat': 0.0625, 'protein': 0.5})), (560, Ingredient(Water, {'carbs': 0, 'fat': 0, 'protein': 0}))]))]

In [50]:
print(basic_french_toast.nutrition)
# Should be roughly {'protein': 59.115, 'carbs': 169.706875, 'cholesterol': 1.2690000000000001, 'fat': 39.479375000000005}
# The order is not important


{'carbs': 169.706875, 'fat': 39.479375000000005, 'protein': 59.115, 'cholesterol': 1.2690000000000001}