huella 0.1.0

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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +97 -0
  8. data/Guardfile +82 -0
  9. data/README.md +48 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/docs/Alimento.html +627 -0
  14. data/docs/Gemfile.html +98 -0
  15. data/docs/Gemfile_lock.html +179 -0
  16. data/docs/Guardfile.html +165 -0
  17. data/docs/Huella/Error.html +103 -0
  18. data/docs/Huella.html +114 -0
  19. data/docs/Lista.html +981 -0
  20. data/docs/Object.html +337 -0
  21. data/docs/PlatoAmbiental.html +436 -0
  22. data/docs/PlatoNutricional.html +517 -0
  23. data/docs/README_md.html +146 -0
  24. data/docs/Rakefile.html +100 -0
  25. data/docs/bin/setup.html +100 -0
  26. data/docs/created.rid +24 -0
  27. data/docs/css/fonts.css +167 -0
  28. data/docs/css/rdoc.css +590 -0
  29. data/docs/fonts/Lato-Light.ttf +0 -0
  30. data/docs/fonts/Lato-LightItalic.ttf +0 -0
  31. data/docs/fonts/Lato-Regular.ttf +0 -0
  32. data/docs/fonts/Lato-RegularItalic.ttf +0 -0
  33. data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
  34. data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
  35. data/docs/huella_gemspec.html +133 -0
  36. data/docs/images/add.png +0 -0
  37. data/docs/images/arrow_up.png +0 -0
  38. data/docs/images/brick.png +0 -0
  39. data/docs/images/brick_link.png +0 -0
  40. data/docs/images/bug.png +0 -0
  41. data/docs/images/bullet_black.png +0 -0
  42. data/docs/images/bullet_toggle_minus.png +0 -0
  43. data/docs/images/bullet_toggle_plus.png +0 -0
  44. data/docs/images/date.png +0 -0
  45. data/docs/images/delete.png +0 -0
  46. data/docs/images/find.png +0 -0
  47. data/docs/images/loadingAnimation.gif +0 -0
  48. data/docs/images/macFFBgHack.png +0 -0
  49. data/docs/images/package.png +0 -0
  50. data/docs/images/page_green.png +0 -0
  51. data/docs/images/page_white_text.png +0 -0
  52. data/docs/images/page_white_width.png +0 -0
  53. data/docs/images/plugin.png +0 -0
  54. data/docs/images/ruby.png +0 -0
  55. data/docs/images/tag_blue.png +0 -0
  56. data/docs/images/tag_green.png +0 -0
  57. data/docs/images/transparent.png +0 -0
  58. data/docs/images/wrench.png +0 -0
  59. data/docs/images/wrench_orange.png +0 -0
  60. data/docs/images/zoom.png +0 -0
  61. data/docs/index.html +117 -0
  62. data/docs/js/darkfish.js +161 -0
  63. data/docs/js/jquery.js +4 -0
  64. data/docs/js/navigation.js +141 -0
  65. data/docs/js/navigation.js.gz +0 -0
  66. data/docs/js/search.js +109 -0
  67. data/docs/js/search_index.js +1 -0
  68. data/docs/js/search_index.js.gz +0 -0
  69. data/docs/js/searcher.js +229 -0
  70. data/docs/js/searcher.js.gz +0 -0
  71. data/docs/table_of_contents.html +378 -0
  72. data/huella.gemspec +38 -0
  73. data/lib/huella/alimento.rb +112 -0
  74. data/lib/huella/lista.rb +275 -0
  75. data/lib/huella/menu_dsl.rb +92 -0
  76. data/lib/huella/nodo.rb +7 -0
  77. data/lib/huella/plato_ambiental.rb +100 -0
  78. data/lib/huella/plato_dsl.rb +89 -0
  79. data/lib/huella/plato_nutricional.rb +102 -0
  80. data/lib/huella/version.rb +4 -0
  81. data/lib/huella.rb +14 -0
  82. metadata +238 -0
