Пример #1
0
def search(words):
    """Searches foods for input"""
    from fuzzywuzzy import fuzz  # pylint: disable=import-outside-toplevel

    food_des = _sql("SELECT * FROM food_des;")

    query = " ".join(words)
    scores = {f[0]: fuzz.token_set_ratio(query, f[2]) for f in food_des}
    scores = sorted(scores.items(), key=lambda x: x[1],
                    reverse=True)[:SEARCH_LIMIT]

    food_ids = [s[0] for s in scores]
    nut_data = sql_analyze_foods(food_ids)

    # Tally foods
    foods_nutrients = {}
    for food_id, nutr_id, nutr_val in nut_data:
        if food_id not in foods_nutrients:
            foods_nutrients[food_id] = {nutr_id: nutr_val}  # init dict
        else:
            foods_nutrients[food_id][nutr_id] = nutr_val

    def search_results(_scores):
        """Generates search results, consumable by tabulate"""
        _results = []
        for score in _scores:
            _food_id = score[0]
            score = score[1]

            food = food_des[_food_id]
            fdgrp_id = food[1]
            long_desc = food[2]
            shrt_desc = food[3]

            nutrients = foods_nutrients[_food_id]
            result = {
                "food_id": _food_id,
                "fdgrp_id": fdgrp_id,
                # TODO: get more details from another function, maybe enhance food_details() ?
                # "fdgrp_desc": cache.fdgrp[fdgrp_id]["fdgrp_desc"],
                # "data_src": cache.data_src[data_src_id]["name"],
                "long_desc": shrt_desc if shrt_desc else long_desc,
                "score": score,
                "nutrients": nutrients,
            }
            _results.append(result)
        return _results

    # TODO: include C/F/P macro ratios as column?
    food_des = {f[0]: f for f in food_des}
    results = search_results(scores)

    tabulate_search(results)
Пример #2
0
def test_1_usda_sql_funcs():
    """Performs cursory inspection (sanity checks) of usda.sqlite image"""
    version = usda_ver()
    assert version == __db_target_usda__
    result = usda_funcs.sql_nutrients_details()
    assert len(result[1]) == 186

    result = usda_funcs.sql_servings([9050, 9052])
    assert len(result) == 3

    result = usda_funcs.sql_analyze_foods([23567, 23293])
    assert len(result) == 188

    result = usda_funcs.sql_sort_foods(789)
    assert len(result) == 415
    # result = usda_funcs.sql_sort_foods(789, fdgrp_ids=[100])
    # assert len(result) == 1

    result = usda_funcs.sql_sort_foods_by_kcal(789)
    assert len(result) == 246
Пример #3
0
def recipe_overview(recipe_id):
    """Shows single recipe overview"""
    recipe = sql_analyze_recipe(recipe_id)
    name = recipe[0][1]
    print(name)

    food_ids = {x[2]: x[3] for x in recipe}
    food_names = {x[0]: x[3] for x in sql_food_details(food_ids.keys())}
    food_analyses = sql_analyze_foods(food_ids.keys())

    table = tabulate(
        [[food_names[food_id], grams] for food_id, grams in food_ids.items()],
        headers=["food", "g"],
    )
    print(table)
    # tabulate nutrient RDA %s
    nutrients = sql_nutrients_overview()
    # rdas = {x[0]: x[1] for x in nutrients.values()}
    progbars = nutprogbar(food_ids, food_analyses, nutrients)
    print(progbars)

    return recipe
