Skip to content

Commit

Permalink
Harmonize usage of fruit, vegetables nuts and pulses
Browse files Browse the repository at this point in the history
  • Loading branch information
wvengen committed May 5, 2022
1 parent 7885507 commit 633f8a5
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 39 deletions.
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ was adopted in 2017 for use as a voluntary label on the packaging.
In 2018, Belgium and Spain adopted the same scheme.

Other countries are evaluating adopting the Nutri-Score as well, including
The Netherlands. There is also a
[European citizen's initiative](http://ec.europa.eu/citizens-initiative/public/initiatives/ongoing/details/2019/000008)
to adopt it Europe-wide.
The Netherlands. There was also a
[European citizen's initiative](http://ec.europa.eu/citizens-initiative/public/initiatives/ongoing/details/2019/000008_en)
to adopt it Europe-wide, but this has been withdrawn.

## Installation

Expand All @@ -39,27 +39,29 @@ gem install nutriscore
## Usage

The input for all nutritional scores are a product category and nutritional values.
Which nutrients are required depends on the product category.
Which nutrients are required depends on the product category. Note that `fvnp` stands
for the amount of fruits, vegetables, nuts and pulses (and, since Oct 2019, also
rapeseed, walnuts and olive oils).

```ruby
require 'nutriscore'

# Fruit fromage frais
product_a = {
energy: 459, # kJ/100g
fat_saturated: 1.8, # g/100g
sugar: 13.4, # g/100g
sodium: 0.1 / 1000, # g/100g
fruits_vegetables_nuts: 8, # g/100g (= weight-%)
fibres: 0.6, # g/100g
proteins: 6.5, # g/100g
energy: 459, # kJ/100g
fat_saturated: 1.8, # g/100g
sugar: 13.4, # g/100g
sodium: 0.1, # g/100g
fvnp: 8, # g/100g (= weight-%)
fibres: 0.6, # g/100g
proteins: 6.5, # g/100g
}

# Compute the french Nutri-Score for a generic product.
score = Nutriscore::FR::SpecificScore.new(product_a)
#<Nutriscore::FR::SpecificScore score=0
# positive_score=#<Nutriscore::FR::PositiveScore score=4
# fruits_vegetables_nuts=0 fibres=0 proteins=4>
# fvnp=0 fibres=0 proteins=4>
# negative_score=#<Nutriscore::FR::NegativeScore score=4
# energy=1 fat_saturated=1 sugar=2 sodium=0>>
score.score.single
Expand Down
6 changes: 3 additions & 3 deletions lib/nutriscore/fr/drinks_score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class DrinksScore < Nutriscore::Common::Score
include DrinksScoreClass

def self.nutrient_keys
[:energy, :sugar, :fruits_vegetables]
[:energy, :sugar, :fvnp]
end

def energy
Expand Down Expand Up @@ -45,10 +45,10 @@ def sugar
end
end

def fruits_vegetables
def fvnp
# the text mentions % but here we use g/100ml
# we'd need to either ask for %, ask for g/100g, or require a density ...
score_value(@nutrients.fruits_vegetables, 0..10) do |v|
score_value(@nutrients.fvnp, 0..10) do |v|
if v > 80 then 10
elsif v > 60 then 4
elsif v > 40 then 2
Expand Down
3 changes: 2 additions & 1 deletion lib/nutriscore/fr/negative_score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def fat_saturated
elsif v > 3 then 3
elsif v > 2 then 2
elsif v > 1 then 1
else 0
else 0
end
end
end
Expand All @@ -61,6 +61,7 @@ def sugar

def sodium
score_value(@nutrients.sodium, 0..10) do |v|
v *= 1000 if v # comparison is in mg/100g
if v > 900 then 10
elsif v > 810 then 9
elsif v > 720 then 8
Expand Down
6 changes: 3 additions & 3 deletions lib/nutriscore/fr/positive_score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ module FR
class PositiveScore < Nutriscore::Common::Score

def self.nutrient_keys
[:fruits_vegetables_nuts, :fibres, :proteins]
[:fvnp, :fibres, :proteins]
end

def fruits_vegetables_nuts
score_value(@nutrients.fruits_vegetables_nuts, 0..5) do |v|
def fvnp
score_value(@nutrients.fvnp, 0..5) do |v|
if v > 80 then 5
elsif v > 60 then 2
elsif v > 40 then 1
Expand Down
4 changes: 2 additions & 2 deletions lib/nutriscore/fr/specific_score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ module FR
# this is for general products
class SpecificScore < GeneralScore
def score
if @negative.score.min < 11 || @positive.fruits_vegetables_nuts.max >= 5
if @negative.score.min < 11 || @positive.fvnp.max >= 5
@negative.score - @positive.score
elsif @negative.score.max >= 11 && @positive.fruits_vegetables_nuts.min < 5
elsif @negative.score.max >= 11 && @positive.fvnp.min < 5
@negative.score - @positive.score_without_proteins
else
Range.new(
Expand Down
6 changes: 3 additions & 3 deletions lib/nutriscore/uk/positive_score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ def initialize(nutrients, fibres_method: :aoac, **opts)
end

def self.nutrient_keys
[:fruits_vegetables_nuts, :fibres, :proteins]
[:fvnp, :fibres, :proteins]
end

def fruits_vegetables_nuts
score_value(@nutrients.fruits_vegetables_nuts, 0..5) do |v|
def fvnp
score_value(@nutrients.fvnp, 0..5) do |v|
if v > 80 then 5
elsif v > 60 then 2
elsif v > 40 then 1
Expand Down
6 changes: 3 additions & 3 deletions lib/nutriscore/uk/specific_score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ module UK
class SpecificScore < GeneralScore
def score
# 'If a food or drink scores 11 or more ‘A’ points then it cannot score points for protein
# unless it also scores 5 points for fruit, vegetables and nuts.'
if @negative.score.min < 11 || @positive.fruits_vegetables_nuts.max >= 5
# unless it also scores 5 points for fruit, vegetables, nuts and pulses.'
if @negative.score.min < 11 || @positive.fvnp.max >= 5
@negative.score - @positive.score
elsif @negative.score.max >= 11 && @positive.fruits_vegetables_nuts.min < 5
elsif @negative.score.max >= 11 && @positive.fvnp.min < 5
@negative.score - @positive.score_without_proteins
else
Range.new(
Expand Down
8 changes: 4 additions & 4 deletions spec/nutriscore/fr/specific_score_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
fat_saturated: 1.8, # g/100g
sugar: 13.4, # g/100g
sodium: 0.1 / 1000, # g/100g
fruits_vegetables_nuts: 8, # g/100g (= weight-%)
fvnp: 8, # g/100g (= weight-%)
fibres: 0.6, # g/100g
proteins: 6.5, # g/100g
}}
Expand All @@ -34,12 +34,12 @@
fat_saturated: 0.1, # g/100g
carbohydrates: 7.8, # g/100g
sugar: 3.1, # g/100g
fruits_vegetables_nuts: 85, # g/100g (= weight-%)
fvnp: 85, # g/100g (= weight-%)
fibres: 3.6, # g/100g
proteins: 2.2, # g/100g
sodium: 0.31 / 2.5, # g/100g
}}
its(:score) { is_expected.to eq(-9) } # @todo check
its(:score) { is_expected.to eq(-8) }
its(:score_class) { is_expected.to eq 'A' }
end

Expand All @@ -49,7 +49,7 @@
energy: 1580, # kJ/100g
fat_saturated: 4.2, # g/100g
sugar: 4.3, # g/100g
fruits_vegetables_nuts: 4, # g/100g (= weight-%)
fvnp: 4, # g/100g (= weight-%)
fibres: 24.9, # g/100g
proteins: 11.4, # g/100g
sodium: 0.15 / 2.5, # g/100g
Expand Down
6 changes: 3 additions & 3 deletions spec/nutriscore/uk/drinks_score_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
fat_saturated: 1.0, # g/100g
sugar: 8.9, # g/100g
sodium: 41 * 1e-3, # g/100g
fruits_vegetables_nuts: 0, # g/100g (= weight-%)
fvnp: 0, # g/100g (= weight-%)
fibres: 0.5, # g/100g
proteins: 3.2, # g/100g
}}
Expand All @@ -32,11 +32,11 @@
fat_saturated: 0, # g/100g
sugar: 10.3, # g/100g
sodium: 0 * 1e-3 , # g/100g
fruits_vegetables_nuts: 15, # g/100g (= weight-%)
fvnp: 15, # g/100g (= weight-%)
fibres: 0, # g/100g
proteins: 0.1, # g/100g
}}
its(:score) { is_expected.to eq 2 }
its(:less_healthy?) { is_expected.to be true }
end
end
end
10 changes: 5 additions & 5 deletions spec/nutriscore/uk/specific_score_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
fat_saturated: 1.8, # g/100g
sugar: 13.4, # g/100g
sodium: 0.1 * 1e-3, # g/100g
fruits_vegetables_nuts: 8, # g/100g (= weight-%)
fvnp: 8, # g/100g (= weight-%)
fibres: 0.6, # g/100g
proteins: 6.5, # g/100g
}}
Expand All @@ -32,7 +32,7 @@
fat_saturated: 6.1, # g/100g
sugar: 18.7, # g/100g
sodium: 60 * 1e-3, # g/100g
fruits_vegetables_nuts: 0, # g/100g (= weight-%)
fvnp: 0, # g/100g (= weight-%)
fibres: 0, # g/100g
proteins: 3.6, # g/100g
}}
Expand All @@ -47,7 +47,7 @@
fat_saturated: 0.4, # g/100g
sugar: 3.6, # g/100g
sodium: 471 * 1e-3, # g/100g
fruits_vegetables_nuts: 0, # g/100g (= weight-%)
fvnp: 0, # g/100g (= weight-%)
fibres: 0.2, # g/100g
proteins: 0.3, # g/100g
}}
Expand All @@ -62,11 +62,11 @@
fat_saturated: 1.4, # g/100g
sugar: 35.7, # g/100g
sodium: 0 * 1e-3, # g/100g
fruits_vegetables_nuts: 46, # g/100g (= weight-%)
fvnp: 46, # g/100g (= weight-%)
fibres: 4.8, # g/100g
proteins: 4.3, # g/100g
}}
its(:score) { is_expected.to eq 6 }
its(:less_healthy?) { is_expected.to be true }
end
end
end

0 comments on commit 633f8a5

Please sign in to comment.