Skip to content

Commit

Permalink
implementation of analysis package in testing and README
Browse files Browse the repository at this point in the history
  • Loading branch information
noahtren committed Apr 4, 2019
1 parent 3d38e83 commit 5bd1e04
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 12 deletions.
95 changes: 94 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,97 @@ for food in m.foods:
{'nutrient_id': 269, 'name': 'Sugar', 'group': 'Proximates', 'unit': 'g', 'value': 8.97}
{'nutrient_id': 269, 'name': 'Sugar', 'group': 'Proximates', 'unit': 'g', 'value': 1.7}
```
Note that this sorts the foods in the Meal object from greatest to least in terms of how much sugar each food has.
Note that this sorts the foods in the Meal object from greatest to least in terms of how much sugar each food has.

## Generate Food Recommendations in Context of a Meal and Pantry
Because it would be computationally expensive to generate a food recommendation in the context of every food in the database, and it may be unrealistic to recommend any food from the database as it may be hard to access, you must define a list of foods that will serve as a pantry object. Here is an example pantry object containing many common whole foods.

```python
pantry = {
# DAIRY AND EGG
"01001":100, # butter, salted
"01145":100, # butter, without salt
"01079":100, # 2% milk
"01077":100, # milk, whole
"01086":100, # skim milk
"01132":100, # scrambled eggs
"01129":100, # hard boiled eggs
"01128":100, # fried egg
# MEAT
"15076":100, # atlantic salmon
"07935":100, # chicken breast oven-roasted
"13647":100, # steak
"05192":100, # turkey
# FRUIT
"09037":100, # avocado
"09316":100, # strawberries
"09050":100, # blueberry
"09302":100, # raspberry
"09500":100, # red delicious apple
"09040":100, # banana
"09150":100, # lemon
"09201":100, # oranges
"09132":100, # grapes
# PROCESSED
"21250":100, # hamburger
"21272":100, # pizza
"19088":100, # ice cream
"18249":100, # donut
# DRINK
"14400":100, # coke
"14429":100, # tap water
"14433":100, # bottled water
"09206":100, # orange juice
"14278":100, # brewed green tea
"14209":100, # coffee brewed with tap water
# (milk is included in dairy group)
# GRAIN
"12006":100, # chia
"12220":100, # flaxseed
"20137":100, # quinoa, cooked
"20006":100, # pearled barley
"20051":100, # white rice enriched cooked
"20041":100, # brown rice cooked
"12151":100, # pistachio
"19047":100, # pretzel
"12061":100, # almond
# LEGUME
"16057":100, # chickpeas
"16015":100, # black beans
"16043":100, # pinto beans
"16072":100, # lima beans
"16167":100, # peanut butter smooth
# VEGETABLE
"11124":100, # raw carrots
"11090":100, # broccoli
"11457":100, # spinach, raw
"11357":100, # baked potato
"11508":100, # baked sweet potato
"11530":100, # tomato, red, cooked
"11253":100, # lettuce
"11233":100, # kale
"11313":100, # peas
"11215":100, # garlic
# OTHER
"04053":100, # olive oil
"19904":100, # dark chocolate
"11238":100, # shiitake mushrooms
"19165":100, # cocoa powder
}
pantry_food = client.get_foods(pantry)
```
Now, with a list of possible foods to recommend, you can call noms.generate_recommendations with the meal we set up earlier, which consists of just broccoli and brown rice.
```python
recommendations = noms.generate_recommendations(m, pantry_food, noms.nutrient_dict, 3)
for rec in recommendations:
# a recommendation is a list containing the calculated loss after the recommendation
# is applied, the index of the pantry for the recommendation, and the amount of that
# food / 100g
print(str(round(rec[2] * 100, 2)) + "g", "of", pantry_food[rec[1]].desc["name"])
```
```
50.36g of Seeds, chia seeds, dried
53.3g of Nuts, almonds
56.76g of Peanut Butter, smooth (Includes foods for USDA's Food Distribution Program)
```
It is reasonable that the function returned these foods from the pantry as the current daily nutrition is low in protein and Omega-3s, which chia seeds satisfy the most.
7 changes: 6 additions & 1 deletion noms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@
# csv reports
from noms.report import export_report, report

from noms.objects.nutrient_dict import index_from_name
# nutrient dict
from noms.objects.nutrient_dict import index_from_name
from noms.objects.nutrient_dict import nutrient_dict

# recommendation method
from noms.analyze import generate_recommendations
7 changes: 4 additions & 3 deletions noms/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def scaled_loss(k, *args):
"""
return (scaled_loss(sol.x[0], required_normed_nutrients, suggestion, nutrient_dict), sol.x[0])

def generate_recommendations(meal, pantry, nutrient_dict, n):
def generate_recommendations(meal, pantry, nutrient_dict, n, verbose=False):
"""
Gives the top n food recommendations to satisfy daily nutrition in
context of the current foods, available foods, and a nutrient_dict full
Expand All @@ -103,7 +103,8 @@ def generate_recommendations(meal, pantry, nutrient_dict, n):
rec_index = rec_i
rec_optimum = sug_obj[1]
rec_data.append([copy.copy(cur_loss), copy.copy(rec_i), copy.deepcopy(sug_obj[1])])
print(pantry[rec_i].desc['name'], cur_loss)
print("^" * 50)
if verbose:
print(pantry[rec_i].desc['name'], cur_loss)
print("^" * 50)
rec_data.sort(key=lambda x: x[0])
return rec_data[:n]
20 changes: 13 additions & 7 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ def _test():

# Test Search
print(client.search_query("Raw Broccoli"))
print(client.search_query("Cola"))
print(client.search_query("Brown Rice"))
# Test Search With No Results
print(client.search_query("Unicorn meat"))

# Test Food (last id in dict is not a food and doesn't return anything)
food_list = client.get_foods({'11090':100, '14400':100, '09120319':100})
food_list = client.get_foods({'11090':100, '20041':500, '09120319':100})
m = noms.Meal(food_list)

# Test Report
Expand Down Expand Up @@ -54,15 +54,14 @@ def _test():
"09201":100, # oranges
"09132":100, # grapes
# PROCESSED
"21250":100, # hamburger, 6 oz
"21272":100, # pizza (2 slices)
"21250":100, # hamburger
"21272":100, # pizza
"19088":100, # ice cream
"19057":100, # doritos (25)
"18249":100, # donut
# DRINK
"14400":100, # coke
"14429":100, # tap water
"14433":100, # aquafina bottled water
"14433":100, # bottled water
"09206":100, # orange juice
"14278":100, # brewed green tea
"14209":100, # coffee brewed with tap water
Expand Down Expand Up @@ -97,14 +96,21 @@ def _test():
# OTHER
"04053":100, # olive oil
"19904":100, # dark chocolate
"14058":100, # protein powder isolate
"11238":100, # shiitake mushrooms
"19165":100, # cocoa powder
}
pantry_food = client.get_foods(pantry)
P = noms.Meal(pantry_food)
for f in P.foods:
print(f.desc["name"])

# Test recommendations
recommendations = noms.generate_recommendations(m, pantry_food, noms.nutrient_dict, 3)
for rec in recommendations:
# a recommendation is a list containing the calculated loss after the recommendation
# is applied, the index of the pantry for the recommendation, and the amount of that
# food / 100g
print(str(round(rec[2] * 100, 2)) + "g", "of", pantry_food[rec[1]].desc["name"])

if __name__ == "__main__":
_test()

0 comments on commit 5bd1e04

Please sign in to comment.