<<

NAME

ProductOpener::Nutriscore - compute the Nutriscore grade of a food product

SYNOPSIS

ProductOpener::Nutriscore is used to compute the Nutriscore score and grade of a food product.

    use ProductOpener::Nutriscore qw/:all/;

        my $nutriscore_data_ref = {
                # Nutrients
                energy =>  518, # in kJ
                sugars => 3,
                saturated_fat => 0.7,
                saturated_fat_ratio => 0.7 / 3 * 100,
                sodium => 0.61 / 2.5 * 1000,    # in mg, sodium = salt divided by 2.5
                fruits_vegetables_nuts_colza_walnut_olive_oils => 20,   # in %
                fiber => 2.2,
                proteins => 6.7,

                # The Nutri-Score computation is different for beverages, waters, cheeses and fats
                is_beverage => 1,
                is_water => 0,
                is_cheese => 0,
                is_fat => 1, # for 2021 version
                is_fat_oil_nuts_seed => 1, # for 2023 version
        }

        my ($nutriscore_score, $nutriscore_grade) = compute_nutriscore_score_and_grade(
                $nutriscore_data_ref
        );

        print "Rounded value for sugars: " . $nutriscore_data_ref->{sugars_value} . "\n";
        print "Points for sugars: " . $nutriscore_data_ref->{sugars_points}. "\n";

DESCRIPTION

The modules implements the Nutri-Score computation as defined by Santé publique France.

Input values for nutrients are rounded according to the Nutri-Score definition and added to the hash passed in parameter with the corresponding amount of positive or negative points.

FUNCTIONS

Note: a significantly different Nutri-Score algorithm has been published in 2022 and 2023 (respectively for foods and beverages).

The functions related to the previous algorithm will be suffixed with _2021, and functions for the new algorithm will be suffixed with _2023.

We will keep both algorithms for a transition period, and we will be able to remove the 2021 algorithm and related functions after.

compute_nutriscore_score_and_grade_2021( $nutriscore_data_ref )

Computes the Nutri-Score score and grade of a food product, and also returns the details of the points for each nutrient.

Arguments: $nutriscore_data_ref

Hash reference used for both input and output:

Input keys: data to compute Nutri-Score

The hash must contain values for the following keys:

- energy -> energy in kJ / 100g or 100ml - sugars -> sugars in g / 100g or 100ml - saturated_fat -> saturated fats in g / 100g or 100ml - saturated_fat_ratio -> saturated fat divided by fat * 100 (in %) - sodium -> sodium in mg / 100g or 100ml (if sodium is computed from salt, it needs to use a sodium = salt / 2.5 conversion factor - fruits_vegetables_nuts_colza_walnut_olive_oils -> % of fruits, vegetables, nuts, and colza / walnut / olive oils - fiber -> fiber in g / 100g or 100ml - proteins -> proteins in g / 100g or 100ml

The values will be rounded according to the Nutri-Score rules, they do not need to be rounded before being passed as arguments.

If the product is a beverage, water, cheese, or fat, it must contain a positive value for the corresponding keys: - is_beverage - is_water - is_cheese - is_fat

Output keys: details of the Nutri-Score computation

Returned values:

- [nutrient]_value -> rounded values for each nutrient according to the Nutri-Score rules - [nutrient]_points -> points for each nutrient - negative_points -> sum of negative nutrients points - positive_points -> sum of positive nutrients points

The nutrients that are counted for the negative and positive points depend on the product type (if it is a beverage, cheese or fat) and on the values for some of the nutrients.

Return values

The function returns a list of 2 values:

- Nutri-Score score from -15 to 40 - Corresponding Nutri-Score letter grade from a to e (in lowercase)

The letter grade depends on the score and on whether the product is a beverage, or is a water.

get_value_with_one_less_negative_point_2021 ( $nutriscore_data_ref, $nutrient )

For a given Nutri-Score nutrient value, return the highest smaller value that would result in less negative points. e.g. for a sugars value of 15 (which gives 3 points), return 13.5 (which gives 2 points).

The value corresponds to the highest smaller threshold.

Return undef is the input nutrient value already gives the minimum amount of points (0).

get_value_with_one_more_positive_point_2021 ( $nutriscore_data_ref, $nutrient )

For a given Nutri-Score nutrient value, return the smallest higher value that would result in more positive points. e.g. for a proteins value of 2.0 (which gives 1 point), return 3.3 (which gives 2 points)

The value correspond to the smallest higher threshold + 1 increment so that it strictly greater than the threshold.

Return undef is the input nutrient value already gives the maximum amount of points.

compute_nutriscore_score_and_grade_2023( $nutriscore_data_ref )

Computes the Nutri-Score score and grade of a food product, and also returns the details of the points for each nutrient.

Arguments: $nutriscore_data_ref

Hash reference used for both input and output:

Input keys: data to compute Nutri-Score

The hash must contain values for the following keys:

- energy -> energy in kJ / 100g or 100ml - sugars -> sugars in g / 100g or 100ml - saturated_fat -> saturated fats in g / 100g or 100ml - saturated_fat_ratio -> saturated fat divided by fat * 100 (in %) - sodium -> sodium in mg / 100g or 100ml (if sodium is computed from salt, it needs to use a sodium = salt / 2.5 conversion factor - fruits_vegetables_nuts_colza_walnut_olive_oils -> % of fruits, vegetables, nuts, and colza / walnut / olive oils - fiber -> fiber in g / 100g or 100ml - proteins -> proteins in g / 100g or 100ml

The values will be rounded according to the Nutri-Score rules, they do not need to be rounded before being passed as arguments.

If the product is a beverage, water, cheese, or fat, it must contain a positive value for the corresponding keys: - is_beverage - is_water - is_cheese - is_fat_oil_nuts_seeds

Output keys: details of the Nutri-Score computation

Returned values:

- [nutrient]_value -> rounded values for each nutrient according to the Nutri-Score rules - [nutrient]_points -> points for each nutrient - negative_nutrients -> list of nutrients that are counted in negative points - negative_points -> sum of negative nutrients points - positive_nutrients -> list of nutrients that are counted in positive points - positive_points -> sum of positive nutrients points - count_proteins -> indicates if proteins are counted in the positive points - count_proteins_reason -> indicates why proteins are counted

The nutrients that are counted for the negative and positive points depend on the product type (if it is a beverage, cheese or fat) and on the values for some of the nutrients.

Return values

The function returns a list of 2 values:

- Nutri-Score score from -15 to 40 - Corresponding Nutri-Score letter grade from a to e (in lowercase)

The letter grade depends on the score and on whether the product is a beverage, or is a water.

get_value_with_one_less_negative_point_2023 ($is_beverage, $nutrient, $current_value)

For a given Nutri-Score nutrient value, return the highest smaller value that would result in less negative points. e.g. for a sugars value of 15 (which gives 3 points), return 13.5 (which gives 2 points).

The value corresponds to the highest smaller threshold.

Return undef if the input nutrient value already gives the minimum amount of points (0).

get_value_with_one_more_positive_point_2023 ($is_beverage, $nutrient, $current_value)

For a given Nutri-Score nutrient value, return the smallest higher value that would result in more positive points. e.g. for a proteins value of 2.0 (which gives 1 point), return 3.3 (which gives 2 points)

The value corresponds to the smallest higher threshold + 1 increment so that it strictly greater than the threshold.

Return undef if the input nutrient value already gives the maximum amount of points.

<<