Пример #4
0
def foods_analyze(food_ids, grams=None):
    """Analyze a list of food_ids against stock RDA values"""
    # TODO: from ntclient.utils.nutprogbar import nutprogbar
    # Get analysis
    raw_analyses = sql_analyze_foods(food_ids)
    analyses = {}
    for analysis in raw_analyses:
        food_id = analysis[0]
        if grams is not None:
            anl = (analysis[1], round(analysis[2] * grams / 100, 2))
        else:
            anl = (analysis[1], analysis[2])
        if food_id not in analyses:
            analyses[food_id] = [anl]
        else:
            analyses[food_id].append(anl)
    # serving = servings()[1]
    serving = sql_servings(food_ids)
    food_des = sql_food_details(food_ids)
    food_des = {x[0]: x for x in food_des}
    nutrients = sql_nutrients_overview()
    rdas = {x[0]: x[1] for x in nutrients.values()}

    # --------------------------------------
    # Food-by-food analysis (w/ servings)
    # --------------------------------------
    servings_tables = []
    nutrients_tables = []
    for food_id in analyses:
        food_name = food_des[food_id][2]
        # food_name = food["long_desc"]
        print("\n======================================\n" +
              "==> {0} ({1})\n".format(food_name, food_id) +
              "======================================\n")
        print(
            "\n=========================\nSERVINGS\n=========================\n"
        )

        ###############
        # Serving table
        headers = ["msre_id", "msre_desc", "grams"]
        # Copy obj with dict(x)
        rows = [(x[1], x[2], x[3]) for x in serving if x[0] == food_id]
        # for r in rows:
        #     r.pop("food_id")
        # Print table
        servings_table = tabulate(rows, headers=headers, tablefmt="presto")
        print(servings_table)
        servings_tables.append(servings_table)

        refuse = next(((x[7], x[8])
                       for x in food_des.values() if x[0] == food_id and x[7]),
                      None)
        if refuse:
            print(
                "\n=========================\nREFUSE\n=========================\n"
            )
            print(refuse[0])
            print("    ({0}%, by mass)".format(refuse[1]))

        print(
            "\n=========================\nNUTRITION\n=========================\n"
        )

        ################
        # Nutrient table
        headers = ["id", "nutrient", "rda", "amount", "units"]
        rows = []
        # food_nutes = {x["nutr_id"]: x for x in food["nutrients"]}
        # for id, nute in food_nutes.items():
        for food_id_2, amount in analyses[food_id]:
            # Skip zero values
            # amount = food_nutes[id]["nutr_val"]
            if not amount:
                continue

            nutr_desc = (nutrients[food_id_2][4] if nutrients[food_id_2][4]
                         else nutrients[food_id_2][3])
            unit = nutrients[food_id_2][2]

            # Insert RDA % into row
            if rdas[food_id_2]:
                rda_perc = str(round(amount / rdas[food_id_2] * 100, 1)) + "%"
            else:
                # print(rdas[id])
                rda_perc = None
            row = [food_id_2, nutr_desc, rda_perc, round(amount, 2), unit]

            rows.append(row)

        # Print table
        table = tabulate(rows, headers=headers, tablefmt="presto")
        print(table)
        nutrients_tables.append(table)

    return nutrients_tables, servings_tables
Пример #5
0
def day_analyze(day_csv_paths, rda_csv_path=None, debug=False):
    """Analyze a day optionally with custom RDAs,
    e.g.  nutra day ~/.nutra/rocky.csv -r ~/.nutra/dog-rdas-18lbs.csv
    TODO: Should be a subset of foods_analyze
    """
    if rda_csv_path is not None:
        with open(rda_csv_path) as file_path:
            rda_csv_input = csv.DictReader(row for row in file_path
                                           if not row.startswith("#"))
            rdas = list(rda_csv_input)
    else:
        rdas = []

    logs = []
    food_ids = set()
    for day_csv_path in day_csv_paths:
        with open(day_csv_path) as file_path:
            rows = [row for row in file_path if not row.startswith("#")]
            day_csv_input = csv.DictReader(rows)
            log = list(day_csv_input)
        for entry in log:
            if entry["id"]:
                food_ids.add(int(entry["id"]))
        logs.append(log)

    # Inject user RDAs
    nutrients = [tuple(x) for x in sql_nutrients_overview().values()]
    for rda in rdas:
        nutrient_id = int(rda["id"])
        _rda = float(rda["rda"])
        for nutrient in nutrients:
            if nutrient[0] == nutrient_id:
                nutrient[1] = _rda
                if debug:
                    substr = "{0} {1}".format(_rda, nutrient[2]).ljust(12)
                    print("INJECT RDA: {0} -->  {1}".format(
                        substr, nutrient[4]))
    nutrients = {x[0]: x for x in nutrients}

    # Analyze foods
    foods_analysis = {}
    for food in sql_analyze_foods(food_ids):
        food_id = food[0]
        anl = food[1], food[2]
        if food_id not in foods_analysis:
            foods_analysis[food_id] = [anl]
        else:
            foods_analysis[food_id].append(anl)

    # Compute totals
    nutrients_totals = []
    for log in logs:
        nutrient_totals = OrderedDict()
        for entry in log:
            if entry["id"]:
                food_id = int(entry["id"])
                grams = float(entry["grams"])
                for nutrient in foods_analysis[food_id]:
                    nutr_id = nutrient[0]
                    nutr_per_100g = nutrient[1]
                    nutr_val = grams / 100 * nutr_per_100g
                    if nutr_id not in nutrient_totals:
                        nutrient_totals[nutr_id] = nutr_val
                    else:
                        nutrient_totals[nutr_id] += nutr_val
        nutrients_totals.append(nutrient_totals)

    #######
    # Print
    term_width = shutil.get_terminal_size()[0]
    buffer = term_width - 4 if term_width > 4 else term_width
    for analysis in nutrients_totals:
        day_format(analysis, nutrients, buffer=buffer)
    return nutrients_totals