Skip to content

Commit

Permalink
Refactor: Projector To Be Able To Keep Track Of Progress
Browse files Browse the repository at this point in the history
Why This Change Is Necessary
========================================================================

Previously we were passing new values into `calculate` but were not
saving them.

In order to be able to be more useful in more situations, we need to
have the projector be called each time progress is updated and be able
to save that data if necessary for future projections.

This particular calculator only needs two values (the starting point and
the current point) but other projectors may need more (for example
a projector that only cares about the last n minutes of items or one
that only cares about the last x items).

What These Changes Do To Address the Issue
========================================================================

Because the projector is now tied into progress events, all we have to
do is implement those methods and save the data as necessary.

We introduce a concept of "samples" into the projector.  Each projector
will be responsible for holding as many samples of progress data as is
necessary for it to do its job properly.

Side Effects Caused By This Change
========================================================================

None expected.
  • Loading branch information
jfelchner committed Mar 4, 2023
1 parent e6b09ad commit 7ab80e3
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 8 deletions.
40 changes: 33 additions & 7 deletions lib/ruby-progressbar/calculators/smoothed_average.rb
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
class ProgressBar
module Calculators
class SmoothedAverage
DEFAULT_STRENGTH = 0.1
DEFAULT_STRENGTH = 0.1
DEFAULT_BEGINNING_POSITION = 0

attr_accessor :strength
attr_accessor :samples,
:strength
attr_reader :projection

def initialize(options = {})
self.samples = []
self.projection = 0.0
self.strength = options[:strength] || DEFAULT_STRENGTH

start(:at => DEFAULT_BEGINNING_POSITION)
end

def start(_options = {})
def start(options = {})
self.projection = 0.0
self.progress = samples[0] = (options[:at] || progress)
end

def decrement
self.progress -= 1
end

def increment
self.progress += 1
end

def progress
samples[1]
end

def progress=(new_progress)
samples[1] = new_progress
calculate(absolute)
end

def decrement; end
def increment; end
def progress=(_new_progress); end
def total=(_new_total); end

def reset
start
start(:at => samples[0])
end

def calculate(new_value)
Expand All @@ -44,6 +64,12 @@ def self.calculate(current_projection, new_value, rate)
protected

attr_writer :projection

private

def absolute
samples[1] - samples[0]
end
end
end
end
1 change: 0 additions & 1 deletion lib/ruby-progressbar/progress.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ def progress=(new_progress)
end

@progress = new_progress
running_average_calculator.calculate(absolute)
end

def running_average
Expand Down
13 changes: 13 additions & 0 deletions spec/lib/ruby-progressbar/calculators/smoothed_average_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ module Calculators

expect(projector.projection).to be 0.0
end

it 'resets based on the starting position' do
projector = SmoothedAverage.new(:strength => 0.1)
projector.start(:at => 10)
projector.progress = 20

expect(projector.projection).not_to be_zero

projector.reset
projector.progress = 20

expect(projector.projection).to be 9.0
end
end

describe '#strength' do
Expand Down
1 change: 1 addition & 0 deletions spec/lib/ruby-progressbar/progress_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class ProgressBar

expect(progress.running_average).to be_zero

projector.progress += 40
progress.progress += 40

expect(progress.running_average).to eql 36.0
Expand Down

0 comments on commit 7ab80e3

Please sign in to comment.