def build_meal(dishes, lower_boundaries, upper_boundaries): #reject if there simply aren't enough meals if len(dishes) < 10: return "NOT ENOUGH DISHES TO MAKE A MEAL" nutrient_reject = {x: 0 for x in TARGET_NUTRIENTS} myMeal = Meal(lower_boundaries) #descending list of foods with most of each respective nutrient sorted_nutrients = { nutrient: sorted(dishes, key=lambda x: x.nutrition[nutrient], reverse=True) for nutrient in TARGET_NUTRIENTS } sorted_indices = {nutrient: 0 for nutrient in TARGET_NUTRIENTS} bestMeal = 0 bestScore = math.inf for i in range(100): highest_unmet = myMeal.nutrient_totals()[0] if sorted_indices[highest_unmet] >= len( sorted_nutrients[highest_unmet]): dish = random.choice(sorted_nutrients[highest_unmet]) else: dish = sorted_nutrients[highest_unmet][ sorted_indices[highest_unmet]] sorted_indices[highest_unmet] += 1 while myMeal.containsDish(dish): if sorted_indices[highest_unmet] >= len( sorted_nutrients[highest_unmet]): dish = random.choice(sorted_nutrients[highest_unmet]) else: dish = sorted_nutrients[highest_unmet][ sorted_indices[highest_unmet]] sorted_indices[highest_unmet] += 1 # print("We need {} so we add {}".format(highest_unmet,dish.name)) # print(myMeal) myMeal.addDish(dish) # print(myMeal) constraint = myMeal.under_upper_bounds(upper_boundaries) if constraint[0]: if myMeal.all_nutrients_met(): return myMeal, True else: # print("Too much of the {} nutrient".format(constraint[1])) myMeal.removeDish(dish.name) # print("Removed {}".format(dish.name)) nutrient_reject[constraint[1]] += 1 if nutrient_reject[constraint[1]] > 3 and not myMeal.isEmpty(): sorted_meal = myMeal.sort_by_nutrient(constraint[1]) myMeal.removeDish(sorted_meal[-1]) # print("Also removed {} because of excess {}".format(sorted_meal[-1], # constraint[1])) nutrient_reject[constraint[1]] = 0 if myMeal.meal_score() < bestScore: bestScore = myMeal.meal_score() bestMeal = Meal(myMeal.boundaries.copy()) bestMeal.items = myMeal.items.copy() bestMeal.totals = myMeal.totals.copy() # print(myMeal.meal_score()) # print() return bestMeal, False