Skip to content

Commit 3ba0120

Browse files
committed
Add: Concept Of A Projector
Why This Change Is Necessary ======================================================================== Currently the `Progress` class is doing too much. It's both in charge of keeping track of the progress but also in understanding how quickly each item of progress is being executed. We need to split the objects up so that each object is responsible for its own job. What These Changes Do To Address the Issue ======================================================================== Introduce the concept of a "projector". Caveats ------------------------------------------------------------------------ Currently this is simply the calculator but will be fleshed out in later commits. Side Effects Caused By This Change ======================================================================== None expected.
1 parent d7a2a51 commit 3ba0120

File tree

10 files changed

+344
-251
lines changed

10 files changed

+344
-251
lines changed

lib/ruby-progressbar/base.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'forwardable'
22

3+
require 'ruby-progressbar/calculators/smoothed_average'
34
require 'ruby-progressbar/components/bar'
45
require 'ruby-progressbar/components/percentage'
56
require 'ruby-progressbar/components/rate'
@@ -31,10 +32,12 @@ def initialize(options = {}) # rubocop:disable Metrics/AbcSize
3132
self.finished = false
3233

3334
self.timer = Timer.new(options)
34-
self.progressable = Progress.new(options)
35+
self.projector = Calculators::SmoothedAverage.new(:strength => options[:smoothing])
36+
self.progressable = Progress.new(options.merge(:projector => projector))
3537

36-
options = options.merge(:progress => progressable,
37-
:timer => timer)
38+
options = options.merge(:progress => progressable,
39+
:projector => projector,
40+
:timer => timer)
3841

3942
self.title_component = Components::Title.new(options)
4043
self.bar_component = Components::Bar.new(options)
@@ -174,6 +177,7 @@ def format=(other)
174177
protected
175178

176179
attr_accessor :output,
180+
:projector,
177181
:timer,
178182
:progressable,
179183
:title_component,

lib/ruby-progressbar/calculators/smoothed_average.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
class ProgressBar
22
module Calculators
33
class SmoothedAverage
4-
def self.calculate(current_average, new_value_to_average, rate)
5-
(new_value_to_average * (1.0 - rate)) + (current_average * rate)
4+
DEFAULT_STRENGTH = 0.1
5+
6+
attr_accessor :strength
7+
8+
def initialize(options = {})
9+
self.strength = options[:strength] || DEFAULT_STRENGTH
10+
end
11+
12+
def calculate(current_projection, new_value)
13+
self.class.calculate(
14+
current_projection,
15+
new_value,
16+
strength
17+
)
18+
end
19+
20+
def self.calculate(current_projection, new_value, rate)
21+
(new_value * (1.0 - rate)) + (current_projection * rate)
622
end
723
end
824
end

lib/ruby-progressbar/progress.rb

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,20 @@
11
require 'ruby-progressbar/errors/invalid_progress_error'
2-
require 'ruby-progressbar/calculators/smoothed_average'
32

43
class ProgressBar
54
class Progress
6-
DEFAULT_TOTAL = 100
7-
DEFAULT_BEGINNING_POSITION = 0
8-
DEFAULT_RUNNING_AVERAGE_RATE = 0.1
9-
DEFAULT_RUNNING_AVERAGE_CALCULATOR = ProgressBar::Calculators::SmoothedAverage
10-
11-
RUNNING_AVERAGE_CALCULATOR_MAP = {
12-
'smoothing' => ProgressBar::Calculators::SmoothedAverage
13-
}.freeze
5+
DEFAULT_TOTAL = 100
6+
DEFAULT_BEGINNING_POSITION = 0
147

158
attr_reader :total,
169
:progress
1710

1811
attr_accessor :starting_position,
1912
:running_average,
20-
:running_average_calculator,
21-
:running_average_rate
13+
:running_average_calculator
2214

2315
def initialize(options = {})
2416
self.total = options.fetch(:total, DEFAULT_TOTAL)
25-
self.running_average_rate = options[:smoothing] ||
26-
options[:running_average_rate] ||
27-
DEFAULT_RUNNING_AVERAGE_RATE
28-
self.running_average_calculator = RUNNING_AVERAGE_CALCULATOR_MAP.
29-
fetch(options[:running_average_calculator],
30-
DEFAULT_RUNNING_AVERAGE_CALCULATOR)
17+
self.running_average_calculator = options[:projector]
3118

3219
start :at => DEFAULT_BEGINNING_POSITION
3320
end
@@ -79,8 +66,7 @@ def progress=(new_progress)
7966
@progress = new_progress
8067

8168
self.running_average = running_average_calculator.calculate(running_average,
82-
absolute,
83-
running_average_rate)
69+
absolute)
8470
end
8571

8672
def total=(new_total)

spec/lib/ruby-progressbar/calculators/smoothed_average_spec.rb

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,27 @@
44
class ProgressBar
55
module Calculators
66
describe SmoothedAverage do
7-
it 'can properly calculate a running average' do
8-
first_average = SmoothedAverage.calculate(4.5, 12, 0.1)
9-
expect(first_average).to be_within(0.001).of 11.25
7+
it 'can properly calculate a projector' do
8+
first_projection = SmoothedAverage.calculate(4.5, 12, 0.1)
9+
expect(first_projection).to be_within(0.001).of 11.25
1010

11-
second_average = SmoothedAverage.calculate(8.2, 51, 0.7)
12-
expect(second_average).to be_within(0.001).of 21.04
11+
second_projection = SmoothedAverage.calculate(8.2, 51, 0.7)
12+
expect(second_projection).to be_within(0.001).of 21.04
1313

14-
third_average = SmoothedAverage.calculate(41.8, 100, 0.59)
15-
expect(third_average).to be_within(0.001).of 65.662
14+
third_projection = SmoothedAverage.calculate(41.8, 100, 0.59)
15+
expect(third_projection).to be_within(0.001).of 65.662
16+
end
17+
18+
describe '#strength' do
19+
it 'allows the default strength to be overridden' do
20+
projector = SmoothedAverage.new(:strength => 0.3)
21+
22+
expect(projector.strength).to be 0.3
23+
end
24+
25+
it 'has a default strength' do
26+
expect(SmoothedAverage.new.strength).to be 0.1
27+
end
1628
end
1729
end
1830
end

0 commit comments

Comments
 (0)