Skip to content

Commit

Permalink
feat: Improvements to Nutri-Score panel, remove extended Eco-Score pa…
Browse files Browse the repository at this point in the history
…nel (#6748)

* record and display all missing data for Nutri-Score and not only the first one #6532

* remove extended ecosore panel #6678, always display nutriscore panel even if not computed #6585

* update tests

* update tests

* update tests

* update tests, ignore compared_to_category

* update tests

* remove obsolete index dir (moved to data/categories_stats)
  • Loading branch information
stephanegigandet committed May 10, 2022
1 parent 41c8a9e commit 37c76c1
Show file tree
Hide file tree
Showing 40 changed files with 311 additions and 180 deletions.
Binary file removed index/categories_nutriments_per_country.world.sto
Binary file not shown.
10 changes: 8 additions & 2 deletions lib/ProductOpener/Display.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8853,8 +8853,14 @@ sub data_to_display_nutriscore_and_nutrient_levels($) {
# Missing nutrition facts?
if (has_tag($product_ref,"misc","en:nutriscore-missing-nutrition-data")) {
push @nutriscore_warnings, lang("nutriscore_missing_nutrition_data");
$result_data_ref->{nutriscore_unknown_reason} = "missing_nutrition_data"; # Takes precedence if the category is also missing
$result_data_ref->{nutriscore_unknown_reason_short} = lang("nutriscore_missing_nutrition_data_short");
if (not has_tag($product_ref,"misc","en:nutriscore-missing-category")) {
$result_data_ref->{nutriscore_unknown_reason} = "missing_nutrition_data";
$result_data_ref->{nutriscore_unknown_reason_short} = lang("nutriscore_missing_nutrition_data_short");
}
else {
$result_data_ref->{nutriscore_unknown_reason} = "missing_category_and_nutrition_data";
$result_data_ref->{nutriscore_unknown_reason_short} = lang("nutriscore_missing_category_and_nutrition_data_short");
}
}
}
}
Expand Down
51 changes: 30 additions & 21 deletions lib/ProductOpener/Food.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1472,13 +1472,22 @@ my %fruits_vegetables_nuts_by_category = (
my @fruits_vegetables_nuts_by_category_sorted = sort { $fruits_vegetables_nuts_by_category{$b} <=> $fruits_vegetables_nuts_by_category{$a} } keys %fruits_vegetables_nuts_by_category;


=head2 compute_nutrition_score( $product_ref )
Determines if we have enough data to compute the Nutri-Score (category + nutrition facts),
and if the Nutri-Score is applicable to the product the category.
Populates the data structure needed to commpute the Nutri-Score and computes it.
=cut

sub compute_nutrition_score($) {

my $product_ref = shift;

# Initialize values

delete $product_ref->{nutrition_score_debug};
$product_ref->{nutrition_score_debug} = '';
delete $product_ref->{nutriments}{"nutrition-score"};
delete $product_ref->{nutriments}{"nutrition-score_100g"};
delete $product_ref->{nutriments}{"nutrition-score_serving"};
Expand All @@ -1504,28 +1513,23 @@ sub compute_nutrition_score($) {
delete $product_ref->{nutriscore_data};
delete $product_ref->{nutriscore_points};

defined $product_ref->{misc_tags} or $product_ref->{misc_tags} = [];

$product_ref->{misc_tags} = ["en:nutriscore-not-computed"];

my $prepared = '';

# do not compute a score when we don't have a category
if ((not defined $product_ref->{categories}) or ($product_ref->{categories} eq '')) {
$product_ref->{"nutrition_grades_tags"} = [ "unknown" ];
$product_ref->{nutrition_score_debug} = "no score when the product does not have a category";
$product_ref->{nutrition_score_debug} = "no score when the product does not have a category" . " - ";;
add_tag($product_ref,"misc","en:nutriscore-missing-category");
return;
}

if (not defined $product_ref->{nutrition_score_beverage}) {
$product_ref->{"nutrition_grades_tags"} = [ "unknown" ];
$product_ref->{nutrition_score_debug} = "did not determine if it was a beverage";
$product_ref->{nutrition_score_debug} = "did not determine if it was a beverage" . " - ";;
add_tag($product_ref,"misc","en:nutriscore-beverage-status-unknown");
return;
}


# do not compute a score for dehydrated products to be rehydrated (e.g. dried soups, powder milk)
# unless we have nutrition data for the prepared product
# same for en:chocolate-powders, en:dessert-mixes and en:flavoured-syrups
Expand All @@ -1535,16 +1539,15 @@ sub compute_nutrition_score($) {
if (has_tag($product_ref, "categories", $category_tag)) {

if ((defined $product_ref->{nutriments}{"energy_prepared_100g"})) {
$product_ref->{nutrition_score_debug} = "using prepared product data for category $category_tag";
$product_ref->{nutrition_score_debug} = "using prepared product data for category $category_tag" . " - ";;
$prepared = '_prepared';
last;
}
else {
$product_ref->{"nutrition_grades_tags"} = [ "unknown" ];
$product_ref->{nutrition_score_debug} = "no score for category $category_tag without data for prepared product";
$product_ref->{nutrition_score_debug} = "no score for category $category_tag without data for prepared product" . " - ";;
add_tag($product_ref,"misc","en:nutriscore-missing-prepared-nutrition-data");
return;
}
last;
}
}

Expand All @@ -1569,8 +1572,8 @@ sub compute_nutrition_score($) {
if (has_tag($product_ref, "categories", $category_id)) {
$product_ref->{"nutrition_grades_tags"} = [ "not-applicable" ];
add_tag($product_ref,"misc","en:nutriscore-not-applicable");
$product_ref->{nutrition_score_debug} = "no nutriscore for category $category_id";
return;
$product_ref->{nutrition_score_debug} = "no nutriscore for category $category_id" . " - ";;
last;
}
}
}
Expand All @@ -1589,14 +1592,10 @@ sub compute_nutrition_score($) {
foreach my $nid ("energy", "fat", "saturated-fat", "sugars", "sodium", "proteins") {
if (not defined $product_ref->{nutriments}{$nid . $prepared . "_100g"}) {
$product_ref->{"nutrition_grades_tags"} = [ "unknown" ];
push @{$product_ref->{misc_tags}}, "en:nutrition-not-enough-data-to-compute-nutrition-score";
if (not defined $product_ref->{nutriments}{"saturated-fat" . $prepared . "_100g"}) {
push @{$product_ref->{misc_tags}}, "en:nutrition-no-saturated-fat";
}
$product_ref->{nutrition_score_debug} .= "missing " . $nid . $prepared;
add_tag($product_ref,"misc","en:nutrition-not-enough-data-to-compute-nutrition-score");
$product_ref->{nutrition_score_debug} .= "missing " . $nid . $prepared . " - ";
add_tag($product_ref,"misc","en:nutriscore-missing-nutrition-data");
add_tag($product_ref,"misc","en:nutriscore-missing-nutrition-data-$nid");
return;
}
}

Expand All @@ -1607,10 +1606,20 @@ sub compute_nutrition_score($) {
and (not defined $product_ref->{nutriments}{"fiber" . $prepared . "_modifier"})
and not (has_tag($product_ref, "categories", "en:sodas"))) {
$product_ref->{nutrition_score_warning_no_fiber} = 1;
push @{$product_ref->{misc_tags}}, "en:nutrition-no-fiber";
add_tag($product_ref,"misc","en:nutrition-no-fiber");
}
}

# Remove ending -
$product_ref->{nutrition_score_debug} =~ s/ - $//;

# If the Nutri-Score is unknown or not applicable, exit the function
if ((defined $product_ref->{"nutrition_grades_tags"})
and (($product_ref->{"nutrition_grades_tags"}[0] eq "unknown")
or ($product_ref->{"nutrition_grades_tags"}[0] eq "not-applicable"))) {
return;
}

if ($prepared ne '') {
push @{$product_ref->{misc_tags}}, "en:nutrition-grade-computed-for-prepared-product";
}
Expand Down
34 changes: 15 additions & 19 deletions lib/ProductOpener/KnowledgePanels.pm
Original file line number Diff line number Diff line change
Expand Up @@ -522,18 +522,20 @@ sub create_ecoscore_panel($$$) {

# Create an extra panel for products that have extended ecoscore data from the impact estimator

if (defined $product_ref->{ecoscore_extended_data}) {
# 2022/05/06: disabled as we currently have few products with reliable extended ecoscore data

extract_data_from_impact_estimator_best_recipe($product_ref, $panel_data_ref);
# if (defined $product_ref->{ecoscore_extended_data}) {

compare_impact_estimator_data_to_category_average($product_ref, $panel_data_ref, $target_cc);
# extract_data_from_impact_estimator_best_recipe($product_ref, $panel_data_ref);

# Display a panel only if we can compare the product extended impact
if (defined $panel_data_ref->{ecoscore_extended_data_for_category}) {
create_panel_from_json_template("ecoscore_extended", "api/knowledge-panels/environment/ecoscore/ecoscore_extended.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);
}
}
# compare_impact_estimator_data_to_category_average($product_ref, $panel_data_ref, $target_cc);

# # Display a panel only if we can compare the product extended impact
# if (defined $panel_data_ref->{ecoscore_extended_data_for_category}) {
# create_panel_from_json_template("ecoscore_extended", "api/knowledge-panels/environment/ecoscore/ecoscore_extended.tt.json",
# $panel_data_ref, $product_ref, $target_lc, $target_cc);
# }
# }

create_panel_from_json_template("carbon_footprint", "api/knowledge-panels/environment/carbon_footprint.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);
Expand Down Expand Up @@ -784,17 +786,11 @@ sub create_nutriscore_panel($$$) {

my $panel_data_ref = data_to_display_nutriscore_and_nutrient_levels($product_ref);

# Do not display the Nutri-Score panel if it is not applicable
if ((not $panel_data_ref->{do_not_display})
and (not $panel_data_ref->{nutriscore_grade} eq "not-applicable")) {

$panel_data_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_" . $panel_data_ref->{nutriscore_grade} . "_description_short");
$panel_data_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_" . $panel_data_ref->{nutriscore_grade} . "_description_short");

# Nutri-Score panel: score + details
create_panel_from_json_template("nutriscore", "api/knowledge-panels/health/nutriscore/nutriscore.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);

}
# Nutri-Score panel: score + details
create_panel_from_json_template("nutriscore", "api/knowledge-panels/health/nutriscore/nutriscore.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);
}


Expand Down
10 changes: 7 additions & 3 deletions lib/ProductOpener/Tags.pm
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ sub is_a($$$) {
}



sub add_tag($$$) {

my $product_ref = shift;
Expand All @@ -365,14 +366,14 @@ sub add_tag($$$) {
(defined $product_ref->{$tagtype . "_tags"}) or $product_ref->{$tagtype . "_tags"} = [];
foreach my $existing_tagid (@{$product_ref->{$tagtype . "_tags"}}) {
if ($tagid eq $existing_tagid) {
return;
return 0;
}
}
push @{$product_ref->{$tagtype . "_tags"}}, $tagid;

return;
return 1;
}


sub remove_tag($$$) {

my $product_ref = shift;
Expand All @@ -388,6 +389,9 @@ sub remove_tag($$$) {
if ($tag ne $tagid) {
push @{$product_ref->{$tagtype . "_tags_new"}}, $tag;
}
else {
$return = 1;
}
}
$product_ref->{$tagtype . "_tags"} = $product_ref->{$tagtype . "_tags_new"};
delete $product_ref->{$tagtype . "_tags_new"};
Expand Down
1 change: 1 addition & 0 deletions lib/ProductOpener/Test.pm
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ sub normalize_product_for_test_comparison($) {
my $product = shift;
# fields we don't want to check for they vary from test to test
# stars means there is a table of elements and we want to run through all (hash not supported yet)
# compared_to_category: depends on which products have been aggregated in index/categories_nutriments_per_country.world.sto
my @fields_ignore_content = qw(
last_modified_t created_t owner_fields
entry_dates_tags last_edit_dates_tags
Expand Down
8 changes: 8 additions & 0 deletions po/common/common.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5924,6 +5924,10 @@ msgctxt "nutriscore_missing_nutrition_data"
msgid "The nutrition facts of the product must be specified in order to compute the Nutri-Score."
msgstr "The nutrition facts of the product must be specified in order to compute the Nutri-Score."

msgctxt "nutriscore_missing_category_and_nutrition_data"
msgid "The category and the nutrition facts of the product must be specified in order to compute the Nutri-Score."
msgstr "The category and the nutrition facts of the product must be specified in order to compute the Nutri-Score."

msgctxt "health"
msgid "Health"
msgstr "Health"
Expand Down Expand Up @@ -5980,6 +5984,10 @@ msgctxt "nutriscore_missing_nutrition_data_short"
msgid "Missing nutrition facts"
msgstr "Missing nutrition facts"

msgctxt "nutriscore_missing_category_and_nutrition_data_short"
msgid "Missing category and nutrition facts"
msgstr "Missing category and nutrition facts"

msgctxt "recommendation_who_reduce_or_stop_drinking_alcohol_title"
msgid "Reduce or stop drinking alcohol"
msgstr "Reduce or stop drinking alcohol"
Expand Down
8 changes: 8 additions & 0 deletions po/common/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -5946,6 +5946,10 @@ msgctxt "nutriscore_missing_nutrition_data"
msgid "The nutrition facts of the product must be specified in order to compute the Nutri-Score."
msgstr "The nutrition facts of the product must be specified in order to compute the Nutri-Score."

msgctxt "nutriscore_missing_category_and_nutrition_data"
msgid "The category and the nutrition facts of the product must be specified in order to compute the Nutri-Score."
msgstr "The category and the nutrition facts of the product must be specified in order to compute the Nutri-Score."

msgctxt "health"
msgid "Health"
msgstr "Health"
Expand Down Expand Up @@ -6002,6 +6006,10 @@ msgctxt "nutriscore_missing_nutrition_data_short"
msgid "Missing nutrition facts"
msgstr "Missing nutrition facts"

msgctxt "nutriscore_missing_category_and_nutrition_data_short"
msgid "Missing category and nutrition facts"
msgstr "Missing category and nutrition facts"

msgctxt "recommendation_who_reduce_or_stop_drinking_alcohol_title"
msgid "Reduce or stop drinking alcohol"
msgstr "Reduce or stop drinking alcohol"
Expand Down
1 change: 1 addition & 0 deletions t/expected_test_results/attributes/en-attributes.json
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@
"c"
],
"nutrition_score_beverage" : 0,
"nutrition_score_debug" : "",
"nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1,
"nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 0,
"other_nutritional_substances_tags" : [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,9 +745,14 @@
"misc_tags" : [
"en:nutriscore-not-computed",
"en:nutrition-not-enough-data-to-compute-nutrition-score",
"en:nutrition-no-saturated-fat",
"en:nutriscore-missing-nutrition-data",
"en:nutriscore-missing-nutrition-data-energy",
"en:nutriscore-missing-nutrition-data-fat",
"en:nutriscore-missing-nutrition-data-saturated-fat",
"en:nutriscore-missing-nutrition-data-sugars",
"en:nutriscore-missing-nutrition-data-sodium",
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
"en:ecoscore-extended-data-not-computed",
"en:ecoscore-missing-data-warning",
"en:ecoscore-missing-data-labels",
Expand All @@ -769,7 +774,8 @@
"unknown"
],
"nutrition_score_beverage" : 0,
"nutrition_score_debug" : "missing energy",
"nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins",
"nutrition_score_warning_no_fiber" : 1,
"other_nutritional_substances_tags" : [],
"packagings" : [],
"pnns_groups_1" : "unknown",
Expand Down
10 changes: 8 additions & 2 deletions t/expected_test_results/attributes/en-maybe-vegan.json
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,14 @@
"misc_tags" : [
"en:nutriscore-not-computed",
"en:nutrition-not-enough-data-to-compute-nutrition-score",
"en:nutrition-no-saturated-fat",
"en:nutriscore-missing-nutrition-data",
"en:nutriscore-missing-nutrition-data-energy",
"en:nutriscore-missing-nutrition-data-fat",
"en:nutriscore-missing-nutrition-data-saturated-fat",
"en:nutriscore-missing-nutrition-data-sugars",
"en:nutriscore-missing-nutrition-data-sodium",
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
"en:ecoscore-extended-data-not-computed",
"en:ecoscore-not-computed"
],
Expand Down Expand Up @@ -724,7 +729,8 @@
"unknown"
],
"nutrition_score_beverage" : 0,
"nutrition_score_debug" : "missing energy",
"nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins",
"nutrition_score_warning_no_fiber" : 1,
"other_nutritional_substances_tags" : [],
"packagings" : [],
"pnns_groups_1" : "unknown",
Expand Down
10 changes: 8 additions & 2 deletions t/expected_test_results/attributes/en-nova-groups-markers.json
Original file line number Diff line number Diff line change
Expand Up @@ -914,9 +914,14 @@
"misc_tags" : [
"en:nutriscore-not-computed",
"en:nutrition-not-enough-data-to-compute-nutrition-score",
"en:nutrition-no-saturated-fat",
"en:nutriscore-missing-nutrition-data",
"en:nutriscore-missing-nutrition-data-energy",
"en:nutriscore-missing-nutrition-data-fat",
"en:nutriscore-missing-nutrition-data-saturated-fat",
"en:nutriscore-missing-nutrition-data-sugars",
"en:nutriscore-missing-nutrition-data-sodium",
"en:nutriscore-missing-nutrition-data-proteins",
"en:nutrition-no-fiber",
"en:ecoscore-extended-data-not-computed",
"en:ecoscore-missing-data-warning",
"en:ecoscore-missing-data-labels",
Expand Down Expand Up @@ -983,7 +988,8 @@
"unknown"
],
"nutrition_score_beverage" : 0,
"nutrition_score_debug" : "missing energy",
"nutrition_score_debug" : "missing energy - missing fat - missing saturated-fat - missing sugars - missing sodium - missing proteins",
"nutrition_score_warning_no_fiber" : 1,
"other_nutritional_substances_tags" : [],
"packagings" : [],
"pnns_groups_1" : "Milk and dairy products",
Expand Down
1 change: 1 addition & 0 deletions t/expected_test_results/attributes/en-nutriscore.json
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,7 @@
"b"
],
"nutrition_score_beverage" : 0,
"nutrition_score_debug" : "",
"nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients" : 1,
"nutrition_score_warning_fruits_vegetables_nuts_estimate_from_ingredients_value" : 100,
"other_nutritional_substances_tags" : [],
Expand Down

0 comments on commit 37c76c1

Please sign in to comment.