foodAX 3.3.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.
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "food"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "foodAX"
8
+ spec.version = FoodGem::VERSION
9
+ spec.authors = ["Angel Igareta"]
10
+ spec.email = ["alu0100967111@ull.edu.es"]
11
+
12
+ spec.summary = %q{Practicas TDD.}
13
+ spec.description = %q{Practica dessarrollada dirigida a pruebas TDD.}
14
+ spec.homepage = "https://github.com/ULL-ESIT-LPP-1718/tdd-alu0100967111"
15
+ spec.license = "MIT"
16
+
17
+ # For uploading it --> http://guides.rubygems.org/make-your-own-gem/
18
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
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
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.15"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+
37
+ spec.add_development_dependency "guard"
38
+ spec.add_development_dependency "guard-rspec"
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"
44
+
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
+ }
@@ -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
@@ -0,0 +1,12 @@
1
+ require "food/version"
2
+ require "food/food_class"
3
+ require "food/dll"
4
+ require "food/sort"
5
+ require "food/functions"
6
+
7
+ require "dsl/harvard_dish"
8
+ require 'terminal-table'
9
+
10
+ # Root Module for the Gem
11
+ # @author Angel Igareta (alu0100967111@ull.edu.es)
12
+ module FoodGem; end
@@ -0,0 +1,168 @@
1
+ # Double Linked List Class
2
+
3
+ # Class Doubly Linked List
4
+ module DLLModule
5
+
6
+ # Struct Node for Doubly Linked List
7
+ Node = Struct.new(:value, :next, :prev)
8
+
9
+ # Class Doubly Linked List
10
+ class DLL
11
+
12
+ # Including Enumerable Module
13
+ include Enumerable
14
+
15
+ # @attr_reader size [int] size of the doubly linked list
16
+ attr_reader :size
17
+
18
+ # Constructor of DLL
19
+ # @param value of Node
20
+ # @param head [Node] Head of the DLL
21
+ # @param tail [Node] Tail of the DLL
22
+ # @param size [int] size of the doubly linked list
23
+ def initialize (value = nil)
24
+ node = Node.new(value)
25
+
26
+ @head = node
27
+ @tail = node
28
+ @size = (node.nil?) ? 0 : 1
29
+ end
30
+
31
+ public
32
+
33
+ # Insert element in DLL head
34
+ # @param *value_array[array] set of values
35
+ def insert_head (*value_array)
36
+ value_array.each { |value|
37
+ node = Node.new(value)
38
+ insert_head_private(node);
39
+ }
40
+ end
41
+
42
+ # Insert element in DLL tail
43
+ # @param *value_array[array] set of values
44
+ def insert_tail (*value_array)
45
+ value_array.each { |value|
46
+ node = Node.new(value)
47
+ insert_tail_private(node);
48
+ }
49
+ end
50
+
51
+ # Extract element in DLL head
52
+ # @return [Node] value of the node that was in the head
53
+ def extract_head
54
+ if @head.nil?
55
+ return nil
56
+ else
57
+ @size -= 1
58
+
59
+ node_to_return = @head
60
+
61
+ @head = @head.next
62
+ @head.prev = nil
63
+
64
+ node_to_return.next = nil
65
+ return node_to_return.value
66
+ end
67
+ end
68
+
69
+ # Extract element in DLL tail
70
+ # @return [Node] value of the node that was in the tail
71
+ def extract_tail
72
+ if @tail.nil?
73
+ return nil
74
+ else
75
+ @size -= 1
76
+
77
+ node_to_return = @tail
78
+
79
+ @tail = @tail.prev
80
+ @tail.next = nil
81
+
82
+ node_to_return.prev = nil
83
+ return node_to_return.value
84
+ end
85
+ end
86
+
87
+ # Delete an specific element in DLL head
88
+ def delete (value)
89
+ current_node = @head
90
+
91
+ while !current_node.nil?
92
+ if (current_node.value == value)
93
+ if (@size == 1)
94
+ @head = nil
95
+ @tail = nil
96
+ current_node = nil
97
+ else
98
+ if current_node != @head
99
+ (current_node.prev).next = current_node.next
100
+ end
101
+ if current_node != @tail
102
+ (current_node.next).prev = current_node.prev
103
+ end
104
+ current_node = nil
105
+ end
106
+ @size -= 1
107
+ else
108
+ current_node = current_node.next
109
+ end
110
+ end
111
+ end
112
+
113
+ # Return head value
114
+ # @return [head(#value)]
115
+ def get_head
116
+ return @head.value
117
+ end
118
+
119
+ # Return tail value
120
+ # @return [tail(#value)]
121
+ def get_tail
122
+ return @tail.value
123
+ end
124
+
125
+ # Return if DLL is empty
126
+ def empty?
127
+ return size == 0
128
+ end
129
+
130
+ # Essential method for Enumerable
131
+ def each
132
+ current_node = @head
133
+
134
+ while !current_node.nil?
135
+ yield current_node.value
136
+ current_node = current_node.next
137
+ end
138
+ end
139
+
140
+ private
141
+
142
+ def insert_head_private (node)
143
+ if @head.nil?
144
+ @head = node
145
+ @tail = node
146
+ else
147
+ node.next = @head
148
+ @head.prev = node
149
+ @head = node
150
+ end
151
+ @size += 1
152
+ end
153
+
154
+ def insert_tail_private (node)
155
+ if @tail.nil?
156
+ @head = node
157
+ @tail = node
158
+ else
159
+ @tail.next = node
160
+ node.prev = @tail
161
+ @tail = node
162
+ end
163
+ @size += 1
164
+ end
165
+
166
+ end
167
+
168
+ end
@@ -0,0 +1,139 @@
1
+ # Constants of energy
2
+ # @param PROTEIN_ENERGY [int] protein energy.
3
+ # @param GLUCID_ENERGY [int] glucid energy.
4
+ # @param LIPID_ENERGY [int] lipid energy
5
+ GLUCID_ENERGY = 4
6
+ LIPID_ENERGY = 9
7
+ PROTEIN_ENERGY = 4
8
+
9
+ # Abstract class for Food
10
+ class FoodAbstract
11
+
12
+ # @attr_reader name [String] name the name of the food
13
+ # @attr_reader protein_quantity [pair] pair of protein number and energy
14
+ # @attr_reader glucid_quantity [pair] pair of glucid number and energy
15
+ # @attr_reader lipid_quantity [pair] pair of lipid number and energy
16
+ # @attr_reader energetic_content [double] energetic content of the food
17
+ attr_reader :name, :protein_quantity, :glucid_quantity, :lipid_quantity, :energetic_content, :glucemic_
18
+
19
+ # Constructor of Abstract Food for allowing the childs to call it.
20
+ # @param name [String] the name for the food.
21
+ # @param protein_energy_pair [pair] pair of protein number and energy.
22
+ # @param glucid_energy_pair [pair] pair of glucid number and energy
23
+ # @param lipid_energy_pair [pair] pair of lipid number and energy
24
+ # @param lipid_energy_pair [pair] pair of lipid number and energy
25
+ def initialize (name, protein_energy_pair, glucid_energy_pair, lipid_energy_pair)
26
+ raise unless name.is_a? String
27
+ raise unless ((protein_energy_pair.is_a? Array) && (glucid_energy_pair.is_a? Array) && (lipid_energy_pair.is_a? Array))
28
+ raise unless ((protein_energy_pair.count == 2) && (glucid_energy_pair.count == 2) && (lipid_energy_pair.count == 2))
29
+
30
+ protein_energy_pair.each { |element| raise unless element.is_a?(Integer) || element.is_a?(Float) }
31
+ glucid_energy_pair.each { |element| raise unless element.is_a?(Integer) || element.is_a?(Float) }
32
+ lipid_energy_pair.each { |element| raise unless element.is_a?(Integer) || element.is_a?(Float) }
33
+
34
+ @name = name.capitalize
35
+ @protein_quantity = protein_energy_pair[0]
36
+ @glucid_quantity = glucid_energy_pair[0]
37
+ @lipid_quantity = lipid_energy_pair[0]
38
+
39
+ # Vector de pares, pues hash no permite iguales
40
+ @pair_macronutrient_energy = []
41
+ @pair_macronutrient_energy.push([protein_energy_pair[0], protein_energy_pair[1]])
42
+ @pair_macronutrient_energy.push([glucid_energy_pair[0], glucid_energy_pair[1]])
43
+ @pair_macronutrient_energy.push([lipid_energy_pair[0], lipid_energy_pair[1]])
44
+
45
+ @energetic_content = calculate_energetic_content.round(3)
46
+ end
47
+
48
+ # Calculates the energetic content for the food
49
+ # @return [double] energetic_content
50
+ def calculate_energetic_content
51
+ energetic_content = 0
52
+ @pair_macronutrient_energy.each{ |macronutrient, energy| energetic_content += (macronutrient * energy) }
53
+ return energetic_content
54
+ end
55
+
56
+ # Return string with the output for the food
57
+ # @return [String] outpout of food
58
+ def to_s
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
66
+ end
67
+
68
+ end
69
+
70
+ # Class for Food that inherit FoodAbstract
71
+ class Food < FoodAbstract
72
+
73
+ # Including Comparable Module
74
+ include Comparable
75
+
76
+ # @attr_reader group_name [String] name the name of the food group
77
+ attr_reader :group_name
78
+
79
+ # Constructor of Food with the group name
80
+ # @param name [String] the name for the food.
81
+ # @param protein_energy_pair [pair] pair of protein number and energy.
82
+ # @param glucid_energy_pair [pair] pair of glucid number and energy
83
+ # @param lipid_energy_pair [pair] pair of lipid number and energy
84
+ # @param group_name [String] the name for the food group.
85
+ def initialize(name, protein_energy_pair, glucid_energy_pair, lipid_energy_pair, group_name = "", gluc_sample_pair_array = [])
86
+ @group_name = group_name
87
+ super(name, protein_energy_pair, glucid_energy_pair, lipid_energy_pair)
88
+
89
+ @aibc_food_array = [] # The AIBC of this food for each person
90
+ @aibc_glucose_array = [] # The AIBC of glucose for each person
91
+ @ig_array = [] # The IG of this food for each person
92
+
93
+ gluc_sample_pair_array.each { |person_array|
94
+ @aibc_food_array.push(calculate_aibc(person_array[0])) # First is the samples of this food for a person
95
+ @aibc_glucose_array.push(calculate_aibc(person_array[1])) # First is the samples of glucose for a person
96
+ @ig_array.push(calculate_ig_for_person(@aibc_food_array.size))
97
+ }
98
+ end
99
+
100
+ private
101
+
102
+ def calculate_aibc(sample_array)
103
+ (1...sample_array.size).map{|i| ((sample_array[i] + sample_array[i-1] - 2*sample_array[0]) / 2) * 5}.reduce(:+)
104
+ end
105
+
106
+ def calculate_ig_for_person(person_number)
107
+ return ((@aibc_food_array[person_number-1] / @aibc_glucose_array[person_number-1]) * 100)
108
+ end
109
+
110
+ public
111
+
112
+ def get_aibc_of_person(person_number)
113
+ return @aibc_food_array[person_number-1]
114
+ end
115
+
116
+ def get_ig_of_person(person_number)
117
+ return @ig_array[person_number-1]
118
+ end
119
+
120
+ def get_ig
121
+ return (@ig_array.reduce(:+) / @ig_array.size)
122
+ end
123
+
124
+ # Return string with the output for the food calling the father
125
+ # @return [String] output of food
126
+ def to_s
127
+ return ("Grupo: #{@group_name} | " + super) if (@group_name != "")
128
+ super
129
+ end
130
+
131
+ # Essential comparating for using Comparable Module
132
+ # @return [String] Return which food is higher depending on the enrgetic content
133
+ def <=> (food)
134
+ raise unless food.is_a?Food
135
+ # return self.energetic_content <=> food.energetic_content
136
+ return self.name <=> food.name
137
+ end
138
+
139
+ end