nutrition_calculator 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb7c8df58d699d0f69ba05ba196c2ffe55f1976e
4
+ data.tar.gz: d3185d82f8c2dd202a37a6e17e5ce4a05978840b
5
+ SHA512:
6
+ metadata.gz: b1e6934c01fe8b9586d8b6e2bb88d9d7400f2fe8f1993eac742f19beb7014ea17ef694cb91705c6ddac4280f64306cc2fc2abca551e44b3d3dd2a5c8b7c8409a
7
+ data.tar.gz: e195e994cb4700b66cbb827ab32f6578b88f113a3884c6e4f120139fc92de83f0f6d5ba2994cd08f57bc523d6cb5cbdccd22c90a49d2e6cd714673a6780ea3fc
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format progress
2
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.5
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nutrition_calculator.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 John Wilger
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # NutritionCalculator
2
+
3
+ NutritionCalculator provides a set of core libraries to help track a
4
+ person's individual nutritional goals. It is meant to aid in both
5
+ weight-management and monitoring the nutritional balance of a diet.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'nutrition_calculator'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install nutrition_calculator
22
+
23
+ ## Usage
24
+
25
+ See {NutritionCalculator::CalorieBudgeter}
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( https://github.com/[my-github-username]/nutrition_calculator/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "cucumber/rake/task"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ desc "Run all cucumber features"
8
+ task :features => 'features:default'
9
+
10
+ namespace :features do
11
+ task :default => %w(wip ok)
12
+
13
+ Cucumber::Rake::Task.new(:wip) do |t|
14
+ t.cucumber_opts = "-t @wip"
15
+ end
16
+
17
+ Cucumber::Rake::Task.new(:ok) do |t|
18
+ t.cucumber_opts = "-t ~@wip -t ~@pending -q --format progress"
19
+ end
20
+ end
21
+
22
+ task :default => %w(spec features)
23
+
@@ -0,0 +1,181 @@
1
+ Feature: Calculate Remaining Daily Calories
2
+
3
+ So that I know how much more I should eat today in order to hit my weekly calorie goal,
4
+ As a dieter,
5
+ I want to see my remaining calories for the day, taking into account what I have already consumed this week
6
+
7
+ Scenario Outline: Maintain Weight
8
+ Given my RMR is <daily_rmr> calories per day
9
+ And my weekly calorie goal is <weekly_goal> calories
10
+ And I have consumed <prev_days_cal> net calories on prior days this week
11
+ And it is the <day> day of the week
12
+ And I have consumed <consumed> calories today
13
+ And I have burned <burned> calories with exercise today
14
+
15
+ When I calculate my remaining calories for the day
16
+
17
+ Then I see that my net calorie consumption for the day is <net>
18
+ And I see that I should consume <remaining> more calories today
19
+ And I see that I should burn <to_burn> more calories by exercising today
20
+
21
+ Examples: RMR 1500
22
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
23
+ | 1500 | 10500 | 0 | 1st | 0 | 0 | 0 | 1500 | 0 |
24
+ | 1500 | 10500 | 0 | 1st | 500 | 0 | 500 | 1000 | 0 |
25
+ | 1500 | 10500 | 0 | 1st | 1500 | 0 | 1500 | 0 | 0 |
26
+ | 1500 | 10500 | 0 | 1st | 1501 | 0 | 1501 | 0 | 1 |
27
+
28
+ Examples: RMR 1500 - with exercise
29
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
30
+ | 1500 | 10500 | 0 | 1st | 0 | 100 | -100 | 1600 | 0 |
31
+ | 1500 | 10500 | 0 | 1st | 500 | 100 | 400 | 1100 | 0 |
32
+ | 1500 | 10500 | 0 | 1st | 1600 | 100 | 1500 | 0 | 0 |
33
+ | 1500 | 10500 | 0 | 1st | 1601 | 100 | 1501 | 0 | 1 |
34
+
35
+ Examples: RMR 1500 - 2nd day of week
36
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
37
+ | 1500 | 10500 | 1500 | 2nd | 0 | 0 | 0 | 1500 | 0 |
38
+ | 1500 | 10500 | 1503 | 2nd | 0 | 0 | 0 | 1500 | 0 |
39
+ | 1500 | 10500 | 1504 | 2nd | 0 | 0 | 0 | 1500 | 1 |
40
+ | 1500 | 10500 | 1504 | 2nd | 500 | 100 | 400 | 1099 | 0 |
41
+ | 1500 | 10500 | 1504 | 2nd | 1500 | 0 | 1500 | 0 | 1 |
42
+ | 1500 | 10500 | 1504 | 2nd | 1600 | 100 | 1500 | 0 | 1 |
43
+
44
+ Examples: RMR 2000
45
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
46
+ | 2000 | 14000 | 0 | 1st | 0 | 0 | 0 | 2000 | 0 |
47
+ | 2000 | 14000 | 0 | 1st | 500 | 0 | 500 | 1500 | 0 |
48
+ | 2000 | 14000 | 0 | 1st | 2000 | 0 | 2000 | 0 | 0 |
49
+ | 2000 | 14000 | 0 | 1st | 2001 | 0 | 2001 | 0 | 1 |
50
+
51
+ Examples: RMR 2000 - with exercise
52
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
53
+ | 2000 | 14000 | 0 | 1st | 0 | 100 | -100 | 2100 | 0 |
54
+ | 2000 | 14000 | 0 | 1st | 500 | 100 | 400 | 1600 | 0 |
55
+ | 2000 | 14000 | 0 | 1st | 2100 | 100 | 2000 | 0 | 0 |
56
+ | 2000 | 14000 | 0 | 1st | 2101 | 100 | 2001 | 0 | 1 |
57
+
58
+ Examples: RMR 2000 - 2nd day of week
59
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
60
+ | 2000 | 14000 | 1997 | 2nd | 0 | 0 | 0 | 2001 | 0 |
61
+ | 2000 | 14000 | 1998 | 2nd | 0 | 0 | 0 | 2000 | 0 |
62
+ | 2000 | 14000 | 2000 | 2nd | 0 | 0 | 0 | 2000 | 0 |
63
+ | 2000 | 14000 | 2003 | 2nd | 0 | 0 | 0 | 2000 | 0 |
64
+ # must consume at lease RMR every day and you should exercise off the overage
65
+ | 2000 | 14000 | 2004 | 2nd | 0 | 0 | 0 | 2000 | 1 |
66
+ | 2000 | 14000 | 2004 | 2nd | 500 | 100 | 400 | 1599 | 0 |
67
+ | 2000 | 14000 | 2004 | 2nd | 2000 | 0 | 2000 | 0 | 1 |
68
+ | 2000 | 14000 | 2004 | 2nd | 2100 | 100 | 2000 | 0 | 1 |
69
+
70
+ Examples: 3rd day of week
71
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
72
+ | 2000 | 14000 | 3997 | 3rd | 0 | 0 | 0 | 2001 | 0 |
73
+ | 2000 | 14000 | 3998 | 3rd | 0 | 0 | 0 | 2000 | 0 |
74
+ | 2000 | 14000 | 4000 | 3rd | 0 | 0 | 0 | 2000 | 0 |
75
+ | 2000 | 14000 | 4002 | 3rd | 0 | 0 | 0 | 2000 | 0 |
76
+ | 2000 | 14000 | 4003 | 3rd | 0 | 0 | 0 | 2000 | 1 |
77
+
78
+ Examples: 4th day of week
79
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
80
+ | 2000 | 14000 | 5998 | 4th | 0 | 0 | 0 | 2001 | 0 |
81
+ | 2000 | 14000 | 5999 | 4th | 0 | 0 | 0 | 2000 | 0 |
82
+ | 2000 | 14000 | 6000 | 4th | 0 | 0 | 0 | 2000 | 0 |
83
+ | 2000 | 14000 | 6002 | 4th | 0 | 0 | 0 | 2000 | 0 |
84
+ | 2000 | 14000 | 6003 | 4th | 0 | 0 | 0 | 2000 | 1 |
85
+
86
+ Examples: 5th day of week
87
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
88
+ | 2000 | 14000 | 7998 | 5th | 0 | 0 | 0 | 2001 | 0 |
89
+ | 2000 | 14000 | 7999 | 5th | 0 | 0 | 0 | 2000 | 0 |
90
+ | 2000 | 14000 | 8000 | 5th | 0 | 0 | 0 | 2000 | 0 |
91
+ | 2000 | 14000 | 8001 | 5th | 0 | 0 | 0 | 2000 | 0 |
92
+ | 2000 | 14000 | 8002 | 5th | 0 | 0 | 0 | 2000 | 1 |
93
+
94
+ Examples: 6th day of week
95
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
96
+ | 2000 | 14000 | 9997 | 6th | 0 | 0 | 0 | 2002 | 0 |
97
+ | 2000 | 14000 | 9998 | 6th | 0 | 0 | 0 | 2001 | 0 |
98
+ | 2000 | 14000 | 9999 | 6th | 0 | 0 | 0 | 2001 | 0 |
99
+ | 2000 | 14000 | 10000 | 6th | 0 | 0 | 0 | 2000 | 0 |
100
+ | 2000 | 14000 | 10001 | 6th | 0 | 0 | 0 | 2000 | 0 |
101
+ | 2000 | 14000 | 10002 | 6th | 0 | 0 | 0 | 2000 | 1 |
102
+
103
+ Examples: 7th day of week
104
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
105
+ | 2000 | 14000 | 11999 | 7th | 0 | 0 | 0 | 2001 | 0 |
106
+ | 2000 | 14000 | 12000 | 7th | 0 | 0 | 0 | 2000 | 0 |
107
+ | 2000 | 14000 | 12001 | 7th | 0 | 0 | 0 | 2000 | 1 |
108
+
109
+ Scenario Outline: Lose Weight - must consume at least RMR daily
110
+ Given my RMR is <daily_rmr> calories per day
111
+ And my weekly calorie goal is <weekly_goal> calories
112
+ And I have consumed <prev_days_cal> net calories on prior days this week
113
+ And it is the <day> day of the week
114
+ And I have consumed <consumed> calories today
115
+ And I have burned <burned> calories with exercise today
116
+
117
+ When I calculate my remaining calories for the day
118
+
119
+ Then I see that my net calorie consumption for the day is <net>
120
+ And I see that I should consume <remaining> more calories today
121
+ And I see that I should burn <to_burn> more calories by exercising today
122
+
123
+ Examples: RMR 2000
124
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
125
+ | 2000 | 10500 | 0 | 1st | 0 | 0 | 0 | 2000 | 500 |
126
+ | 2000 | 10500 | 0 | 1st | 500 | 0 | 500 | 1500 | 500 |
127
+ | 2000 | 10500 | 0 | 1st | 2000 | 0 | 2000 | 0 | 500 |
128
+ | 2000 | 10500 | 0 | 1st | 2001 | 0 | 2001 | 0 | 501 |
129
+
130
+ Examples: RMR 2000 - with exercise
131
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
132
+ | 2000 | 10500 | 0 | 1st | 0 | 100 | -100 | 2000 | 400 |
133
+ | 2000 | 10500 | 0 | 1st | 500 | 100 | 400 | 1500 | 400 |
134
+ | 2000 | 10500 | 0 | 1st | 2100 | 100 | 2000 | 0 | 500 |
135
+ | 2000 | 10500 | 0 | 1st | 2101 | 100 | 2001 | 0 | 501 |
136
+ | 2000 | 10500 | 0 | 1st | 2000 | 500 | 1500 | 0 | 0 |
137
+ | 2000 | 10500 | 0 | 1st | 0 | 500 | -500 | 2000 | 0 |
138
+
139
+ Examples: 3rd day of week
140
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
141
+ | 2000 | 10500 | 3000 | 3rd | 0 | 0 | 0 | 2000 | 500 |
142
+ | 2000 | 10500 | 3997 | 3rd | 0 | 0 | 0 | 2000 | 699 |
143
+ | 2000 | 10500 | 3998 | 3rd | 0 | 0 | 0 | 2000 | 700 |
144
+ | 2000 | 10500 | 4000 | 3rd | 0 | 0 | 0 | 2000 | 700 |
145
+ | 2000 | 10500 | 4002 | 3rd | 0 | 0 | 0 | 2000 | 700 |
146
+ | 2000 | 10500 | 4003 | 3rd | 0 | 0 | 0 | 2000 | 701 |
147
+ | 2000 | 10500 | 4000 | 3rd | 2000 | 0 | 2000 | 0 | 700 |
148
+ | 2000 | 10500 | 4000 | 3rd | 2000 | 700 | 1300 | 0 | 0 |
149
+
150
+ Scenario Outline: Gain Weight
151
+ Given my RMR is <daily_rmr> calories per day
152
+ And my weekly calorie goal is <weekly_goal> calories
153
+ And I have consumed <prev_days_cal> net calories on prior days this week
154
+ And it is the <day> day of the week
155
+ And I have consumed <consumed> calories today
156
+ And I have burned <burned> calories with exercise today
157
+
158
+ When I calculate my remaining calories for the day
159
+
160
+ Then I see that my net calorie consumption for the day is <net>
161
+ And I see that I should consume <remaining> more calories today
162
+ And I see that I should burn <to_burn> more calories by exercising today
163
+
164
+ Examples: RMR 2000
165
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
166
+ | 2000 | 17500 | 0 | 1st | 0 | 0 | 0 | 2500 | 0 |
167
+ | 2000 | 17500 | 0 | 1st | 500 | 0 | 500 | 2000 | 0 |
168
+ | 2000 | 17500 | 0 | 1st | 2500 | 0 | 2500 | 0 | 0 |
169
+ | 2000 | 17500 | 0 | 1st | 2501 | 0 | 2501 | 0 | 1 |
170
+
171
+ Examples: RMR 2000 - with exercise
172
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
173
+ | 2000 | 17500 | 0 | 1st | 0 | 500 | -500 | 3000 | 0 |
174
+ | 2000 | 17500 | 0 | 1st | 2500 | 500 | 2000 | 500 | 0 |
175
+ | 2000 | 17500 | 0 | 1st | 3001 | 500 | 2501 | 0 | 1 |
176
+
177
+ Examples: 3rd day of week
178
+ | daily_rmr | weekly_goal | prev_days_cal | day | consumed | burned | net | remaining | to_burn |
179
+ | 2000 | 17500 | 4997 | 3rd | 0 | 0 | 0 | 2501 | 0 |
180
+ | 2000 | 17500 | 5000 | 3rd | 0 | 0 | 0 | 2500 | 0 |
181
+ | 2000 | 17500 | 5003 | 3rd | 0 | 0 | 0 | 2499 | 0 |
File without changes
@@ -0,0 +1,39 @@
1
+ Given(/^my RMR is (\d+) calories per day$/) do |rmr|
2
+ inputs.resting_metabolic_rate = rmr.to_i
3
+ end
4
+
5
+ Given(/^my weekly calorie goal is (\d+) calories$/) do |cals|
6
+ inputs.weekly_calorie_goal = cals.to_i
7
+ end
8
+
9
+ Given(/^I have consumed (\d+) net calories on prior days this week$/) do |cals|
10
+ inputs.prior_days_calories = cals.to_i
11
+ end
12
+
13
+ Given(/^it is the (\d+)(st|nd|rd|th) day of the week$/) do |day, _|
14
+ inputs.current_day_of_week = day.to_i
15
+ end
16
+
17
+ Given(/^I have consumed (\d+) calories today$/) do |cals|
18
+ inputs.calories_consumed = cals.to_i
19
+ end
20
+
21
+ Given(/^I have burned (\d+) calories with exercise today$/) do |cals|
22
+ inputs.calories_burned = cals.to_i
23
+ end
24
+
25
+ When(/^I calculate my remaining calories for the day$/) do
26
+ calculate_remaining_calories
27
+ end
28
+
29
+ Then(/^I see that my net calorie consumption for the day is (\-?\d+)$/) do |cals|
30
+ expect(outputs.net_calorie_consumption).to eq cals.to_i
31
+ end
32
+
33
+ Then(/^I see that I should consume (\d+) more calories today$/) do |cals|
34
+ expect(outputs.calories_remaining).to eq cals.to_i
35
+ end
36
+
37
+ Then(/^I see that I should burn (\d+) more calories by exercising today$/) do |cals|
38
+ expect(outputs.exercise_calories_remaining).to eq cals.to_i
39
+ end
File without changes
@@ -0,0 +1,18 @@
1
+ require 'nutrition_calculator/calorie_budgeter'
2
+
3
+ def inputs
4
+ @inputs ||= NutritionCalculator::CalorieBudgeter.new
5
+ end
6
+
7
+ def calculate_remaining_calories
8
+ # Uncomment the following line if you need debugging output
9
+ # inputs.logger = logger
10
+ end
11
+
12
+ def outputs
13
+ inputs
14
+ end
15
+
16
+ def logger
17
+ Logger.new(STDERR)
18
+ end
@@ -0,0 +1,126 @@
1
+ require 'nutrition_calculator/has_logging'
2
+
3
+ module NutritionCalculator
4
+
5
+ # Define an object that turns inputs into outputs. With Caching! And Logging!
6
+ #
7
+ # @example
8
+ # class Foo
9
+ # extend NutritionCalculator::CachedOutputsWithRecalculation
10
+ #
11
+ # def_input :bar
12
+ #
13
+ # def_output :baz do
14
+ # bar.expensive_operation
15
+ # end
16
+ # end
17
+ #
18
+ # x = Foo.new
19
+ #
20
+ # x.baz
21
+ # #=> Raises a RuntimeError because input bar was not set
22
+ #
23
+ # a_thing = ExpensiveObject.new
24
+ #
25
+ # x.bar = a_thing
26
+ # x.baz
27
+ # #=> result of `a_thing.expensive_operation`
28
+ #
29
+ # # `a_thing.expensive_operation` will not be called again
30
+ # x.baz
31
+ # #=> cached result of `a_thing.expensive_operation`
32
+ #
33
+ # # `a_thing.expensive_operation` will be called again since input is
34
+ # # reassigned
35
+ # x.bar = a_thing
36
+ # x.baz
37
+ # #=> result of `a_thing.expensive_operation`
38
+ #
39
+ module CachedOutputsWithRecalculation
40
+ # @private
41
+ def self.extended(other)
42
+ other.include(InstanceMethods)
43
+ end
44
+
45
+ # Defines accessors for the named attribute
46
+ #
47
+ # Assignment to the named accessor will cause all cached results to be
48
+ # recalculated the next time they are called.
49
+ #
50
+ # @param name [Symbol]
51
+ def def_input(name)
52
+ def_input_writer name
53
+ def_input_reader name
54
+ end
55
+
56
+ # Defines attribute reader methods for the specified calculation
57
+ #
58
+ # The result of the block is cached as long as no inputs are re-assigned
59
+ # after the attribute reader is called. Additionaly, if `#logger` is set,
60
+ # the result of the calculation will be sent to the DEBUG log when the block
61
+ # is run.
62
+ #
63
+ # @param name [Symbol]
64
+ # @param block [Proc] will be `instance_eval`ed in the Object as though it
65
+ # were the body of a regular method
66
+ def def_output(name, &block)
67
+ define_method(name) do
68
+ cache_and_debug(name, &block)
69
+ end
70
+ end
71
+
72
+ private
73
+
74
+ def def_input_writer(name)
75
+ define_method("#{name}=") do |value|
76
+ recalculate!
77
+ instance_variable_set("@#{name}", value)
78
+ end
79
+ end
80
+
81
+ def def_input_reader(name)
82
+ define_method(name) do
83
+ require_input name
84
+ instance_variable_get("@#{name}")
85
+ end
86
+ end
87
+
88
+ module InstanceMethods
89
+ include HasLogging
90
+
91
+ private
92
+
93
+ def cached_values
94
+ @cached_values ||= {}
95
+ end
96
+
97
+ def recalculate!
98
+ logger.debug "Input received; clearing cached calculations."
99
+ @cached_values = {}
100
+ end
101
+
102
+ def cache(name, &block)
103
+ cached_values.fetch(name) do
104
+ cached_values[name] = block.call
105
+ end
106
+ end
107
+
108
+ def require_input(name)
109
+ unless instance_variable_defined?("@#{name}")
110
+ raise RuntimeError, "Required input missing: `#{name}`."
111
+ end
112
+ end
113
+
114
+ def cache_and_debug(name, &block)
115
+ cache(name) do
116
+ run_and_debug(name, &block)
117
+ end
118
+ end
119
+
120
+ def run_and_debug(name, &block)
121
+ debug_value(name) { instance_eval &block }
122
+ end
123
+ end
124
+ private_constant :InstanceMethods
125
+ end
126
+ end
@@ -0,0 +1,158 @@
1
+ require 'nutrition_calculator/cached_outputs_with_recalculation'
2
+
3
+ module NutritionCalculator
4
+ # Calculates Calorie Budget Per Day in Weekly Context
5
+ #
6
+ # The `NutritionCalculator::CalorieBudgeter` is used to determine how many
7
+ # calories you need to consume and how many calories you need to burn via
8
+ # exercise for a given day in order to stay on target with your diet. In
9
+ # particular, it ensures that you consume at least enough to satisfy your
10
+ # resting metabolic rate each day, even if that means you need to burn off
11
+ # calories via exercise to keep on track. It operates on a weekly basis,
12
+ # so if you are over-/under-budget on a given day, the goals for the
13
+ # remainder of the week will be adjusted accordingly.
14
+ #
15
+ # @example
16
+ # cb = NutritionCalculator::CalorieBudgeter.new
17
+ #
18
+ # cb.resting_metabolic_rate = 2_000 # calories per day
19
+ # cb.weekly_calorie_goal = 10_500 # creates an average deficit of 500 calories/day
20
+ # cb.current_day_of_week = 3 # if your week starts on Monday, this would be Wednesday
21
+ # cb.prior_days_calories = 3_524 # net calories from Monday and Tuesday
22
+ #
23
+ # cb.calories_consumed = 0
24
+ # cb.calories_burned = 0
25
+ #
26
+ # cb.calories_remaining
27
+ # #=> 2_000
28
+ #
29
+ # cb.exercise_calories_remaining
30
+ # #=> 605
31
+ #
32
+ # cb.calories_consumed = 681 # total calories consumed today
33
+ # cb.calories_burned = 1752
34
+ #
35
+ # cb.calories_remaining
36
+ # #=> 2_466
37
+ #
38
+ # cb.exercise_calories_remaining
39
+ # #=> 0
40
+ class CalorieBudgeter
41
+ extend CachedOutputsWithRecalculation
42
+
43
+ # @!group Inputs
44
+
45
+ # @!attribute
46
+ # @return [Integer] The daily resting metabolic rate in calories
47
+ def_input :resting_metabolic_rate
48
+
49
+ # @!attribute
50
+ # @return [Integer] The total net calories (consumed - burned) planned for
51
+ # the week
52
+ def_input :weekly_calorie_goal
53
+
54
+ # @!attribute
55
+ # @return [Integer] The total net calories from all days this week prior
56
+ # to the current day
57
+ # @example
58
+ # If it is currently Wednesday
59
+ # And on Monday you consumed 100 calories and burned 75 for a net of 25
60
+ # And on Tuesday you consumed 200 calories and burned 100 for a net of 100
61
+ # Then you don't care about today's calories
62
+ # And the value for this input should be 125 (Monday + Tuesday)
63
+ def_input :prior_days_calories
64
+
65
+ # @!attribute
66
+ # @return [Integer] The number of the day of the week
67
+ # @example If you start your week on Monday
68
+ # 1 - Monday
69
+ # 2 - Tuesday
70
+ # 3 - Wednesday
71
+ # 4 - Thursday
72
+ # 5 - Friday
73
+ # 6 - Saturday
74
+ # 7 - Sunday
75
+ def_input :current_day_of_week
76
+
77
+ # @!attribute
78
+ # @return [Integer] The total number of calories consumed today
79
+ def_input :calories_consumed
80
+
81
+ # @!attribute
82
+ # @return [Integer] The total number of calories burned via exercise today
83
+ def_input :calories_burned
84
+
85
+ # @!group Outputs
86
+
87
+ # @!attribute [r]
88
+ # @return [Integer] The net calories for the day (consumed - burned via
89
+ # exercise)
90
+ def_output :net_calorie_consumption do
91
+ calories_consumed - calories_burned
92
+ end
93
+
94
+ # @!attribute [r]
95
+ # @return [Integer] The number of calories remaining to consume today
96
+ def_output :calories_remaining do
97
+ [0, remaining_to_target].max
98
+ end
99
+
100
+ # @!attribute [r]
101
+ # @return [Integer] The number of calories that must still be burned today
102
+ # in order to meet the daily calorie goal
103
+ def_output :exercise_calories_remaining do
104
+ [0, predicted_overage].max
105
+ end
106
+
107
+ # @!attribute [r]
108
+ # @return [Integer] The number of calories that will likely be consumed
109
+ # today (the greater of actual consumption or target
110
+ # consumption).
111
+ def_output :predicted_calorie_consumption do
112
+ [target_daily_calorie_consumption, calories_consumed].max
113
+ end
114
+
115
+ # @!attribute [r]
116
+ # @return [Integer] The number of calories consumed (or predicted to be
117
+ # consumed) that is greater than the daily calorie goal
118
+ # and not yet burned off via exercise
119
+ def_output :predicted_overage do
120
+ predicted_calorie_consumption - daily_calorie_goal - calories_burned
121
+ end
122
+
123
+ # @!attribute [r]
124
+ # @return [Integer] The number of calories that must still be consumed to
125
+ # hit the day's target
126
+ def_output :remaining_to_target do
127
+ target_daily_calorie_consumption - calories_consumed
128
+ end
129
+
130
+ # @!attribute [r]
131
+ # @return [Integer] The number of calories that should be consumed today
132
+ def_output :target_daily_calorie_consumption do
133
+ [(daily_calorie_goal + calories_burned), resting_metabolic_rate].max
134
+ end
135
+
136
+ # @!attribute [r]
137
+ # @return [Integer] The number of net calories that should be consumed today
138
+ # to meet the weekly calorie goal
139
+ def_output :daily_calorie_goal do
140
+ (remaining_calories_this_week.to_f / remaining_days_of_week).round
141
+ end
142
+
143
+ # @!attribute [r]
144
+ # @return [Integer] The number of calories left in the calorie budget for
145
+ # the current week (does not include calories consumed
146
+ # today)
147
+ def_output :remaining_calories_this_week do
148
+ weekly_calorie_goal - prior_days_calories
149
+ end
150
+
151
+ # @!attribute [r]
152
+ # @return [Integer] The number of days remaining in the week, including the
153
+ # current day
154
+ def_output :remaining_days_of_week do
155
+ 8 - current_day_of_week
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,40 @@
1
+ require 'logger'
2
+
3
+ module NutritionCalculator
4
+ # Provides a few logging utilities to the including class/module
5
+ module HasLogging
6
+ module NullLogger
7
+ extend self
8
+
9
+ def noop(*args); args; end
10
+ alias_method :error, :noop
11
+ alias_method :warn, :noop
12
+ alias_method :info, :noop
13
+ alias_method :debug, :noop
14
+ end
15
+ private_constant :NullLogger
16
+
17
+ attr_writer :logger
18
+
19
+ # The logger to which the including class/module should write
20
+ #
21
+ # Defaults to a NullLogger, which simply discards all logging attempts as
22
+ # noops.
23
+ #
24
+ # @return [Logger] an object adhering to the Logger interface
25
+ def logger
26
+ @logger ||= NullLogger
27
+ end
28
+
29
+ protected
30
+
31
+ # Executes the block and both logs and returns the result
32
+ #
33
+ # @return [block.call] The result of calling the block provided
34
+ def debug_value(name, &block)
35
+ block.call.tap do |value|
36
+ logger.debug("#{name}: #{value}")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module NutritionCalculator
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "nutrition_calculator/version"
2
+
3
+ module NutritionCalculator
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'nutrition_calculator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "nutrition_calculator"
8
+ spec.version = NutritionCalculator::VERSION
9
+ spec.authors = ["John Wilger"]
10
+ spec.email = ["johnwilger@gmail.com"]
11
+ spec.summary = %q{Nutrition calculators for diet management}
12
+ spec.description = %q{
13
+ NutritionCalculator provides a set of core libraries to help track a
14
+ person's individual nutritional goals. It is meant to aid in both
15
+ weight-management and monitoring the nutritional balance of a diet.
16
+ }
17
+ spec.homepage = ""
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.7"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec", "~> 3.2.0"
28
+ spec.add_development_dependency "cucumber", "~> 1.3.0"
29
+ spec.add_development_dependency "reek"
30
+ spec.add_development_dependency "yard"
31
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'nutrition_calculator/cached_outputs_with_recalculation'
3
+
4
+ describe NutritionCalculator::CachedOutputsWithRecalculation do
5
+ subject {
6
+ klass = Class.new do
7
+ extend NutritionCalculator::CachedOutputsWithRecalculation
8
+
9
+ def_input :foo
10
+
11
+ def_output :baz do
12
+ foo.bar
13
+ end
14
+ end
15
+
16
+ klass.new
17
+ }
18
+
19
+ let(:foo_value) { double('FooValue', bar: 'baz') }
20
+
21
+ it 'creates attr_accessors for inputs' do
22
+ subject.foo = :bar
23
+ expect(subject.foo).to eq :bar
24
+ end
25
+
26
+ it "complains when asked for the value of an input that was not provided" do
27
+ expect{subject.foo}.to \
28
+ raise_error(RuntimeError, "Required input missing: `foo`.")
29
+ end
30
+
31
+ it 'creates attr_readers for outputs' do
32
+ subject.foo = foo_value
33
+ expect(subject.baz).to eq 'baz'
34
+ end
35
+
36
+ it 'caches the calculated values for output' do
37
+ subject.foo = foo_value
38
+ expect(foo_value).to receive(:bar).once.and_return('baz')
39
+ 2.times do
40
+ subject.baz
41
+ end
42
+ end
43
+
44
+ it 'clears cached calculations when inputs are changed' do
45
+ expect(foo_value).to receive(:bar).twice.and_return('baz')
46
+ 2.times do
47
+ subject.foo = foo_value
48
+ subject.baz
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,236 @@
1
+ require 'spec_helper'
2
+ require 'logger'
3
+ require 'nutrition_calculator/calorie_budgeter'
4
+
5
+ describe NutritionCalculator::CalorieBudgeter do
6
+ # Uncomment the following line if you need debugging output
7
+ # before(:each) { subject.logger = Logger.new(STDERR) }
8
+
9
+ describe '#net_calorie_consumption' do
10
+ it 'is the number of calories consumed less any calories burned via exercise' do
11
+ subject.calories_consumed = 100
12
+ subject.calories_burned = 10
13
+ expect(subject.net_calorie_consumption).to eq 90
14
+ end
15
+ end
16
+
17
+ describe '#remaining_calories_this_week' do
18
+ it 'is the weekly calorie goal less net calories from previous days' do
19
+ subject.weekly_calorie_goal = 10_000
20
+ subject.prior_days_calories = 1_000
21
+ expect(subject.remaining_calories_this_week).to eq 9000
22
+ end
23
+ end
24
+
25
+ describe '#daily_calorie_goal' do
26
+ let(:days_left) { 8 - day }
27
+ let(:weekly_goal) { 10_000 }
28
+
29
+ before(:each) do
30
+ subject.current_day_of_week = day
31
+ subject.weekly_calorie_goal = weekly_goal
32
+ subject.prior_days_calories = weekly_consumed
33
+ end
34
+
35
+ shared_examples_for 'it calculates the daily calorie goal' do
36
+ it 'is the number of calories remaining for the week divided by the remaining days in the week' do
37
+ expected = ((weekly_goal - weekly_consumed).to_f / days_left).round
38
+ expect(subject.daily_calorie_goal).to eq expected
39
+ end
40
+ end
41
+
42
+ (1..7).each do |day_num|
43
+ context "on day #{day_num}" do
44
+ let(:day) { day_num }
45
+ let(:weekly_consumed) { day_num * 10 }
46
+ it_behaves_like 'it calculates the daily calorie goal'
47
+ end
48
+ end
49
+ end
50
+
51
+ describe '#target_daily_calorie_consumption' do
52
+ before(:each) do
53
+ subject.current_day_of_week = 1
54
+ subject.prior_days_calories = 0
55
+ subject.resting_metabolic_rate = 2_000
56
+ end
57
+
58
+ context 'when the daily calorie goal is the same as the RMR' do
59
+ before(:each) do
60
+ subject.weekly_calorie_goal = 14_000
61
+ end
62
+
63
+ context 'when no calories have been burned via exercise' do
64
+ before(:each) do
65
+ subject.calories_burned = 0
66
+ end
67
+
68
+ it 'is equal to the resting metabolic rate' do
69
+ expect(subject.target_daily_calorie_consumption).to eq 2_000
70
+ end
71
+ end
72
+
73
+ context 'when calories have been burned via exercise' do
74
+ before(:each) do
75
+ subject.calories_burned = 100
76
+ end
77
+
78
+ it 'is equal to the resting metabolic rate plus exercise calories' do
79
+ expect(subject.target_daily_calorie_consumption).to eq 2_100
80
+ end
81
+ end
82
+ end
83
+
84
+ context 'when the daily calorie goal is lower than the RMR' do
85
+ before(:each) do
86
+ subject.weekly_calorie_goal = 10_500
87
+ end
88
+
89
+ context 'when no calories have been burned via exercise' do
90
+ before(:each) do
91
+ subject.calories_burned = 0
92
+ end
93
+
94
+ it 'is equal to the resting metabolic rate' do
95
+ expect(subject.target_daily_calorie_consumption).to eq 2_000
96
+ end
97
+ end
98
+
99
+ context 'when calories burned are less than difference between goal and RMR' do
100
+ before(:each) do
101
+ subject.calories_burned = 100
102
+ end
103
+
104
+ it 'is equal to the resting metabolic rate' do
105
+ expect(subject.target_daily_calorie_consumption).to eq 2_000
106
+ end
107
+ end
108
+
109
+ context 'when calories burned are equal to the difference between goal and RMR' do
110
+ before(:each) do
111
+ subject.calories_burned = 500
112
+ end
113
+
114
+ it 'is equal to the resting metabolic rate' do
115
+ expect(subject.target_daily_calorie_consumption).to eq 2_000
116
+ end
117
+ end
118
+
119
+ context 'when calories burned are greater than the difference between goal and RMR' do
120
+ before(:each) do
121
+ subject.calories_burned = 501
122
+ end
123
+
124
+ it 'is equal to the daily goal plus calories burned' do
125
+ expect(subject.target_daily_calorie_consumption).to eq 2_001
126
+ end
127
+ end
128
+ end
129
+
130
+ context 'when the daily calorie goal is higher than the RMR' do
131
+ before(:each) do
132
+ subject.weekly_calorie_goal = 17_500
133
+ end
134
+
135
+ context 'when no calories have been burned via exercise' do
136
+ before(:each) do
137
+ subject.calories_burned = 0
138
+ end
139
+
140
+ it 'is equal to the daily calorie goal rate' do
141
+ expect(subject.target_daily_calorie_consumption).to eq 2_500
142
+ end
143
+ end
144
+
145
+ context 'when any calories have been burned via exercise' do
146
+ before(:each) do
147
+ subject.calories_burned = 1
148
+ end
149
+
150
+ it 'is equal to the daily goal plus calories burned' do
151
+ expect(subject.target_daily_calorie_consumption).to eq 2_501
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ describe '#remaining_to_target' do
158
+ before(:each) do
159
+ subject.resting_metabolic_rate = 2_000
160
+ subject.weekly_calorie_goal = 14_000
161
+ subject.current_day_of_week = 1
162
+ subject.prior_days_calories = 0
163
+ subject.calories_burned = 0
164
+ end
165
+
166
+ it 'is equal to the target daily calorie consumption less any calories already consumed' do
167
+ subject.calories_consumed = 500
168
+ expect(subject.remaining_to_target).to eq 1_500
169
+ end
170
+
171
+ it 'can be negative' do
172
+ subject.calories_consumed = 2_001
173
+ expect(subject.remaining_to_target).to eq -1
174
+ end
175
+ end
176
+
177
+ describe 'calories_remaining' do
178
+ before(:each) do
179
+ subject.resting_metabolic_rate = 2_000
180
+ subject.weekly_calorie_goal = 14_000
181
+ subject.current_day_of_week = 1
182
+ subject.prior_days_calories = 0
183
+ subject.calories_burned = 0
184
+ end
185
+
186
+ it 'is usually equal to the calories remaining to target' do
187
+ subject.calories_consumed = 500
188
+ expect(subject.calories_remaining).to eq 1_500
189
+ end
190
+
191
+ it 'will not be less than zero' do
192
+ subject.calories_consumed = 2_001
193
+ expect(subject.calories_remaining).to eq 0
194
+ end
195
+ end
196
+
197
+ describe '#predicted_calorie_consumption' do
198
+ before(:each) do
199
+ subject.current_day_of_week = 1
200
+ subject.prior_days_calories = 0
201
+ subject.resting_metabolic_rate = 2_000
202
+ subject.weekly_calorie_goal = 14_000
203
+ subject.calories_burned = 0
204
+ end
205
+
206
+ context 'when net calorie consumption is less than the target daily consumption' do
207
+ before(:each) do
208
+ subject.calories_consumed = 1_999
209
+ end
210
+
211
+ it 'is equal to the target daily consumption' do
212
+ expect(subject.predicted_calorie_consumption).to eq 2_000
213
+ end
214
+ end
215
+
216
+ context 'when net calorie consumption is equal to the target daily consumption' do
217
+ before(:each) do
218
+ subject.calories_consumed = 2_000
219
+ end
220
+
221
+ it 'is equal to the target daily consumption' do
222
+ expect(subject.predicted_calorie_consumption).to eq 2_000
223
+ end
224
+ end
225
+
226
+ context 'when net calorie consumption is greater than the target daily consumption' do
227
+ before(:each) do
228
+ subject.calories_consumed = 2_001
229
+ end
230
+
231
+ it 'is equal to the net consumption' do
232
+ expect(subject.predicted_calorie_consumption).to eq 2_001
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe NutritionCalculator do
4
+ it 'has a version number' do
5
+ expect(NutritionCalculator::VERSION).not_to be nil
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'nutrition_calculator'
3
+
4
+ RSpec.configure do |c|
5
+ c.filter_run_including :focus => true
6
+ c.run_all_when_everything_filtered = true
7
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nutrition_calculator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - John Wilger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.2.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.2.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: cucumber
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: reek
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: "\n NutritionCalculator provides a set of core libraries to help track
98
+ a\n person's individual nutritional goals. It is meant to aid in both\n weight-management
99
+ and monitoring the nutritional balance of a diet.\n "
100
+ email:
101
+ - johnwilger@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - ".rspec"
108
+ - ".ruby-version"
109
+ - ".travis.yml"
110
+ - Gemfile
111
+ - LICENSE.txt
112
+ - README.md
113
+ - Rakefile
114
+ - features/calorie_budgeter.feature
115
+ - features/step_definitions/.keep
116
+ - features/step_definitions/calorie_budgeter_steps.rb
117
+ - features/support/.keep
118
+ - features/support/helper_methods.rb
119
+ - lib/nutrition_calculator.rb
120
+ - lib/nutrition_calculator/cached_outputs_with_recalculation.rb
121
+ - lib/nutrition_calculator/calorie_budgeter.rb
122
+ - lib/nutrition_calculator/has_logging.rb
123
+ - lib/nutrition_calculator/version.rb
124
+ - nutrition_calculator.gemspec
125
+ - spec/nutrition_calculator/cached_outputs_with_recalculation_spec.rb
126
+ - spec/nutrition_calculator/calorie_budgeter_spec.rb
127
+ - spec/nutrition_calculator_spec.rb
128
+ - spec/spec_helper.rb
129
+ homepage: ''
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.2.2
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Nutrition calculators for diet management
153
+ test_files:
154
+ - features/calorie_budgeter.feature
155
+ - features/step_definitions/.keep
156
+ - features/step_definitions/calorie_budgeter_steps.rb
157
+ - features/support/.keep
158
+ - features/support/helper_methods.rb
159
+ - spec/nutrition_calculator/cached_outputs_with_recalculation_spec.rb
160
+ - spec/nutrition_calculator/calorie_budgeter_spec.rb
161
+ - spec/nutrition_calculator_spec.rb
162
+ - spec/spec_helper.rb
163
+ has_rdoc: