nom 0.1.1 → 0.1.2

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.
@@ -1,120 +1,122 @@
1
1
  require "yaml"
2
2
  require "fileutils"
3
3
 
4
- class WeightDatabase
5
- def initialize(file)
6
- @interpolated = {}
7
- @weights = {}
8
- @moving_averages = {}
9
-
10
- FileUtils.touch(file)
11
- IO.readlines(file).each do |line|
12
- date, weight = line.split(" ", 2)
13
- date = Date.parse(date)
14
- @weights[date] = weight.to_f
15
- @interpolated[date] = false
4
+ module Nom
5
+ class WeightDatabase
6
+ def initialize(file)
7
+ @interpolated = {}
8
+ @weights = {}
9
+ @moving_averages = {}
10
+
11
+ FileUtils.touch(file)
12
+ IO.readlines(file).each do |line|
13
+ date, weight = line.split(" ", 2)
14
+ date = Date.parse(date)
15
+ @weights[date] = weight.to_f
16
+ @interpolated[date] = false
17
+ end
16
18
  end
17
- end
18
19
 
19
- def interpolate_gaps!
20
- @weights.keys.each_cons(2) do |a, b|
21
- (a+1).upto(b-1) do |d|
22
- @weights[d] = @weights[a] + (@weights[a]-@weights[b])/(a-b)*(d-a)
23
- @interpolated[d] = true
20
+ def interpolate_gaps!
21
+ @weights.keys.each_cons(2) do |a, b|
22
+ (a+1).upto(b-1) do |d|
23
+ @weights[d] = @weights[a] + (@weights[a]-@weights[b])/(a-b)*(d-a)
24
+ @interpolated[d] = true
25
+ end
24
26
  end
25
27
  end
26
- end
27
28
 
28
- def precompute_moving_average!(alpha, beta, goal, rate)
29
- trend = dampened_rate(@weights[first], goal, rate)/7.0
29
+ def precompute_moving_average!(alpha, beta, goal, rate)
30
+ trend = dampened_rate(@weights[first], goal, rate)/7.0
30
31
 
31
- @moving_averages[first] = at(first)
32
- (first+1).upto(last).each do |d|
33
- @moving_averages[d] = alpha*at(d) + (1-alpha)*(@moving_averages[d-1]+trend)
34
- trend = beta*(@moving_averages[d]-@moving_averages[d-1]) + (1-beta)*trend
32
+ @moving_averages[first] = at(first)
33
+ (first+1).upto(last).each do |d|
34
+ @moving_averages[d] = alpha*at(d) + (1-alpha)*(@moving_averages[d-1]+trend)
35
+ trend = beta*(@moving_averages[d]-@moving_averages[d-1]) + (1-beta)*trend
36
+ end
35
37
  end
36
- end
37
38
 
38
- def predict_weights!(rate, goal, tail)
39
- d = (last)
40
- loop do
41
- if (@weights[d] - goal).abs < 0.1
42
- tail -= 1
43
- end
44
- if tail == 0
45
- break
39
+ def predict_weights!(rate, goal, tail)
40
+ d = (last)
41
+ loop do
42
+ if (@weights[d] - goal).abs < 0.1 and d > Date.today
43
+ tail -= 1
44
+ end
45
+ if tail == 0
46
+ break
47
+ end
48
+
49
+ d += 1
50
+ prev_weight = @moving_averages[d-1] || @weights[d-1]
51
+ @weights[d] = prev_weight+dampened_rate(prev_weight, goal, rate)/7.0
52
+ @interpolated[d] = true
46
53
  end
47
-
48
- d += 1
49
- prev_weight = @moving_averages[d-1] || @weights[d-1]
50
- @weights[d] = prev_weight+dampened_rate(prev_weight, goal, rate)/7.0
51
- @interpolated[d] = true
52
54
  end
53
- end
54
55
 
55
- def dampened_rate weight, goal, rate
56
- r = (goal-weight).to_f
57
- if r.abs > 1
58
- r/r.abs*rate
59
- else
60
- r*rate
56
+ def dampened_rate weight, goal, rate
57
+ r = (goal-weight).to_f
58
+ if r.abs > 1
59
+ r/r.abs*rate
60
+ else
61
+ r*rate
62
+ end
61
63
  end
62
- end
63
64
 
64
- def real? date
65
- @weights[date] and not @interpolated[date]
66
- end
65
+ def real? date
66
+ @weights[date] and not @interpolated[date]
67
+ end
67
68
 
68
- def at date
69
- @weights[date]
70
- end
69
+ def at date
70
+ @weights[date]
71
+ end
71
72
 
72
- def moving_average_at date
73
- @moving_averages[date]
74
- end
73
+ def moving_average_at date
74
+ @moving_averages[date]
75
+ end
75
76
 
76
- def rate_at date, goal, rate
77
- if date > last_real
78
- dampened_rate(@weights[date], goal, rate)
79
- else
80
- dampened_rate(@moving_averages[date], goal, rate)
77
+ def rate_at date, goal, rate
78
+ if date > last_real
79
+ dampened_rate(@weights[date], goal, rate)
80
+ else
81
+ dampened_rate(@moving_averages[date], goal, rate)
82
+ end
81
83
  end
82
- end
83
84
 
84
- def empty?
85
- @weights.empty?
86
- end
85
+ def empty?
86
+ @weights.empty?
87
+ end
87
88
 
88
- def first
89
- @weights.keys.min
90
- end
89
+ def first
90
+ @weights.keys.min
91
+ end
91
92
 
92
- def last
93
- @weights.keys.max
94
- end
93
+ def last
94
+ @weights.keys.max
95
+ end
95
96
 
96
- def last_real
97
- @interpolated.select{|d, i| not i}.keys.max
98
- end
97
+ def last_real
98
+ @interpolated.select{|d, i| not i}.keys.max
99
+ end
99
100
 
100
- def truncate date
101
- @weights.delete_if{|d, w| d < date}
102
- end
101
+ def truncate date
102
+ @weights.delete_if{|d, w| d < date}
103
+ end
103
104
 
104
- def min
105
- @weights.values.min
106
- end
105
+ def min
106
+ @weights.values.min
107
+ end
107
108
 
108
- def max
109
- @weights.values.max
110
- end
109
+ def max
110
+ @weights.values.max
111
+ end
111
112
 
112
- def find_gap days
113
- gap = @weights.keys.reverse.each_cons(2).find{|a,b| a-b > days}
114
- if gap
115
- gap.reverse
116
- else
117
- nil
113
+ def find_gap days
114
+ gap = @weights.keys.reverse.each_cons(2).find{|a,b| a-b > days}
115
+ if gap
116
+ gap.reverse
117
+ else
118
+ nil
119
+ end
118
120
  end
119
121
  end
120
122
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Morr
@@ -39,6 +39,7 @@ files:
39
39
  - bin/nom
40
40
  - lib/nom/config.rb
41
41
  - lib/nom/food_entry.rb
42
+ - lib/nom/helpers.rb
42
43
  - lib/nom/nom.plt.erb
43
44
  - lib/nom/nom.rb
44
45
  - lib/nom/weight_database.rb