@@ -0,0 +1,112 @@
1
+ =begin
2
+ Representa un alimento con su nombre y sus
3
+ * valores energéticos: Proteinas carbohidratos y lipidos
4
+ * valores ambientales: Gases de efecto invernadero (gei) y uso de terreno
5
+ =end
6
+ class Alimento
7
+
8
+ include Comparable
9
+
10
+ attr_reader :nombre, :proteinas, :carbohidratos, :lipidos, :gei, :terreno
11
+
12
+ def initialize(nombre, proteinas, carbohidratos, lipidos, gei, terreno)
13
+ @nombre = nombre
14
+ @proteinas = proteinas
15
+ @carbohidratos = carbohidratos
16
+ @lipidos = lipidos
17
+ @gei = gei
18
+ @terreno = terreno
19
+ end
20
+
21
+ #Retorna el Alimento formateado
22
+ def to_s
23
+ "[#{@nombre} [#{@proteinas} #{@carbohidratos} #{@lipidos}] [#{@gei} #{@terreno}]]"
24
+ end
25
+
26
+ #Define la proporcion de cada nutriente en el aporte energético
27
+ def getValorEnergetico
28
+ ( (proteinas * 4.00) + (carbohidratos * 4.00) + (lipidos * 9.00) ).round(2)
29
+ end
30
+
31
+ #Retorna el valor energético dependiendo de la cantidad de gramos del alimento
32
+ def getValorEnergeticoConGramos(cantidad)
33
+ ( (getValorEnergetico * cantidad) / 100.0 ).round(2)
34
+ end
35
+
36
+ #Compara cada Alimento según su valor energético
37
+ def <=>(other)
38
+ #-1 si left < right
39
+ # 0 si left == right
40
+ # 1 si left > right
41
+ self.getValorEnergetico <=> other.getValorEnergetico
42
+ end
43
+
44
+ #Dos Alimentos son iguales si tienen los mismos atributos
45
+ def ==(other)
46
+ (@nombre == other.nombre) && (@proteinas == other.proteinas) &&
47
+ (@carbohidratos == other.carbohidratos) && (@lipidos == other.lipidos) &&
48
+ (@gei == other.gei) && (@terreno == other.terreno)
49
+ end
50
+
51
+ #Retorna un índice de energía según la cantidad en gr del alimento
52
+ def getIndiceEnergia(cantidad)
53
+
54
+ energia = self.getValorEnergetico * cantidad
55
+
56
+ if(energia < 670)
57
+ return 1
58
+ elsif(energia < 830)
59
+ return 2
60
+ else
61
+ return 3
62
+ end
63
+
64
+ end
65
+
66
+ #Como el valor de gei está en 1 Kg, se hace la equivalencia a 100 gr
67
+ def getGeix100gr
68
+ (@gei * 100).round(2)
69
+ end
70
+
71
+ #Retorna un índice de huella de carbono según la cantidad en gr del alimento
72
+ def getIndiceHuellaCarbono(cantidad)
73
+
74
+ gases = self.getGeix100gr * cantidad
75
+
76
+ if(gases < 800)
77
+ return 1
78
+ elsif(gases < 1200)
79
+ return 2
80
+ else
81
+ return 3
82
+ end
83
+
84
+ end
85
+
86
+ #Retorna un nuevo Alimento resultado de la suma de otros dos alimentos
87
+ def +(other)
88
+
89
+ proNew = (other.proteinas + @proteinas).round(2)
90
+ carboNew = (other.carbohidratos + @carbohidratos).round(2)
91
+ lipNew = (other.lipidos + @lipidos).round(2)
92
+ geiNew = (other.gei + @gei).round(2)
93
+ terNew = (other.terreno + @terreno).round(2)
94
+
95
+ Alimento.new("combinado", proNew, carboNew, lipNew, geiNew, terNew)
96
+
97
+ end
98
+
99
+ #Retorna un nuevo Alimento resultado de la multiplicación de un Alimento por un escalar
100
+ def *(value)
101
+
102
+ proNew = (@proteinas * value).round(2)
103
+ carboNew = (@carbohidratos * value).round(2)
104
+ lipNew = (@lipidos * value).round(2)
105
+ geiNew = (@gei * value).round(2)
106
+ terNew = (@terreno * value).round(2)
107
+
108
+ Alimento.new(@nombre, proNew, carboNew, lipNew, geiNew, terNew)
109
+
110
+ end
111
+
112
+ end
@@ -0,0 +1,275 @@
1
+ =begin
2
+ Es una abstración de una lista doblemente enlazada, es decir se puede recorrer en ambos
3
+ sentidos. En otras palabras, se puede ver como una aproximación de array.
4
+ Tiene un puntero a cada extremo de la lista:
5
+ * Puntero al nodo cabeza
6
+ * Puntero al nodo cola
7
+ =end
8
+ class Lista
9
+
10
+ include Enumerable
11
+
12
+ attr_reader :head, :tail
13
+
14
+ def initialize(head = nil, tail = nil, arrayElementos = nil)
15
+ @head = head
16
+ @tail = tail
17
+
18
+ if(arrayElementos != nil)
19
+ self.pushAll(arrayElementos)
20
+ end
21
+ end
22
+
23
+ #Inserta un elemento por la cola
24
+ def push (elemento)
25
+ nodoNuevo = Nodo.new(elemento)
26
+
27
+ #La lista está vacia
28
+ if(@head == nil)
29
+ @head = nodoNuevo
30
+ else
31
+ #Agrega el nuevo nodo al final de una lista no vacia
32
+ @tail.next=(nodoNuevo)
33
+ nodoNuevo.prev=(@tail)
34
+ end
35
+
36
+ #Actualiza la cola
37
+ @tail = nodoNuevo
38
+
39
+ end
40
+
41
+ #Inserta varios elementos por la cola
42
+ def pushAll(arrayElementos)
43
+ arrayElementos.each do |elemento|
44
+ push(elemento)
45
+ end
46
+ end
47
+
48
+ #Inserta un elemento por la cabeza
49
+ def unshift (elemento)
50
+
51
+ nodoNuevo = Nodo.new(elemento)
52
+
53
+ #La lista está vacia
54
+ if(@head == nil)
55
+ @tail = nodoNuevo
56
+ else
57
+ #Agrega el nuevo nodo al principio de una lista no vacia
58
+ nodoNuevo.next=(@head)
59
+ @head.prev=(nodoNuevo)
60
+ end
61
+
62
+ #Actualiza la cabeza
63
+ @head = nodoNuevo
64
+
65
+ end
66
+
67
+ #Extae el último elemento
68
+ def pop
69
+
70
+ oldTail = @tail
71
+
72
+ #Existen mínimo 2 nodos
73
+ if( (@head != nil) && (@head.next != nil) )
74
+ @tail = @tail.prev
75
+ @tail.next=(nil)
76
+ oldTail.prev=(nil)
77
+ #Existe un solo nodo o ninguno
78
+ else
79
+ @head = nil
80
+ @tail = nil
81
+ end
82
+
83
+ oldTail
84
+
85
+ end
86
+
87
+ #Extae el primer elemento
88
+ def shift
89
+
90
+ oldHead = @head
91
+
92
+ #Existen mínimo 2 nodos
93
+ if( (@head != nil) && (@head.next != nil) )
94
+ @head = @head.next
95
+ @head.prev=(nil)
96
+ oldHead.next=(nil)
97
+ #Existe un solo nodo o ninguno
98
+ else
99
+ @head = nil
100
+ @tail = nil
101
+ end
102
+
103
+ oldHead
104
+
105
+ end
106
+
107
+ #Accede a un elemento dada la posición
108
+ def at(pos)
109
+
110
+ temp = nil
111
+
112
+ #En caso de que no exista la posición, se devuelve el valor nil
113
+ self.each_with_index do |elemento, index|
114
+ if(index == pos)
115
+ temp = elemento
116
+ break
117
+ end
118
+ end
119
+
120
+ temp
121
+
122
+ end
123
+
124
+ #Dos listas son iguales si tienen exactamente los mismos elementos y en el mismo orden
125
+ def ==(other)
126
+
127
+ if(self.cantNodos != other.cantNodos)
128
+ return false
129
+ else
130
+ self.each_with_index do |elemento, index|
131
+ if(elemento != other.at(index))
132
+ return false
133
+ end
134
+ end
135
+ end
136
+
137
+ return true
138
+
139
+ end
140
+
141
+ #Retorna verdadero si la lista está vacia, en otro caso retorna falso
142
+ def isVacia
143
+ if(cantNodos == 0)
144
+ return true
145
+ end
146
+
147
+ return false
148
+ end
149
+
150
+ #Devuelve la cantidad de elementos
151
+ def cantNodos
152
+ total = 0
153
+ temp = @head
154
+
155
+ while(temp != nil)
156
+ temp = temp.next
157
+ total += 1
158
+ end
159
+
160
+ total
161
+
162
+ end
163
+
164
+ #Retorna en porcenataje el aporte de proteinas en el valor energético
165
+ def getProcentajeProteinas
166
+
167
+ totalProteinas = 0
168
+ totalValorEnergetico = 0
169
+ temp = @head
170
+
171
+ while(temp != nil)
172
+ totalProteinas += temp.value.proteinas
173
+ totalValorEnergetico += temp.value.getValorEnergetico
174
+ temp = temp.next
175
+ end
176
+
177
+ ( (totalProteinas * 100 * 4) / totalValorEnergetico ).round(2)
178
+
179
+ end
180
+
181
+ #Retorna en porcenataje el aporte de carbohidratos en el valor energético
182
+ def getProcentajeCarbohidratos
183
+
184
+ totalCarbohidratos = 0
185
+ totalValorEnergetico = 0
186
+ temp = @head
187
+
188
+ while(temp != nil)
189
+ totalCarbohidratos += temp.value.carbohidratos
190
+ totalValorEnergetico += temp.value.getValorEnergetico
191
+ temp = temp.next
192
+ end
193
+
194
+ ( (totalCarbohidratos * 100 * 4) / totalValorEnergetico ).round(2)
195
+
196
+ end
197
+
198
+ #Retorna en porcenataje el aporte de lípidos en el valor energético
199
+ def getProcentajeLipidos
200
+
201
+ totalLipidos = 0
202
+ totalValorEnergetico = 0
203
+ temp = @head
204
+
205
+ while(temp != nil)
206
+ totalLipidos += temp.value.lipidos
207
+ totalValorEnergetico += temp.value.getValorEnergetico
208
+ temp = temp.next
209
+ end
210
+
211
+ ( (totalLipidos * 100 * 9) / totalValorEnergetico ).round(2)
212
+
213
+ end
214
+
215
+ #Retorna los gases de efecto invernadero producidos en un día
216
+ def getGeiDiario
217
+
218
+ totalGei = 0
219
+ temp = @head
220
+
221
+ while(temp != nil)
222
+ totalGei += temp.value.gei
223
+ temp = temp.next
224
+ end
225
+
226
+ totalGei.round(2)
227
+
228
+ end
229
+
230
+ #Retorna los gases de efecto invernadero producidos en un año
231
+ def getGeiAnual
232
+ (getGeiDiario * 365).round(2)
233
+ end
234
+
235
+ #Retorna el uso de terreno en un año
236
+ def getTerrenoTotal
237
+
238
+ totalTerreno = 0
239
+ temp = @head
240
+
241
+ while(temp != nil)
242
+ totalTerreno += temp.value.terreno
243
+ temp = temp.next
244
+ end
245
+
246
+ totalTerreno.round(2)
247
+
248
+ end
249
+
250
+ #Retorna la Lista formateada
251
+ def to_s
252
+
253
+ salida = []
254
+
255
+ self.each do |elemento|
256
+ salida << elemento
257
+ end
258
+
259
+ "[" + salida.join(" <-> ") + "]"
260
+
261
+ end
262
+
263
+ #Implementación del método each para utilizar los demás métodos del módulo enumerable
264
+ def each
265
+
266
+ temp = @head
267
+
268
+ while(temp != nil)
269
+ yield temp.value
270
+ temp = temp.next
271
+ end
272
+
273
+ end
274
+
275
+ end
@@ -0,0 +1,92 @@
1
+ class MenuDSL
2
+
3
+ def initialize(nombre, &block)
4
+
5
+ @nombre = nombre
6
+ @descripcion = ""
7
+ @listaPlatos = []
8
+ @listaPrecios = []
9
+ @precioTotal = 0
10
+
11
+ if block_given?
12
+
13
+ # Baja y sube para analizar cada linea
14
+ if block.arity == 1
15
+ yield self
16
+ # Solo sube una vez, todo el bloque se interpreta
17
+ else
18
+ instance_eval(&block)
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ # Asignar una descripción al menú
26
+ def descripcion(desc = "")
27
+ @descripcion = desc
28
+ end
29
+
30
+ # Valida si un componente tiene las características válidas
31
+ def componenteValido(comp)
32
+
33
+ if !comp[:plato]
34
+ return 0
35
+ elsif !comp[:precio]
36
+ return 0
37
+ end
38
+
39
+ return 1
40
+
41
+ end
42
+
43
+ # Asignar un componente a partir de un hash
44
+ def componente(comp = {})
45
+
46
+ if componenteValido(comp) == 1
47
+
48
+ @listaPlatos << comp[:plato]
49
+ @listaPrecios << comp[:precio]
50
+
51
+ end
52
+
53
+ end
54
+
55
+ # Asignar el precio del menú
56
+ def precio(prec = 0)
57
+ @precioTotal = prec
58
+ end
59
+
60
+ # Formatea el menú en un string
61
+ def to_s
62
+
63
+ cantDecimales = '%.2f'
64
+
65
+ output = "#{@nombre}\n"
66
+ #output << "#{'=' * @nombre.size}\n"
67
+ output << "Descripcion: #{@descripcion}\n"
68
+ output << "Precio: #{cantDecimales % @precioTotal}\n"
69
+ output << "============\n\n"
70
+
71
+ output << "Platos:\n\n"
72
+
73
+ @listaPlatos.each_with_index do |plato, index|
74
+ energia = plato.getValorEnergeticoPlato()
75
+ gei = plato.getGeiDiarioPlato()
76
+
77
+ output << "#{index + 1}) #{plato.nombre}\n"
78
+
79
+ alimentos = plato.listaAlimentos
80
+ nombresAlimentos = alimentos.map{|alim| alim.nombre}
81
+ output << "Componentes: #{nombresAlimentos.join(', ')}\n"
82
+
83
+ output << "Valor Nutricional: #{cantDecimales % energia} kcal\n"
84
+ output << "Valor Ambiental: #{cantDecimales % gei} kgCO2\n"
85
+ output << "Precio: #{cantDecimales % @listaPrecios[index]}\n\n"
86
+ end
87
+
88
+ output
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,7 @@
1
+ =begin
2
+ Define la estructura de un nodo
3
+ * Valor
4
+ * Puntero al nodo proximo
5
+ * Puntero al nodo previo
6
+ =end
7
+ Nodo = Struct.new(:value, :next, :prev)
@@ -0,0 +1,100 @@
1
+ =begin
2
+ Es una clase hija de PlatoNutricional, encapsula los métodos ambientales de un Plato.
3
+ Al igual que en la clase padre, se define un nombre, lista de alimentos y lista de
4
+ cantidades, que son inicializadas en el initialize de la clase padre con super
5
+ =end
6
+ class PlatoAmbiental < PlatoNutricional
7
+
8
+ def initialize(nombre, listaAlimentos, listaCantidades)
9
+ super(nombre, listaAlimentos, listaCantidades)
10
+ end
11
+
12
+ #Retorna los gases de efecto invernadero producidos en un día por un plato
13
+ def getGeiDiarioPlato
14
+
15
+ geiTotal = 0
16
+
17
+ alimentoWithCantidad = @listaAlimentos.zip(@listaCantidades)
18
+
19
+ alimentosMultiplicados = alimentoWithCantidad.map do |alimento, cantidad|
20
+ alimento * cantidad
21
+ end
22
+
23
+ geiTotal = alimentosMultiplicados.reduce(:+).gei
24
+ geiTotal.round(2)
25
+
26
+ end
27
+
28
+ #Retorna los gases de efecto invernadero producidos en un año por un plato
29
+ def getGeiAnualPlato
30
+ (self.getGeiDiarioPlato * 365).round(2)
31
+ end
32
+
33
+ #Retorna el uso de terreno producido en un año por un plato
34
+ def getTerrenoPlato
35
+
36
+ terrenoTotal = 0
37
+
38
+ @listaAlimentos.each_with_index do |alimento, index|
39
+ terrenoTotal += alimento.terreno * @listaCantidades.at(index)
40
+ end
41
+
42
+ terrenoTotal.round(2)
43
+
44
+ end
45
+
46
+ #Se calcula la relación GEI/valorEnegertico y la retorna formateada
47
+ def getEficienciaEnergeticaFormateada
48
+
49
+ salida = []
50
+ eficienciaTotal = 0
51
+
52
+ @listaAlimentos.each_with_index do |elemento, index|
53
+ energia = @listaCantidades.at(index) * elemento.getValorEnergetico
54
+ gei = @listaCantidades.at(index) * elemento.gei
55
+
56
+ #GEI pruducidos por 1 kcal de un alimento
57
+ eficiencia = (gei/energia).round(2)
58
+ eficienciaTotal += eficiencia
59
+
60
+ salida << eficiencia
61
+ end
62
+
63
+ "[" + @nombre + " " + eficienciaTotal.round(2).to_s + " [" + salida.join(" ") + "]]"
64
+
65
+ end
66
+
67
+ #Compara dos Platos según la huella nutricional
68
+ def <=>(other)
69
+ #-1 si left < right
70
+ # 0 si left == right
71
+ # 1 si left > right
72
+ self.huellaNutricional <=> other.huellaNutricional
73
+ end
74
+
75
+
76
+ #Retorna un número en el rango [1,3] que corresponde a la huella nutricional de un plato
77
+ def huellaNutricional
78
+
79
+ alimentoWithCantidad = @listaAlimentos.zip(@listaCantidades)
80
+
81
+ #Energia
82
+ energia = alimentoWithCantidad.map do |alimento, cantidad|
83
+ alimento.getIndiceEnergia(cantidad)
84
+ end
85
+
86
+ #Huella Carbono
87
+ carbono = alimentoWithCantidad.map do |alimento, cantidad|
88
+ alimento.getIndiceHuellaCarbono(cantidad)
89
+ end
90
+
91
+ #Sumatorio
92
+ dividendo = energia.reduce(:+) + carbono.reduce(:+)
93
+ divisor = energia.size * 2.0
94
+ #Nota: Se divide entre la cantidad de indices
95
+
96
+ (dividendo / divisor).round(2)
97
+
98
+ end
99
+
100
+ end
@@ -0,0 +1,89 @@
1
+ class PlatoDSL
2
+
3
+ def initialize(nombre, &block)
4
+
5
+ @nombre = nombre
6
+ @listaAlimentos = []
7
+ @listaCantidades = []
8
+
9
+ if block_given?
10
+
11
+ # Baja y sube para analizar cada linea
12
+ if block.arity == 1
13
+ yield self
14
+ # Solo sube una vez, todo el bloque se interpreta
15
+ else
16
+ instance_eval(&block)
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ # Valida que un hash tenga todos los atributos para crear un alimento valido
24
+ def alimentoValido(alim)
25
+
26
+ if !alim[:nombre]
27
+ return 0
28
+ elsif !alim[:proteinas]
29
+ return 0
30
+ elsif !alim[:carbohidratos]
31
+ return 0
32
+ elsif !alim[:lipidos]
33
+ return 0
34
+ elsif !alim[:gei]
35
+ return 0
36
+ elsif !alim[:terreno]
37
+ return 0
38
+ elsif !alim[:gramos]
39
+ return 0
40
+ end
41
+
42
+ return 1
43
+
44
+ end
45
+
46
+ # Crea un alimento a partir de un DLS
47
+ def alimento(alim = {})
48
+
49
+ # Alimento valido
50
+ if alimentoValido(alim) == 1
51
+ nom = alim[:nombre]
52
+ pro = alim[:proteinas]
53
+ car = alim[:carbohidratos]
54
+ lip = alim[:lipidos]
55
+ gei = alim[:gei]
56
+ ter = alim[:terreno]
57
+
58
+ alimento = Alimento.new(nom, pro, car, lip, gei, ter)
59
+ @listaAlimentos << alimento
60
+
61
+ @listaCantidades << alim[:gramos]
62
+ end
63
+
64
+ end
65
+
66
+ # Formatea el menú en un string
67
+ def to_s
68
+
69
+ cantDecimales = '%.2f'
70
+
71
+ output = "#{@nombre}\n"
72
+ output << "#{'=' * @nombre.size}\n\n"
73
+
74
+ output << "Ingedientes:\n\n"
75
+
76
+ @listaAlimentos.each_with_index do |alim, index|
77
+ energia = alim.getValorEnergeticoConGramos(@listaCantidades[index])
78
+
79
+ output << "#{index + 1}) #{alim.nombre}\n"
80
+ output << "Cantidad: #{cantDecimales % @listaCantidades[index]}\n"
81
+ output << "Valor Nutricional: #{cantDecimales % energia} kcal\n"
82
+ output << "Valor Ambiental: #{cantDecimales % alim.gei} kgCO2\n\n"
83
+ end
84
+
85
+ output
86
+
87
+ end
88
+
89
+ end