Пример #1
0
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
Пример #2
0
    def create_meal(self, mealid):
        mealigredients = self.get_meal_ingredients(mealid)

        macros = self.calc_meal(mealid)

        name = self.get_name(mealid)

        meal = Meal.Meal(name, mealigredients, macros)
        return meal
Пример #3
0
def main():
    while True:

        #user picks meal
        print_options(OPTIONS)
        choice = input("Which meal?: ")
        if is_invalid(choice, len(OPTIONS)):
            print()
            print("Please type a number from the menu!")
            print()
            continue
        choice = int(choice)
        if choice == 4:
            print()
            break

        #user picks dining hall
        locations = get_locations(MEALS[choice - 1])
        print_options(locations + ["Quit"])
        choice_2 = input("Which available dining hall?: ")
        if is_invalid(choice_2, len(locations) + 1):
            print()
            print("Please type a number from the menu!")
            print()
            continue
        choice_2 = int(choice_2)
        if choice_2 == len(locations) + 1:
            print()
            break

        #meal is built
        testMeal = Meal({})
        dishes = crawl_menu(get_menu_url(MEALS[choice - 1],
                                         locations[choice_2 - 1]),
                            red_meat=False,
                            fish=False)

        #user is given results: meals that meet the minimum are printed first
        #then, meals that are lopsided; there are stored in a list called non_winners
        non_winners = []
        #store a running list of meals to prevent the same meal from printing twice
        all_meals = []
        print()
        print()
        print("Meals that meet your minimum requirements:")
        print()
        for i in range(5):
            output = build_meal(dishes, TEST_LB, TEST_UB)
            if isinstance(output, str):
                print(output)
                break
            meal = output[0]
            found_winner = output[1]
            if found_winner:
                if set(meal.items.keys()) in all_meals:
                    continue
                print(meal)
                print(meal.meal_score())
                print()
                all_meals.append(set(meal.items.keys()))
            else:
                non_winners.append(meal)
            # if not isinstance(meal,str):
            # 	print(meal.meal_score())
        print("Meals that are slightly lopsided:")
        print()
        for meal in non_winners:
            if set(meal.items.keys()) in all_meals:
                continue
            print(meal)
            print(meal.meal_score())
            print()
            all_meals.append(set(meal.items.keys()))