foodAX 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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