-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
124 lines (117 loc) · 5.22 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from sys import argv
from classes import *
import csv
import numpy as py
from scipy.optimize import nnls
from tqdm import tqdm
from flask import Flask, render_template, request, redirect
from itertools import combinations
import random
app = Flask(__name__)
food_list = []
with open('nutrition.csv', newline='') as csvfile:
reader = csv.DictReader(csvfile)
its = 1000000
it_count = 0
for row in reader:
fat_per_gram = float(row['total_fat'][:-1])*(1/float(row['serving_size'][:-2]))
calories_per_gram = float(row['calories'])*(1/float(row['serving_size'][:-2])) #assumed serving_size is in grams
carbs_per_gram = float(row['carbohydrate'][:-2])*(1/float(row['serving_size'][:-2]))
protein_per_gram = float(row['protein'][:-2])*(1/float(row['serving_size'][:-2]))
f = Food(row['name'], calories_per_gram, carbs_per_gram, protein_per_gram, fat_per_gram)
food_list.append(f)
it_count = it_count + 1
if it_count == its:
break
def predict(foodlist, target_calories, target_carbs, target_protein, target_fat, verbose=0):
calories_list = []
fat_list = []
carbs_list = []
protein_list = []
for food in foodlist:
calories_list.append(food.calories)
fat_list.append(food.fat)
carbs_list.append(food.carbs)
protein_list.append(food.protein)
A = [calories_list, carbs_list, protein_list, fat_list]
B = py.array([target_calories, target_carbs, target_protein, target_fat])
x = nnls(A,B)
i = 0
cals = 0
carbs = 0
protein = 0
fat = 0
names = []
for scale in x[0]:
cals = cals + (scale * food_list[i].calories)
carbs = carbs + (scale * food_list[i].carbs)
protein = protein + (scale * food_list[i].protein)
fat = fat + (scale * food_list[i].fat)
names.append(food_list[i].name)
i = i + 1
foods = []
food_amounts = []
for idx, name in enumerate(names):
if verbose == 1:
print(str("{:.2f}".format(x[0][idx]))+" grams "+name)
foods.append(name)
food_amounts.append(x[0][idx])
if verbose == 1:
print("========================================================================")
print("target calories: "+str(target_calories)+", actual: "+str(cals)+", difference: "+str(target_calories-cals))
print("target carbs: "+str(target_carbs)+", actual: "+str(carbs)+", difference: "+str(target_carbs-carbs))
print("target protein: "+str(target_protein)+", actual: "+str(protein)+", difference: "+str(target_protein-protein))
print("target fat: "+str(target_fat)+", actual: "+str(fat)+", difference: "+str(target_fat-fat))
error_score = abs(target_calories-cals) + abs(target_carbs-carbs) + abs(target_protein-protein) + abs(target_fat-fat)
if verbose == 1 or verbose == 2:
print("error score: "+str(error_score))
return (error_score, foods, food_amounts, [cals, carbs, protein, fat])
def run(random_count, order_length, target_calories, target_carbs, target_protein, target_fat):
#order_length = int(argv[2])
#selection = random.choice(options)
#print(selection)
#print(len(options))
lowest_error = 99999
lowest_combo = None
random_sampling = True
#random_count = int(argv[1])
random_target = 80
random_mode = True #true is random for random_count iterations, false is til reaches below random_target
if random_sampling == False:
options = list(combinations(food_list, order_length)) #len = c(len(food_list), order_length)) = 20c5 = 15504
for option in options:
e = predict(option, target_calories, target_carbs, target_protein, target_fat)[0]
if e < lowest_error:
lowest_error = e
lowest_combo = option
else:
if random_mode:
for i in range(random_count):
option = []
for i in range(order_length):
option.append(random.choice(food_list))
e = predict(option, target_calories, target_carbs, target_protein, target_fat)[0]
if e < lowest_error:
lowest_error = e
lowest_combo = option
else:
while lowest_error > random_target:
option = []
for i in range(order_length):
option.append(random.choice(food_list))
e = predict(option, target_calories, target_carbs, target_protein, target_fat)[0]
if e < lowest_error:
lowest_error = e
lowest_combo = option
#e = predict(lowest_combo, target_calories, target_carbs, target_protein, target_fat, 0)[0]
return predict(lowest_combo, target_calories, target_carbs, target_protein, target_fat, 0)
@app.route('/', methods=["GET", "POST"])
def index():
r = None
if request.method == "POST":
req = request.form
r = run(int(req['random_count']), int(req['order_length']), int(req['target_calories']), int(req['target_carbs']), int(req['target_protein']), int(req['target_fat']))
print(r)
if r == None:
return render_template('index.html')
return render_template('index.html', foods=r[1], quantities=r[2], total=r[3])