nom 0.1.1 → 0.1.2

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