foodAIHE 3.3.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.coveralls.yml +1 -0
- data/.travis.yml +2 -1
- data/README.md +1 -1
- data/docs/input/dish_recipes.txt +18 -0
- data/docs/input/food-data.txt +1 -1
- data/food.gemspec +11 -7
- data/input/dish_recipes.txt +18 -0
- data/input/food-data.txt +19 -0
- data/input/samples-data.txt +9 -0
- data/lib/dsl/harvard_dish.rb +123 -0
- data/lib/food.rb +6 -85
- data/lib/food/food_class.rb +17 -10
- data/lib/food/functions.rb +144 -0
- data/lib/food/sort.rb +135 -0
- data/lib/food/version.rb +1 -1
- metadata +54 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13b2da53673543476c6e782cbc6336315f86e7f3
|
|
4
|
+
data.tar.gz: 6b81cdb810010f46131c4aab5a47b3cca765a1cd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a91cd5c159f6f98f2e5da9fdc24509750e443d6a9af2c95e5035cffe2a734975e289b8385d6685173f0ecb65b111d1776c2e27cf8c81bef281b4b2b40e4ba8ec
|
|
7
|
+
data.tar.gz: e36d3ecc252ee59a13dca60470c3d78dd7934d80f1289207a1ac2379f471f47548060b082ba095ed3dbd0203416f0098edc09ee6a217d71067e1ea6dd1627d8f
|
data/.coveralls.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -34,7 +34,7 @@ por glucidos o proteínas. Las vitaminas y los minerales, así como los oligoele
|
|
|
34
34
|
se considera que no aportan calorías.
|
|
35
35
|
|
|
36
36
|
Por ejemplo, un alimento que contenga 10 g de proteína, 20 g
|
|
37
|
-
de glucidos y 9 g de grasa nos proporcionaría 201 Kcal: 10 × 4 + 20 × 4 + 9 × 9 = 201Kcal
|
|
37
|
+
de glucidos y 9 g de grasa nos proporcionaría 201 Kcal: 10 × 4 + 20 × 4 + 9 × 9 = 201Kcal
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
## Requisitos
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Lentejas con arroz, salsa de tomate, huevo y plátano a la plancha {
|
|
2
|
+
vegetal "Tomate", :porcion => "2 piezas pequeñas"
|
|
3
|
+
fruta "Plátano", :gramos => 20
|
|
4
|
+
cereal "Arroz", :porcion => "1 taza"
|
|
5
|
+
proteina "Lentejas", :porcion => "1/2 cucharon"
|
|
6
|
+
proteina "Huevo frito", :porcion => "1 pieza"
|
|
7
|
+
aceite "Aceite de oliva", :porcion => "1/2 cucharada"
|
|
8
|
+
|
|
9
|
+
personas 2
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Paella a la valenciana {
|
|
13
|
+
cereal "Arroz", :porcion => "5 taza"
|
|
14
|
+
vegetal "Tomate", :porcion => "2 piezas pequeñas"
|
|
15
|
+
aceite "Aceite de oliva", :porcion => "2 cucharadas"
|
|
16
|
+
|
|
17
|
+
personas 5
|
|
18
|
+
}
|
data/docs/input/food-data.txt
CHANGED
data/food.gemspec
CHANGED
|
@@ -9,19 +9,19 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.authors = ["Angel Igareta"]
|
|
10
10
|
spec.email = ["alu0100967111@ull.edu.es"]
|
|
11
11
|
|
|
12
|
-
spec.summary = %q{
|
|
12
|
+
spec.summary = %q{Practicas TDD.}
|
|
13
13
|
spec.description = %q{Practica dessarrollada dirigida a pruebas TDD.}
|
|
14
14
|
spec.homepage = "https://github.com/ULL-ESIT-LPP-1718/tdd-alu0100967111"
|
|
15
15
|
spec.license = "MIT"
|
|
16
16
|
|
|
17
|
+
# For uploading it --> http://guides.rubygems.org/make-your-own-gem/
|
|
17
18
|
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
18
19
|
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
# end
|
|
20
|
+
if spec.respond_to?(:metadata)
|
|
21
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
22
|
+
else
|
|
23
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
|
24
|
+
end
|
|
25
25
|
|
|
26
26
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
27
27
|
f.match(%r{^(test|spec|features)/})
|
|
@@ -37,5 +37,9 @@ Gem::Specification.new do |spec|
|
|
|
37
37
|
spec.add_development_dependency "guard"
|
|
38
38
|
spec.add_development_dependency "guard-rspec"
|
|
39
39
|
spec.add_development_dependency "guard-bundler"
|
|
40
|
+
|
|
41
|
+
spec.add_development_dependency "benchmark-ips" # Para mas info en los Benchmark
|
|
42
|
+
spec.add_development_dependency "coveralls"
|
|
43
|
+
spec.add_development_dependency "terminal-table"
|
|
40
44
|
|
|
41
45
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
Lentejas con arroz, salsa de tomate, huevo y plátano a la plancha {
|
|
2
|
+
vegetal "Tomate", :porcion => "2 piezas pequeñas"
|
|
3
|
+
fruta "Plátano", :gramos => 20
|
|
4
|
+
cereal "Arroz", :porcion => "1 taza"
|
|
5
|
+
proteina "Lentejas", :porcion => "1/2 cucharon"
|
|
6
|
+
proteina "Huevo frito", :porcion => "1 pieza"
|
|
7
|
+
aceite "Aceite de oliva", :porcion => "1/2 cucharada"
|
|
8
|
+
|
|
9
|
+
personas 2
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
Paella a la valenciana {
|
|
13
|
+
cereal "Arroz", :porcion => "5 taza"
|
|
14
|
+
vegetal "Tomate", :porcion => "2 piezas pequeñas"
|
|
15
|
+
aceite "Aceite de oliva", :porcion => "2 cucharadas"
|
|
16
|
+
|
|
17
|
+
personas 5
|
|
18
|
+
}
|
data/input/food-data.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Huevo frito 14.1 0.0 19.5 Huevos, lacteos y helados
|
|
2
|
+
Leche vaca 3.3 4.8 3.2 Huevos, lacteos y helados
|
|
3
|
+
Yogurt 3.8 4.9 3.8 Huevos, lacteos y helados
|
|
4
|
+
Cerdo 21.5 0.0 6.3 Carnes y derivados
|
|
5
|
+
Ternera 21.1 0.0 3.1 Carnes y derivados
|
|
6
|
+
Pollo 20.6 0.0 5.6 Carnes y derivados
|
|
7
|
+
Bacalao 17.7 0.0 0.4 Pescados y mariscos
|
|
8
|
+
Atún 21.5 0.0 15.5 Pescados y mariscos
|
|
9
|
+
Salmón 19.9 0.0 13.6 Pescados y mariscos
|
|
10
|
+
Aceite de oliva 0.0 0.2 99.6 Alimentos grasos
|
|
11
|
+
Chocolate 5.3 47.0 30.0 Alimentos grasos
|
|
12
|
+
Azúar 0.0 99.8 0.0 Alimentos ricos en carbohidratos
|
|
13
|
+
Arroz 6.8 77.7 0.6 Alimentos ricos en carbohidratos
|
|
14
|
+
Lentejas 23.5 52.0 1.4 Alimentos ricos en carbohidratos
|
|
15
|
+
Papas 2.0 15.4 0.1 Alimentos ricos en carbohidratos
|
|
16
|
+
Tomate 1.0 3.5 0.2 Verduras y Hortalizas
|
|
17
|
+
Cebolla 1.3 5.8 0.3 Verduras y Hortalizas
|
|
18
|
+
Manzana 0.3 12.4 0.4 Frutas
|
|
19
|
+
Plátano 1.2 21.4 0.2 Frutas
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
ind. alimento 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120
|
|
2
|
+
1 manzana 6.7 6.5 6.8 6.9 7.0 7.1 6.9 6.9 6.9 6.7 6.9 7.3 7.0 7.0 7.2 7.1 6.8 7.2 7.3 7.0 6.8 6.7 6.8 6.7 6.9
|
|
3
|
+
yogurt 6.1 6.6 6.3 6.3 6.1 6.9 6.8 6.5 6.4 6.9 6.8 6.5 6.3 6.2 6.7 6.2 5.9 5.8 5.8 5.8 5.8 5.8 5.9 6.2 6.4
|
|
4
|
+
chocolate 6.5 6.5 6.7 6.5 6.5 6.8 6.7 6.2 6.5 7.2 6.9 7.0 6.3 6.2 6.1 5.9 5.8 6.1 6.7 6.7 6.6 6.7 6.9 7.2 7.1
|
|
5
|
+
glucosa 4.9 5.3 5.9 6.7 7.2 7.6 8.0 8.2 8.2 8.4 8.3 8.3 8.0 7.5 7.1 6.8 6.8 6.9 6.8 6.3 6.2 6.3 6.2 6.3 6.1
|
|
6
|
+
2 manzana 4.6 4.8 5.3 5.6 6.1 6.5 6.6 7.0 7.0 6.8 6.4 6.3 6.1 6.1 6.2 6.0 6.1 6.1 6.2 6.3 6.4 6.1 6.1 5.7 5.9
|
|
7
|
+
yogurt 4.9 4.9 5.2 5.8 6.5 7.0 7.2 7.3 7.3 6.6 6.2 6.1 6.0 6.1 5.9 5.9 5.9 5.9 5.8 5.8 5.5 5.5 5.6 5.9 5.9
|
|
8
|
+
chocolate 4.6 4.6 4.7 4.7 4.8 4.7 4.8 4.8 4.6 4.4 4.7 4.7 4.8 4.7 5.2 5.9 5.9 5.7 5.4 5.3 5.1 4.8 4.8 4.9 5.9
|
|
9
|
+
glucosa 6.3 5.4 5.6 5.7 6.5 7.4 7.9 7.4 7.7 7.9 7.9 7.8 7.8 7.8 8.0 8.5 9.4 10.8 10.5 9.1 8.9 8.3 7.7 7.6 7.5
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# CLASS FOR HARVARDISHES
|
|
2
|
+
INGREDIENT_DATABASE_FILENAME = "input/food-data.txt"
|
|
3
|
+
INGREDIENT_DATABASE_GRAMS = 100
|
|
4
|
+
|
|
5
|
+
# INGREDIENT WEIGHT 10G
|
|
6
|
+
PIECE_QUANTITY = 100
|
|
7
|
+
SMALL_PIECE_QUANTITY = PIECE_QUANTITY * 0.5
|
|
8
|
+
MUG_QUANTITY = 240
|
|
9
|
+
SMALL_MUG_QUANTITY = MUG_QUANTITY * 0.5
|
|
10
|
+
SPOON_QUANTITY = 150
|
|
11
|
+
SMALL_SPOON_QUANTITY = SPOON_QUANTITY * 0.5
|
|
12
|
+
|
|
13
|
+
class HarvardDishDSL
|
|
14
|
+
|
|
15
|
+
attr_reader :dish_title, :ingredient_quantity_array
|
|
16
|
+
|
|
17
|
+
@@ingredient_database = read_ingredient_database(INGREDIENT_DATABASE_FILENAME)
|
|
18
|
+
|
|
19
|
+
def initialize(dish_title, &block)
|
|
20
|
+
@dish_title = dish_title
|
|
21
|
+
@ingredient_quantity_array = [] # Arrays of pairs ingredient name and quantity
|
|
22
|
+
@number_of_people = 0
|
|
23
|
+
|
|
24
|
+
if block_given?
|
|
25
|
+
if block.arity == 1
|
|
26
|
+
yield self
|
|
27
|
+
else
|
|
28
|
+
instance_eval(&block)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_s
|
|
35
|
+
rows = []
|
|
36
|
+
total_energetic_content = 0
|
|
37
|
+
|
|
38
|
+
@ingredient_quantity_array.each { |ingredient_name, ingredient_quantity|
|
|
39
|
+
@food = @@ingredient_database[ingredient_name] * ingredient_quantity
|
|
40
|
+
rows << [@food.name, ingredient_quantity*10, @food.glucid_quantity, @food.protein_quantity, @food.lipid_quantity, @food.energetic_content]
|
|
41
|
+
total_energetic_content += @food.energetic_content
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rows << ['Valor Energético Total', '', '', '', '', total_energetic_content]
|
|
45
|
+
|
|
46
|
+
# Gema para tabla usada -> https://github.com/tj/terminal-table
|
|
47
|
+
return Terminal::Table.new(:title => @dish_title,
|
|
48
|
+
:headings => [' ', 'Gramos', 'Glúcidos', 'Proteínas', 'Lípidos', 'Valor Energético'],
|
|
49
|
+
:rows => rows)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def vegetal (ingredient_name, options = {})
|
|
53
|
+
ingredient_quantity = analyze_options(options)
|
|
54
|
+
@ingredient_quantity_array.push([ingredient_name, ingredient_quantity])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def fruta (ingredient_name, options = {})
|
|
58
|
+
ingredient_quantity = analyze_options(options)
|
|
59
|
+
@ingredient_quantity_array.push([ingredient_name, ingredient_quantity])
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def cereal (ingredient_name, options = {})
|
|
63
|
+
ingredient_quantity = analyze_options(options)
|
|
64
|
+
@ingredient_quantity_array.push([ingredient_name, ingredient_quantity])
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def proteina (ingredient_name, options = {})
|
|
68
|
+
ingredient_quantity = analyze_options(options)
|
|
69
|
+
@ingredient_quantity_array.push([ingredient_name, ingredient_quantity])
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def aceite (ingredient_name, options = {})
|
|
73
|
+
ingredient_quantity = analyze_options(options)
|
|
74
|
+
@ingredient_quantity_array.push([ingredient_name, ingredient_quantity])
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def personas (number_of_people)
|
|
78
|
+
@number_of_people = number_of_people
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def analyze_options(options)
|
|
84
|
+
quantity = 0
|
|
85
|
+
options.each { |option_name, option_value|
|
|
86
|
+
case option_name
|
|
87
|
+
when :porcion
|
|
88
|
+
quantity = transform_to_grams(option_value)
|
|
89
|
+
else :gramos
|
|
90
|
+
quantity = option_value/10
|
|
91
|
+
end
|
|
92
|
+
}
|
|
93
|
+
return quantity
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# pieza, pieza pequeña, taza, taza pequeña, cucharon, cucharada
|
|
97
|
+
def transform_to_grams(portion)
|
|
98
|
+
quantity = 0
|
|
99
|
+
|
|
100
|
+
if (portion =~ /piez/)
|
|
101
|
+
if (portion =~ /pequeña/)
|
|
102
|
+
quantity = SMALL_PIECE_QUANTITY
|
|
103
|
+
else
|
|
104
|
+
quantity = PIECE_QUANTITY
|
|
105
|
+
end
|
|
106
|
+
elsif (portion =~ /taz/)
|
|
107
|
+
if (portion =~ /pequeña/)
|
|
108
|
+
quantity = SMALL_MUG_QUANTITY
|
|
109
|
+
else
|
|
110
|
+
quantity = MUG_QUANTITY
|
|
111
|
+
end
|
|
112
|
+
elsif (portion =~ /cucharon/)
|
|
113
|
+
quantity = SPOON_QUANTITY
|
|
114
|
+
elsif (portion =~ /cuchar/)
|
|
115
|
+
quantity = SMALL_SPOON_QUANTITY
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
fixed_quantity = (quantity * portion.to_r).to_f / INGREDIENT_DATABASE_GRAMS
|
|
119
|
+
|
|
120
|
+
return fixed_quantity
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
data/lib/food.rb
CHANGED
|
@@ -1,91 +1,12 @@
|
|
|
1
1
|
require "food/version"
|
|
2
2
|
require "food/food_class"
|
|
3
3
|
require "food/dll"
|
|
4
|
+
require "food/sort"
|
|
5
|
+
require "food/functions"
|
|
6
|
+
|
|
7
|
+
require "dsl/harvard_dish"
|
|
8
|
+
require 'terminal-table'
|
|
4
9
|
|
|
5
10
|
# Root Module for the Gem
|
|
6
11
|
# @author Angel Igareta (alu0100967111@ull.edu.es)
|
|
7
|
-
module FoodGem
|
|
8
|
-
|
|
9
|
-
def read_samples_data (samples_data_filename)
|
|
10
|
-
data_file = File.open(samples_data_filename)
|
|
11
|
-
data_file = data_file.read.split("\n")[1..-1] # Divido el fichero en líneas y quito la primera
|
|
12
|
-
data_line_array = data_file.collect! { |data_array| data_array.split(" ") } # Cambio las líneas a arrays
|
|
13
|
-
|
|
14
|
-
# Hash with (name of the food, sample array for all the persons to that foods)
|
|
15
|
-
sample_people_hash = Hash.new([])
|
|
16
|
-
person_number = 1
|
|
17
|
-
line_counter = 0
|
|
18
|
-
|
|
19
|
-
# Mientras no hayamos recorrido todas las lineas y el primero sea un int (nuevo individuo)
|
|
20
|
-
while ((line_counter < data_line_array.count) && (data_line_array[line_counter][0].to_i == person_number))
|
|
21
|
-
|
|
22
|
-
data_line = data_line_array[line_counter]
|
|
23
|
-
|
|
24
|
-
person_number = person_number + 1 # Change of person
|
|
25
|
-
data_line = data_line[1..-1] # Delete the person number
|
|
26
|
-
|
|
27
|
-
while ((line_counter < data_line_array.count) && (data_line_array[line_counter][0].to_i != person_number))
|
|
28
|
-
food_name = data_line[0].capitalize
|
|
29
|
-
sample_person_array = data_line[1..-1].collect { |data| data.to_f } # Cambio numeros a float
|
|
30
|
-
|
|
31
|
-
if (sample_people_hash[food_name] == [])
|
|
32
|
-
if (food_name == "Glucosa")
|
|
33
|
-
sample_people_hash.each_key { |name| sample_people_hash[name][person_number-2].push(sample_person_array) }
|
|
34
|
-
else
|
|
35
|
-
sample_people_hash[food_name] = [[sample_person_array]]
|
|
36
|
-
end
|
|
37
|
-
else
|
|
38
|
-
sample_people_hash[food_name].push([sample_person_array])
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
line_counter = line_counter + 1 # Cambio de línea
|
|
42
|
-
unless (line_counter >= data_line_array.count)
|
|
43
|
-
data_line = data_line_array[line_counter]
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
#sample_people_hash.each{ |x, y| puts "#{x} => #{y}" }
|
|
49
|
-
|
|
50
|
-
return sample_people_hash
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# Method to read data by file
|
|
54
|
-
# @params data_filename [String] filename of the data
|
|
55
|
-
# @return [Array] Return array of food
|
|
56
|
-
def read_data (data_filename, samples_data_filename)
|
|
57
|
-
data_string = File.open(data_filename).read.split("\n") # Divido el fichero en string de lineas
|
|
58
|
-
food_array = []
|
|
59
|
-
sample_people_hash = read_samples_data(samples_data_filename)
|
|
60
|
-
|
|
61
|
-
data_string.each { |data_line|
|
|
62
|
-
data_line = data_line.split(" ") # La divido en espacios
|
|
63
|
-
name = ""
|
|
64
|
-
|
|
65
|
-
while (data_line[0] != data_line[0].to_f.to_s) # Si el nombre no cambia al pasar de string afloat es que es un float
|
|
66
|
-
name << data_line[0] << " "
|
|
67
|
-
data_line = data_line[1..-1] # Quito el primer elemento
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
food_name = name[0..-2].capitalize
|
|
71
|
-
protein = [data_line[0].to_f, PROTEIN_ENERGY]
|
|
72
|
-
glucid = [data_line[1].to_f, GLUCID_ENERGY]
|
|
73
|
-
lipid = [data_line[2].to_f, LIPID_ENERGY]
|
|
74
|
-
|
|
75
|
-
data_line = data_line[3..-1]
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
group_name = ""
|
|
79
|
-
while (!data_line[0].nil?) # Si el nombre no cambia al pasar de string afloat es que es un float
|
|
80
|
-
group_name << data_line[0] << " "
|
|
81
|
-
data_line = data_line[1..-1] # Quito el primer elemento
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
food = Food.new(food_name, protein, glucid, lipid, group_name[0..-2], sample_people_hash[food_name])
|
|
85
|
-
food_array.push(food) # Quito último espacio a nombre y grupo
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return food_array
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
end
|
|
12
|
+
module FoodGem; end
|
data/lib/food/food_class.rb
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
# @param PROTEIN_ENERGY [int] protein energy.
|
|
3
3
|
# @param GLUCID_ENERGY [int] glucid energy.
|
|
4
4
|
# @param LIPID_ENERGY [int] lipid energy
|
|
5
|
-
PROTEIN_ENERGY = 4
|
|
6
5
|
GLUCID_ENERGY = 4
|
|
7
6
|
LIPID_ENERGY = 9
|
|
7
|
+
PROTEIN_ENERGY = 4
|
|
8
8
|
|
|
9
9
|
# Abstract class for Food
|
|
10
10
|
class FoodAbstract
|
|
@@ -42,22 +42,27 @@ class FoodAbstract
|
|
|
42
42
|
@pair_macronutrient_energy.push([glucid_energy_pair[0], glucid_energy_pair[1]])
|
|
43
43
|
@pair_macronutrient_energy.push([lipid_energy_pair[0], lipid_energy_pair[1]])
|
|
44
44
|
|
|
45
|
-
@energetic_content = calculate_energetic_content
|
|
45
|
+
@energetic_content = calculate_energetic_content.round(3)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
# Calculates the energetic content for the food
|
|
49
49
|
# @return [double] energetic_content
|
|
50
50
|
def calculate_energetic_content
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
energetic_content = 0
|
|
52
|
+
@pair_macronutrient_energy.each{ |macronutrient, energy| energetic_content += (macronutrient * energy) }
|
|
53
|
+
return energetic_content
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Return string with the output for the food
|
|
57
57
|
# @return [String] outpout of food
|
|
58
58
|
def to_s
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
"Nombre: #{@name} | Proteínas: #{@protein_quantity} gramos | Glúcidos: #{@glucid_quantity} gramos | Lípidos: #{@lipid_quantity} gramos | " \
|
|
60
|
+
"Contenido Energético: #{@energetic_content} Kcal."
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def *(quantity)
|
|
64
|
+
@energetic_content = (@energetic_content * quantity).round(3)
|
|
65
|
+
return self
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
end
|
|
@@ -77,7 +82,7 @@ class Food < FoodAbstract
|
|
|
77
82
|
# @param glucid_energy_pair [pair] pair of glucid number and energy
|
|
78
83
|
# @param lipid_energy_pair [pair] pair of lipid number and energy
|
|
79
84
|
# @param group_name [String] the name for the food group.
|
|
80
|
-
def initialize(name, protein_energy_pair, glucid_energy_pair, lipid_energy_pair, group_name, gluc_sample_pair_array = [])
|
|
85
|
+
def initialize(name, protein_energy_pair, glucid_energy_pair, lipid_energy_pair, group_name = "", gluc_sample_pair_array = [])
|
|
81
86
|
@group_name = group_name
|
|
82
87
|
super(name, protein_energy_pair, glucid_energy_pair, lipid_energy_pair)
|
|
83
88
|
|
|
@@ -119,14 +124,16 @@ class Food < FoodAbstract
|
|
|
119
124
|
# Return string with the output for the food calling the father
|
|
120
125
|
# @return [String] output of food
|
|
121
126
|
def to_s
|
|
122
|
-
"Grupo: #{@group_name} | " + super
|
|
127
|
+
return ("Grupo: #{@group_name} | " + super) if (@group_name != "")
|
|
128
|
+
super
|
|
123
129
|
end
|
|
124
130
|
|
|
125
131
|
# Essential comparating for using Comparable Module
|
|
126
132
|
# @return [String] Return which food is higher depending on the enrgetic content
|
|
127
133
|
def <=> (food)
|
|
128
134
|
raise unless food.is_a?Food
|
|
129
|
-
return self.energetic_content <=> food.energetic_content
|
|
135
|
+
# return self.energetic_content <=> food.energetic_content
|
|
136
|
+
return self.name <=> food.name
|
|
130
137
|
end
|
|
131
138
|
|
|
132
139
|
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# USEFUL FUNCTIONS
|
|
2
|
+
|
|
3
|
+
def read_recipe (recipe_filename)
|
|
4
|
+
recipes = File.open(recipe_filename).read.split("\n") # Divido el fichero en string de lineas
|
|
5
|
+
# hash nombre_receta ingredientes(proc)
|
|
6
|
+
recipe_ingredient_hash = Hash.new()
|
|
7
|
+
|
|
8
|
+
# Por cada receta ( Que tenga un { )
|
|
9
|
+
recipes.grep(/{/).each { |recipe_title|
|
|
10
|
+
|
|
11
|
+
# Coger el índice donde empieza y donde termina (Que tenga un })
|
|
12
|
+
start_index = recipes.find_index{ |line| line == recipe_title }
|
|
13
|
+
end_index = recipes[start_index..-1].find_index{ |line| line == "}" }
|
|
14
|
+
|
|
15
|
+
# Cogemos lo que está dentro de los dos índices (la receta)
|
|
16
|
+
|
|
17
|
+
recipe_ingredient_hash[recipe_title[0..-3]] = recipes[start_index+1, end_index-1]
|
|
18
|
+
# .join("\n")
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return recipe_ingredient_hash
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def read_samples_data (samples_data_filename)
|
|
25
|
+
data_file = File.open(samples_data_filename)
|
|
26
|
+
data_file = data_file.read.split("\n")[1..-1] # Divido el fichero en líneas y quito la primera
|
|
27
|
+
data_line_array = data_file.collect! { |data_array| data_array.split(" ") } # Cambio las líneas a arrays
|
|
28
|
+
|
|
29
|
+
# Hash with (name of the food, sample array for all the persons to that foods)
|
|
30
|
+
sample_people_hash = Hash.new([])
|
|
31
|
+
person_number = 1
|
|
32
|
+
line_counter = 0
|
|
33
|
+
|
|
34
|
+
# Mientras no hayamos recorrido todas las lineas y el primero sea un int (nuevo individuo)
|
|
35
|
+
while ((line_counter < data_line_array.count) && (data_line_array[line_counter][0].to_i == person_number))
|
|
36
|
+
|
|
37
|
+
data_line = data_line_array[line_counter]
|
|
38
|
+
|
|
39
|
+
person_number = person_number + 1 # Change of person
|
|
40
|
+
data_line = data_line[1..-1] # Delete the person number
|
|
41
|
+
|
|
42
|
+
while ((line_counter < data_line_array.count) && (data_line_array[line_counter][0].to_i != person_number))
|
|
43
|
+
food_name = data_line[0].capitalize
|
|
44
|
+
sample_person_array = data_line[1..-1].collect { |data| data.to_f } # Cambio numeros a float
|
|
45
|
+
|
|
46
|
+
if (sample_people_hash[food_name] == [])
|
|
47
|
+
if (food_name == "Glucosa")
|
|
48
|
+
sample_people_hash.each_key { |name| sample_people_hash[name][person_number-2].push(sample_person_array) }
|
|
49
|
+
else
|
|
50
|
+
sample_people_hash[food_name] = [[sample_person_array]]
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
sample_people_hash[food_name].push([sample_person_array])
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
line_counter = line_counter + 1 # Cambio de línea
|
|
57
|
+
unless (line_counter >= data_line_array.count)
|
|
58
|
+
data_line = data_line_array[line_counter]
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
#sample_people_hash.each{ |x, y| puts "#{x} => #{y}" }
|
|
64
|
+
|
|
65
|
+
return sample_people_hash
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Method to read data by file
|
|
69
|
+
# @params data_filename [String] filename of the data
|
|
70
|
+
# @return [Array] Return array of food
|
|
71
|
+
def read_data (data_filename, samples_data_filename = "")
|
|
72
|
+
data_string = File.open(data_filename).read.split("\n") # Divido el fichero en string de lineas
|
|
73
|
+
food_array = []
|
|
74
|
+
|
|
75
|
+
if (samples_data_filename != "")
|
|
76
|
+
sample_people_hash = read_samples_data(samples_data_filename)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
data_string.each { |data_line|
|
|
80
|
+
data_line = data_line.split(" ") # La divido en espacios
|
|
81
|
+
name = ""
|
|
82
|
+
|
|
83
|
+
while (data_line[0] != data_line[0].to_f.to_s) # Si el nombre no cambia al pasar de string afloat es que es un float
|
|
84
|
+
name << data_line[0] << " "
|
|
85
|
+
data_line = data_line[1..-1] # Quito el primer elemento
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
food_name = name[0..-2].capitalize
|
|
89
|
+
protein = [data_line[0].to_f, PROTEIN_ENERGY]
|
|
90
|
+
glucid = [data_line[1].to_f, GLUCID_ENERGY]
|
|
91
|
+
lipid = [data_line[2].to_f, LIPID_ENERGY]
|
|
92
|
+
|
|
93
|
+
data_line = data_line[3..-1]
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
group_name = ""
|
|
97
|
+
while (!data_line[0].nil?) # Si el nombre no cambia al pasar de string afloat es que es un float
|
|
98
|
+
group_name << data_line[0] << " "
|
|
99
|
+
data_line = data_line[1..-1] # Quito el primer elemento
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if (samples_data_filename != "")
|
|
103
|
+
food = Food.new(food_name, protein, glucid, lipid, group_name[0..-2], sample_people_hash[food_name])
|
|
104
|
+
else
|
|
105
|
+
food = Food.new(food_name, protein, glucid, lipid, group_name[0..-2])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
food_array.push(food)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return food_array
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def read_ingredient_database(data_filename)
|
|
115
|
+
data_string = File.open(data_filename).read.split("\n") # Divido el fichero en string de lineas
|
|
116
|
+
food_hash = Hash.new()
|
|
117
|
+
|
|
118
|
+
data_string.each { |data_line|
|
|
119
|
+
data_line = data_line.split(" ") # La divido en espacios
|
|
120
|
+
name = ""
|
|
121
|
+
|
|
122
|
+
while (data_line[0] != data_line[0].to_f.to_s) # Si el nombre no cambia al pasar de string afloat es que es un float
|
|
123
|
+
name << data_line[0] << " "
|
|
124
|
+
data_line = data_line[1..-1] # Quito el primer elemento
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
food_name = name[0..-2].capitalize
|
|
128
|
+
protein = [data_line[0].to_f, PROTEIN_ENERGY]
|
|
129
|
+
glucid = [data_line[1].to_f, GLUCID_ENERGY]
|
|
130
|
+
lipid = [data_line[2].to_f, LIPID_ENERGY]
|
|
131
|
+
|
|
132
|
+
data_line = data_line[3..-1]
|
|
133
|
+
|
|
134
|
+
group_name = ""
|
|
135
|
+
while (!data_line[0].nil?)
|
|
136
|
+
group_name << data_line[0] << " "
|
|
137
|
+
data_line = data_line[1..-1] # Quito el primer elemento
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
food_hash[food_name] = Food.new(food_name, protein, glucid, lipid, group_name[0..-2])
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return food_hash
|
|
144
|
+
end
|
data/lib/food/sort.rb
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
class Array
|
|
2
|
+
|
|
3
|
+
# Swap changes elements in position!
|
|
4
|
+
def swap(i, j)
|
|
5
|
+
clone_array = self.clone
|
|
6
|
+
clone_array[i], clone_array[j] = clone_array[j], clone_array[i]
|
|
7
|
+
clone_array
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def swap!(i, j)
|
|
11
|
+
self[i], self[j] = self[j], self[i]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def bubble_sort_imp()
|
|
15
|
+
clone_array = self.clone
|
|
16
|
+
|
|
17
|
+
for i in 1...clone_array.size
|
|
18
|
+
for j in 0...(clone_array.size - i)
|
|
19
|
+
clone_array.swap!(j, j+1) if (clone_array[j] > clone_array[j+1])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
clone_array
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def bubble_sort_imp!()
|
|
27
|
+
self.replace(self.bubble_sort_imp())
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def bubble_sort()
|
|
31
|
+
clone_array = self.clone
|
|
32
|
+
|
|
33
|
+
(1...clone_array.size).each { |i|
|
|
34
|
+
(0...(clone_array.size - i)).each { |j|
|
|
35
|
+
clone_array.swap!(j, j+1) if (clone_array[j] > clone_array[j+1])
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
clone_array
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def bubble_sort!()
|
|
43
|
+
self.replace(self.bubble_sort())
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def merge_sort()
|
|
47
|
+
split_array(self)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def merge_sort_imp()
|
|
51
|
+
split_array(self)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def split_array_imp(sorted_array)
|
|
57
|
+
if (sorted_array.size <= 2)
|
|
58
|
+
if ((sorted_array.size == 2) && (sorted_array[0] > sorted_array[1]))
|
|
59
|
+
return sorted_array.swap(0, 1)
|
|
60
|
+
else
|
|
61
|
+
return sorted_array
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
middle = sorted_array.size / 2
|
|
65
|
+
array_1 = split_array(sorted_array[0...middle])
|
|
66
|
+
array_2 = split_array(sorted_array[middle...sorted_array.size])
|
|
67
|
+
|
|
68
|
+
return merge_arrays(array_1, array_2)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def merge_arrays_imp(array_1, array_2)
|
|
73
|
+
sorted_array = Array.new()
|
|
74
|
+
|
|
75
|
+
i = 0 # Iterador array_1
|
|
76
|
+
j = 0 # Iterador array_2
|
|
77
|
+
|
|
78
|
+
while ((i < array_1.size) && (j < array_2.size)) # Iterador array_3
|
|
79
|
+
if (array_1[i] <= array_2[j])
|
|
80
|
+
sorted_array.push(array_1[i])
|
|
81
|
+
i = i+1
|
|
82
|
+
else
|
|
83
|
+
sorted_array.push(array_2[j])
|
|
84
|
+
j = j+1
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
while(i < array_1.size)
|
|
89
|
+
sorted_array.push(array_1[i])
|
|
90
|
+
i = i+1
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
while(j < array_2.size)
|
|
94
|
+
sorted_array.push(array_2[j])
|
|
95
|
+
j = j+1
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
return sorted_array
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def split_array(sorted_array)
|
|
102
|
+
if (sorted_array.size <= 2)
|
|
103
|
+
if ((sorted_array.size == 2) && (sorted_array[0] > sorted_array[1]))
|
|
104
|
+
return sorted_array.swap!(0, 1)
|
|
105
|
+
else
|
|
106
|
+
return sorted_array
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
middle = sorted_array.size / 2
|
|
111
|
+
array_1 = split_array(sorted_array[0...middle])
|
|
112
|
+
array_2 = split_array(sorted_array[middle...sorted_array.size])
|
|
113
|
+
|
|
114
|
+
return merge_arrays(array_1, array_2)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def merge_arrays(array_1, array_2)
|
|
118
|
+
sorted_array = Array.new()
|
|
119
|
+
|
|
120
|
+
while (array_1.any? && array_2.any?) # Iterador array_3
|
|
121
|
+
if (array_1[0] <= array_2[0])
|
|
122
|
+
sorted_array.push(array_1[0])
|
|
123
|
+
array_1.delete_at(0)
|
|
124
|
+
else
|
|
125
|
+
sorted_array.push(array_2[0])
|
|
126
|
+
array_2.delete_at(0)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
sorted_array.concat(array_1) if array_1.any?
|
|
131
|
+
sorted_array.concat(array_2) if array_2.any?
|
|
132
|
+
return sorted_array
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
end
|
data/lib/food/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foodAIHE
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.3.
|
|
4
|
+
version: 3.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Angel Igareta
|
|
@@ -94,6 +94,48 @@ dependencies:
|
|
|
94
94
|
- - ">="
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: benchmark-ips
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: coveralls
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: terminal-table
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
97
139
|
description: Practica dessarrollada dirigida a pruebas TDD.
|
|
98
140
|
email:
|
|
99
141
|
- alu0100967111@ull.edu.es
|
|
@@ -101,6 +143,7 @@ executables: []
|
|
|
101
143
|
extensions: []
|
|
102
144
|
extra_rdoc_files: []
|
|
103
145
|
files:
|
|
146
|
+
- ".coveralls.yml"
|
|
104
147
|
- ".gitignore"
|
|
105
148
|
- ".travis.yml"
|
|
106
149
|
- Gemfile
|
|
@@ -126,6 +169,7 @@ files:
|
|
|
126
169
|
- docs/file_list.html
|
|
127
170
|
- docs/frames.html
|
|
128
171
|
- docs/index.html
|
|
172
|
+
- docs/input/dish_recipes.txt
|
|
129
173
|
- docs/input/food-data.txt
|
|
130
174
|
- docs/input/samples-data.txt
|
|
131
175
|
- docs/js/app.js
|
|
@@ -134,14 +178,21 @@ files:
|
|
|
134
178
|
- docs/method_list.html
|
|
135
179
|
- docs/top-level-namespace.html
|
|
136
180
|
- food.gemspec
|
|
181
|
+
- input/dish_recipes.txt
|
|
182
|
+
- input/food-data.txt
|
|
183
|
+
- input/samples-data.txt
|
|
184
|
+
- lib/dsl/harvard_dish.rb
|
|
137
185
|
- lib/food.rb
|
|
138
186
|
- lib/food/dll.rb
|
|
139
187
|
- lib/food/food_class.rb
|
|
188
|
+
- lib/food/functions.rb
|
|
189
|
+
- lib/food/sort.rb
|
|
140
190
|
- lib/food/version.rb
|
|
141
191
|
homepage: https://github.com/ULL-ESIT-LPP-1718/tdd-alu0100967111
|
|
142
192
|
licenses:
|
|
143
193
|
- MIT
|
|
144
|
-
metadata:
|
|
194
|
+
metadata:
|
|
195
|
+
allowed_push_host: https://rubygems.org
|
|
145
196
|
post_install_message:
|
|
146
197
|
rdoc_options: []
|
|
147
198
|
require_paths:
|
|
@@ -161,5 +212,5 @@ rubyforge_project:
|
|
|
161
212
|
rubygems_version: 2.5.1
|
|
162
213
|
signing_key:
|
|
163
214
|
specification_version: 4
|
|
164
|
-
summary:
|
|
215
|
+
summary: Practicas TDD.
|
|
165
216
|
test_files: []
|