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.
- checksums.yaml +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +97 -0
- data/Guardfile +82 -0
- data/README.md +48 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/docs/Alimento.html +627 -0
- data/docs/Gemfile.html +98 -0
- data/docs/Gemfile_lock.html +179 -0
- data/docs/Guardfile.html +165 -0
- data/docs/Huella/Error.html +103 -0
- data/docs/Huella.html +114 -0
- data/docs/Lista.html +981 -0
- data/docs/Object.html +337 -0
- data/docs/PlatoAmbiental.html +436 -0
- data/docs/PlatoNutricional.html +517 -0
- data/docs/README_md.html +146 -0
- data/docs/Rakefile.html +100 -0
- data/docs/bin/setup.html +100 -0
- data/docs/created.rid +24 -0
- data/docs/css/fonts.css +167 -0
- data/docs/css/rdoc.css +590 -0
- data/docs/fonts/Lato-Light.ttf +0 -0
- data/docs/fonts/Lato-LightItalic.ttf +0 -0
- data/docs/fonts/Lato-Regular.ttf +0 -0
- data/docs/fonts/Lato-RegularItalic.ttf +0 -0
- data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
- data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
- data/docs/huella_gemspec.html +133 -0
- data/docs/images/add.png +0 -0
- data/docs/images/arrow_up.png +0 -0
- data/docs/images/brick.png +0 -0
- data/docs/images/brick_link.png +0 -0
- data/docs/images/bug.png +0 -0
- data/docs/images/bullet_black.png +0 -0
- data/docs/images/bullet_toggle_minus.png +0 -0
- data/docs/images/bullet_toggle_plus.png +0 -0
- data/docs/images/date.png +0 -0
- data/docs/images/delete.png +0 -0
- data/docs/images/find.png +0 -0
- data/docs/images/loadingAnimation.gif +0 -0
- data/docs/images/macFFBgHack.png +0 -0
- data/docs/images/package.png +0 -0
- data/docs/images/page_green.png +0 -0
- data/docs/images/page_white_text.png +0 -0
- data/docs/images/page_white_width.png +0 -0
- data/docs/images/plugin.png +0 -0
- data/docs/images/ruby.png +0 -0
- data/docs/images/tag_blue.png +0 -0
- data/docs/images/tag_green.png +0 -0
- data/docs/images/transparent.png +0 -0
- data/docs/images/wrench.png +0 -0
- data/docs/images/wrench_orange.png +0 -0
- data/docs/images/zoom.png +0 -0
- data/docs/index.html +117 -0
- data/docs/js/darkfish.js +161 -0
- data/docs/js/jquery.js +4 -0
- data/docs/js/navigation.js +141 -0
- data/docs/js/navigation.js.gz +0 -0
- data/docs/js/search.js +109 -0
- data/docs/js/search_index.js +1 -0
- data/docs/js/search_index.js.gz +0 -0
- data/docs/js/searcher.js +229 -0
- data/docs/js/searcher.js.gz +0 -0
- data/docs/table_of_contents.html +378 -0
- data/huella.gemspec +38 -0
- data/lib/huella/alimento.rb +112 -0
- data/lib/huella/lista.rb +275 -0
- data/lib/huella/menu_dsl.rb +92 -0
- data/lib/huella/nodo.rb +7 -0
- data/lib/huella/plato_ambiental.rb +100 -0
- data/lib/huella/plato_dsl.rb +89 -0
- data/lib/huella/plato_nutricional.rb +102 -0
- data/lib/huella/version.rb +4 -0
- data/lib/huella.rb +14 -0
- 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
|
data/lib/huella/lista.rb
ADDED
|
@@ -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
|
data/lib/huella/nodo.rb
ADDED
|
@@ -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
|