Skip to content

Commit

Permalink
fix: handle both absolute and relative percent values for sub-ingredi…
Browse files Browse the repository at this point in the history
…ents (#6528)
  • Loading branch information
stephanegigandet authored Apr 1, 2022
1 parent bbf14bc commit 04bdb4e
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 24 deletions.
71 changes: 69 additions & 2 deletions lib/ProductOpener/Ingredients.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2332,16 +2332,80 @@ sub compute_ingredients_percent_values($$$) {
return $changed_total;
}


=head2 init_percent_values($total_min, $total_max, $ingredients_ref)
Initialize the percent, percent_min and percent_max value for each ingredient in list.
$ingredients_ref is the list of ingredients (as hash), where parsed percent are already set.
$total_min and $total_max might be set if we have a parent ingredient and are parsing a sub list.
When a percent is specifically set, use this value for percent_min and percent_max.
Warning: percent listed for sub-ingredients can be absolute (e.g. "Sugar, fruits 40% (pear 30%, apple 10%)")
or they can be relative to the parent ingredient (e.g. "Sugar, fruits 40% (pear 75%, apple 25%)".
We try to detect those cases and rescale the percent accordingly.
Otherwise use 0 for percent_min and total_max for percent_max.
=cut

sub init_percent_values($$$) {

my $total_min = shift;
my $total_max = shift;
my $ingredients_ref = shift;

# Determine if percent listed are absolute (default) or relative to a parent ingredient

my $percent_mode = "absolute";

# Assume that percent listed is relative to the parent ingredient
# if the sum of specified percents for the ingredients is greater than the percent max of the parent.

my $percent_sum = 0;
foreach my $ingredient_ref (@{$ingredients_ref}) {
if (defined $ingredient_ref->{percent}) {
$percent_sum += $ingredient_ref->{percent};
}
}

if ($percent_sum > $total_max) {
$percent_mode = "relative";
}

$log->debug("init_percent_values - percent mode", { percent_mode => $percent_mode, ingredients_ref => $ingredients_ref,
total_min => $total_min, total_max => $total_max, percent_sum => $percent_sum }) if $log->is_debug();

# Go through each ingredient to set percent_min, percent_max, and if we can an absolute percent

foreach my $ingredient_ref (@{$ingredients_ref}) {
if (defined $ingredient_ref->{percent}) {
$ingredient_ref->{percent_min} = $ingredient_ref->{percent};
$ingredient_ref->{percent_max} = $ingredient_ref->{percent};
# There is a specified percent for the ingredient.

if (($percent_mode eq "absolute") or ($total_min == $total_max)) {
# We can assign an absolute percent to the ingredient because
# 1. the percent mode is absolute
# or 2. we have a specific percent for the parent ingredient
# so we can rescale the relative percent of the ingredient to make it absolute
my $percent = ($percent_mode eq "absolute") ?
$ingredient_ref->{percent} :
$ingredient_ref->{percent} * $total_max / 100
;
$ingredient_ref->{percent} = $percent;
$ingredient_ref->{percent_min} = $percent;
$ingredient_ref->{percent_max} = $percent;
}
else {
# The percent mode is relative and we do not have a specific percent for the parent ingredient
# We cannot compute an absolute percent for the ingredient, but we can apply the relative percent
# to percent_min and percent_max
$ingredient_ref->{percent_min} = $ingredient_ref->{percent} * $total_min / 100;
$ingredient_ref->{percent_max} = $ingredient_ref->{percent} * $total_max / 100;
# The absolute percent is unknown, delete it
delete $ingredient_ref->{percent};
}
}
else {
if (not defined $ingredient_ref->{percent_min}) {
Expand All @@ -2353,9 +2417,12 @@ sub init_percent_values($$$) {
}
}

$log->debug("init_percent_values - result", { ingredients_ref => $ingredients_ref }) if $log->is_debug();

return;
}


sub set_percent_max_values($$$) {

my $total_min = shift;
Expand Down
19 changes: 8 additions & 11 deletions t/expected_test_results/ingredients/fi-additives-percents.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,28 @@
"ingredients" : [
{
"id" : "en:cocoa-butter",
"percent" : 15,
"percent_estimate" : 15,
"percent_estimate" : 22,
"text" : "kaakaovoi",
"vegan" : "yes",
"vegetarian" : "yes"
},
{
"id" : "en:sugar",
"percent" : 10,
"percent_estimate" : 10,
"percent_estimate" : 11,
"text" : "sokeri",
"vegan" : "yes",
"vegetarian" : "yes"
},
{
"id" : "en:milk-proteins",
"percent_estimate" : 9.5,
"percent_estimate" : 5.5,
"text" : "maitoproteiini",
"vegan" : "no",
"vegetarian" : "yes"
},
{
"id" : "en:chicken-egg",
"percent" : 1,
"percent_estimate" : 9.5,
"percent_estimate" : 5.5,
"text" : "kananmuna",
"vegan" : "no",
"vegetarian" : "yes"
Expand Down Expand Up @@ -246,10 +243,10 @@
"en:e338"
],
"ingredients_text" : "jauho (12%), suklaa (kaakaovoi (15%), sokeri [10%], maitoproteiini, kananmuna 1%) - emulgointiaineet : E463, E432 ja E472 - happamuudensäätöaineet : E322/E333 E474-E475, happo (sitruunahappo, fosforihappo) - suola",
"ingredients_with_specified_percent_n" : 4,
"ingredients_with_specified_percent_sum" : 38,
"ingredients_with_unspecified_percent_n" : 11,
"ingredients_with_unspecified_percent_sum" : 53.5,
"ingredients_with_specified_percent_n" : 1,
"ingredients_with_specified_percent_sum" : 12,
"ingredients_with_unspecified_percent_n" : 14,
"ingredients_with_unspecified_percent_sum" : 88,
"known_ingredients_n" : 25,
"lc" : "fi",
"nutriments" : {
Expand Down
19 changes: 8 additions & 11 deletions t/expected_test_results/ingredients/fr-chocolate-cake.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,28 @@
"ingredients" : [
{
"id" : "en:cocoa-butter",
"percent" : 15,
"percent_estimate" : 15,
"percent_estimate" : 22,
"text" : "beurre de cacao",
"vegan" : "yes",
"vegetarian" : "yes"
},
{
"id" : "en:sugar",
"percent" : 10,
"percent_estimate" : 10,
"percent_estimate" : 11,
"text" : "sucre",
"vegan" : "yes",
"vegetarian" : "yes"
},
{
"id" : "en:milk-proteins",
"percent_estimate" : 9.5,
"percent_estimate" : 5.5,
"text" : "protéines de lait",
"vegan" : "no",
"vegetarian" : "yes"
},
{
"id" : "en:egg",
"percent" : 1,
"percent_estimate" : 9.5,
"percent_estimate" : 5.5,
"text" : "oeuf",
"vegan" : "no",
"vegetarian" : "yes"
Expand Down Expand Up @@ -244,10 +241,10 @@
"en:e338"
],
"ingredients_text" : "farine (12%), chocolat (beurre de cacao (15%), sucre [10%], protéines de lait, oeuf 1%) - émulsifiants : E463, E432 et E472 - correcteurs d'acidité : E322/E333 E474-E475, acidifiant (acide citrique, acide phosphorique) - sel",
"ingredients_with_specified_percent_n" : 4,
"ingredients_with_specified_percent_sum" : 38,
"ingredients_with_unspecified_percent_n" : 11,
"ingredients_with_unspecified_percent_sum" : 53.5,
"ingredients_with_specified_percent_n" : 1,
"ingredients_with_specified_percent_sum" : 12,
"ingredients_with_unspecified_percent_n" : 14,
"ingredients_with_unspecified_percent_sum" : 88,
"known_ingredients_n" : 24,
"lc" : "fr",
"nutriments" : {
Expand Down
Loading

0 comments on commit 04bdb4e

Please sign in to comment.