tty-progressbar 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 439fab8fa2f01250536b13ccc0449b45666cc5b4
4
- data.tar.gz: 71ba8ed5afc229ce963fbb0024c1412b3aa03a2c
3
+ metadata.gz: ae9ad2ae6d8a85a713de8ee733bcee99f30363ae
4
+ data.tar.gz: bf7550f7709ecf82fed2760ba04c15aca402fa10
5
5
  SHA512:
6
- metadata.gz: da558151e07076430689c8342ddafb2960d8ef8f15cffc0cb9dc70c3d2b20f07b9c51361ffad8990d0d0985ee5df07db7da3530676d020f4bd32bfeceb8b3728
7
- data.tar.gz: 5ac177be8d609806e52c83ae78e2cda8d9a1990c0376f6febb06a783d4d30d4f2dbfab427bcf26b2b41319ed1e967503837fb30f43413ef78391474cd05ba212
6
+ metadata.gz: 9a2ccc30badc32c66c6c83c98be1ec9509ab79ecec0cd79ed72f9c85c331d73f74403a40744db0489de026b7b9a2ba05d8875eedda7368dbe0dc1ae3ca1bde71
7
+ data.tar.gz: 211f366e8a8fefc4741da94388d783b98204c633826d652674c65827b01398c9d4aa08fa84d7dc6930050b3a8c6a58ab682b6da23e38dc19d4d6563da9212ef7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Change log
2
2
 
3
+ ## [v0.10.0] - 2016-06-25
4
+
5
+ ### Fixed
6
+ * Fix Meter#sample to accurately calculate rate and mean_rate by Sylvain Joyeux
7
+
3
8
  ## [v0.9.0] - 2016-04-09
4
9
 
5
10
  ### Fixed
@@ -85,6 +90,8 @@
85
90
 
86
91
  * Initial implementation and release
87
92
 
93
+ [v0.10.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.9.0...v0.10.0
94
+ [v0.9.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.8.2...v0.9.0
88
95
  [v0.8.2]: https://github.com/peter-murach/tty-progressbar/compare/v0.8.1...v0.8.2
89
96
  [v0.8.1]: https://github.com/peter-murach/tty-progressbar/compare/v0.8.0...v0.8.1
90
97
  [v0.8.0]: https://github.com/peter-murach/tty-progressbar/compare/v0.7.0...v0.8.0
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
- # TTY::ProgressBar
1
+ # TTY::ProgressBar [![Gitter](https://badges.gitter.im/Join%20Chat.svg)][gitter]
2
2
  [![Gem Version](https://badge.fury.io/rb/tty-progressbar.svg)][gem]
3
3
  [![Build Status](https://secure.travis-ci.org/piotrmurach/tty-progressbar.svg?branch=master)][travis]
4
4
  [![Code Climate](https://codeclimate.com/github/piotrmurach/tty-progressbar/badges/gpa.svg)][codeclimate]
5
5
  [![Coverage Status](https://coveralls.io/repos/github/piotrmurach/tty-progressbar/badge.svg)][coverage]
6
6
  [![Inline docs](http://inch-ci.org/github/piotrmurach/tty-progressbar.svg?branch=master)][inchpages]
7
7
 
8
+ [gitter]: https://gitter.im/piotrmurach/tty
8
9
  [gem]: http://badge.fury.io/rb/tty-progressbar
9
10
  [travis]: http://travis-ci.org/piotrmurach/tty-progressbar
10
11
  [codeclimate]: https://codeclimate.com/github/piotrmurach/tty-progressbar
@@ -14,32 +14,56 @@ module TTY
14
14
  #
15
15
  # @api private
16
16
  def initialize(interval)
17
- @samples = Hash.new { |h, el| h[el] = [] }
18
17
  @interval = interval || 1 # 1 sec
19
- @marker = 0
20
-
21
- @start_time = Time.now.to_f
22
- @last_sample_at = @start_time
18
+ start
23
19
  end
24
20
 
25
21
  # Start sampling timer
26
22
  #
27
23
  # @api public
28
24
  def start
29
- @start_time = Time.now.to_f
30
- @last_sample_at = @start_time
25
+ @start_time = Time.now
26
+ @current = 0
27
+ @samples = [[@start_time, 0]]
28
+ @rates = []
29
+ @start_time
31
30
  end
32
31
 
33
32
  # Update meter with value
34
33
  #
34
+ # @param [Time] at
35
+ # the time of the sampling
36
+ #
37
+ # @param [Integer] value
38
+ # the current value of progress
39
+ #
35
40
  # @api public
36
41
  def sample(at, value)
37
- if @interval < (at.to_f - @last_sample_at)
38
- @marker += 1
42
+ @current += value
43
+ prune_samples(at)
44
+ @samples << [at, @current]
45
+ save_rate(at)
46
+ end
47
+
48
+ # Remove samples that are obsolete
49
+ #
50
+ # @api private
51
+ def prune_samples(at)
52
+ cutoff = at - @interval
53
+ while @samples.size > 1 && (@samples.first.first < cutoff)
54
+ @samples.shift
39
55
  end
40
- @samples[@marker] << value
56
+ end
41
57
 
42
- @last_sample_at = at.to_f
58
+ # If we crossed a period boundary since @start_time,
59
+ # save the rate for {#rates}
60
+ #
61
+ # @api private
62
+ def save_rate(at)
63
+ period_index = ((at - @start_time) / @interval).floor
64
+ while period_index > @rates.size
65
+ @rates << rate
66
+ end
43
67
  end
44
68
 
45
69
  # The current rate of sampling for a given interval
@@ -49,18 +73,20 @@ module TTY
49
73
  #
50
74
  # @api public
51
75
  def rate
52
- samples = @samples[@marker]
53
- result = samples.inject(:+).to_f / samples.size
54
- result.nan? ? 0 : result
76
+ first_at, first_value = @samples.first
77
+ last_at, last_value = @samples.last
78
+ if first_at == last_at
79
+ 0
80
+ else
81
+ (last_value - first_value) / (last_at - first_at)
82
+ end
55
83
  end
56
84
 
57
85
  # Group all rates per interval
58
86
  #
59
87
  # @api public
60
88
  def rates
61
- @samples.reduce([]) do |acc, (key, _)|
62
- acc << @samples[key].reduce(:+)
63
- end
89
+ @rates + [rate]
64
90
  end
65
91
 
66
92
  # The mean rate of all the sampled rates
@@ -70,10 +96,11 @@ module TTY
70
96
  #
71
97
  # @api public
72
98
  def mean_rate
73
- if rates.size == 1
74
- rate
99
+ last_at, last_value = @samples.last
100
+ if last_at == @start_time
101
+ 0
75
102
  else
76
- rates.reduce(:+).to_f / rates.size
103
+ last_value / (last_at - @start_time)
77
104
  end
78
105
  end
79
106
  alias_method :avg_rate, :mean_rate
@@ -82,8 +109,7 @@ module TTY
82
109
  #
83
110
  # @api public
84
111
  def clear
85
- @marker = 0
86
- @samples.clear
112
+ start
87
113
  end
88
114
  end # Meter
89
115
  end # ProgressBar
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class ProgressBar
5
- VERSION = '0.9.0'
5
+ VERSION = '0.10.0'
6
6
  end # ProgressBar
7
7
  end # TTY
@@ -9,6 +9,13 @@ RSpec.describe TTY::ProgressBar, ':byte_rate token' do
9
9
  time_now = Time.local(2014, 10, 5, 12, 0, 0)
10
10
  Timecop.freeze(time_now)
11
11
  progress = TTY::ProgressBar.new(":byte_rate", output: output, total: 10000, interval: 1)
12
+ # Generate a serie of advances at 2s intervals
13
+ # t+0 advance=0 total=0
14
+ # t+2 advance=1000 total=1000
15
+ # t+4 advance=2000 total=3000
16
+ # t+6 advance=3000 total=6000
17
+ # t+8 advance=4000 total=10_000
18
+ # NOTE: mean_byte uses 1024 for the scale in K, M ...
12
19
  5.times do |i|
13
20
  time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
14
21
  Timecop.freeze(time_now)
@@ -16,11 +23,11 @@ RSpec.describe TTY::ProgressBar, ':byte_rate token' do
16
23
  end
17
24
  output.rewind
18
25
  expect(output.read).to eq([
19
- "\e[1G0.0B",
26
+ "\e[1G0B",
27
+ "\e[1G500.0B",
20
28
  "\e[1G1000.0B",
21
- "\e[1G1.95KB",
22
- "\e[1G2.93KB",
23
- "\e[1G3.91KB\n"
29
+ "\e[1G1.46KB",
30
+ "\e[1G1.95KB\n"
24
31
  ].join)
25
32
  Timecop.return
26
33
  end
@@ -9,6 +9,13 @@ RSpec.describe TTY::ProgressBar, ':mean_byte token' do
9
9
  time_now = Time.local(2014, 10, 5, 12, 0, 0)
10
10
  Timecop.freeze(time_now)
11
11
  progress = TTY::ProgressBar.new(":mean_byte", output: output, total: 10000, interval: 1)
12
+ # Generate a serie of advances at 2s intervals
13
+ # t+0 advance=0 total=0
14
+ # t+2 advance=1000 total=1000
15
+ # t+4 advance=2000 total=3000
16
+ # t+6 advance=3000 total=6000
17
+ # t+8 advance=4000 total=10_000
18
+ # NOTE: mean_byte uses 1024 for the scale in K, M ...
12
19
  5.times do |i|
13
20
  time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
14
21
  Timecop.freeze(time_now)
@@ -16,11 +23,11 @@ RSpec.describe TTY::ProgressBar, ':mean_byte token' do
16
23
  end
17
24
  output.rewind
18
25
  expect(output.read).to eq([
19
- "\e[1G0.0B",
26
+ "\e[1G0B",
20
27
  "\e[1G500.0B",
28
+ "\e[1G750.0B",
21
29
  "\e[1G1000.0B",
22
- "\e[1G1.46KB",
23
- "\e[1G1.95KB\n"
30
+ "\e[1G1.22KB\n"
24
31
  ].join)
25
32
  Timecop.return
26
33
  end
@@ -9,6 +9,12 @@ RSpec.describe TTY::ProgressBar, ':mean_rate token' do
9
9
  time_now = Time.local(2014, 10, 5, 12, 0, 0)
10
10
  Timecop.freeze(time_now)
11
11
  progress = TTY::ProgressBar.new(":mean_rate", output: output, total: 100, interval: 1)
12
+ # Generate a serie of advances at 2s intervals
13
+ # t+0 advance=0 total=0
14
+ # t+2 advance=10 total=10
15
+ # t+4 advance=20 total=30
16
+ # t+6 advance=30 total=60
17
+ # t+8 advance=40 total=100
12
18
  5.times do |i|
13
19
  time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
14
20
  Timecop.freeze(time_now)
@@ -18,9 +24,9 @@ RSpec.describe TTY::ProgressBar, ':mean_rate token' do
18
24
  expect(output.read).to eq([
19
25
  "\e[1G 0.00",
20
26
  "\e[1G 5.00",
27
+ "\e[1G 7.50",
21
28
  "\e[1G10.00",
22
- "\e[1G15.00",
23
- "\e[1G20.00\n"
29
+ "\e[1G12.50\n"
24
30
  ].join)
25
31
  Timecop.return
26
32
  end
@@ -9,6 +9,12 @@ RSpec.describe TTY::ProgressBar, ':rate token' do
9
9
  time_now = Time.local(2014, 10, 5, 12, 0, 0)
10
10
  Timecop.freeze(time_now)
11
11
  progress = TTY::ProgressBar.new(":rate", output: output, total: 100, interval: 1)
12
+ # Generate a serie of advances at 2s intervals
13
+ # t+0 advance=0 total=0
14
+ # t+2 advance=10 total=10
15
+ # t+4 advance=20 total=30
16
+ # t+6 advance=30 total=60
17
+ # t+8 advance=40 total=100
12
18
  5.times do |i|
13
19
  time_now = Time.local(2014, 10, 5, 12, 0, i * 2)
14
20
  Timecop.freeze(time_now)
@@ -17,10 +23,10 @@ RSpec.describe TTY::ProgressBar, ':rate token' do
17
23
  output.rewind
18
24
  expect(output.read).to eq([
19
25
  "\e[1G 0.00",
26
+ "\e[1G 5.00",
20
27
  "\e[1G10.00",
21
- "\e[1G20.00",
22
- "\e[1G30.00",
23
- "\e[1G40.00\n"
28
+ "\e[1G15.00",
29
+ "\e[1G20.00\n"
24
30
  ].join)
25
31
  Timecop.return
26
32
  end
@@ -6,64 +6,67 @@ RSpec.describe TTY::ProgressBar::Meter, '#rate' do
6
6
 
7
7
  after { Timecop.return }
8
8
 
9
+ it "measures with no samples" do
10
+ meter = TTY::ProgressBar::Meter.new(1)
11
+
12
+ meter.start
13
+
14
+ expect(meter.rate).to eq(0)
15
+ expect(meter.mean_rate).to eq(0)
16
+ end
17
+
18
+ it "measures with a single sample" do
19
+ meter = TTY::ProgressBar::Meter.new(1)
20
+ start_time = Time.at(10, 0)
21
+ Timecop.freeze(start_time)
22
+ meter.start
23
+
24
+ meter.sample(Time.at(10, 100_000), 10)
25
+
26
+ expect(meter.rate).to eq(100)
27
+ expect(meter.mean_rate).to eq(100)
28
+ end
29
+
9
30
  it "measures rate per second" do
10
31
  meter = TTY::ProgressBar::Meter.new(1)
32
+ start_time = Time.at(10, 0)
33
+ Timecop.freeze(start_time)
11
34
  meter.start
12
- time_now = Time.local(2014, 10, 5, 12, 0, 0)
13
- Timecop.freeze(time_now)
14
35
 
15
36
  # First sample batch
16
- time_now = Time.local(2014, 10, 5, 12, 0, 0, 100)
17
- meter.sample time_now, 1000
18
- expect(meter.rate).to eq(1000)
19
- expect(meter.mean_rate).to eq(1000)
20
-
21
- time_now = Time.local(2014, 10, 5, 12, 0, 0, 200)
22
- meter.sample time_now, 2000
23
- expect(meter.rate).to eq(1500)
24
- expect(meter.mean_rate).to eq(1500)
25
-
26
- time_now = Time.local(2014, 10, 5, 12, 0, 0, 300)
27
- meter.sample time_now, 1000
28
- expect(meter.rate).to be_within(0.5).of(1333)
29
- expect(meter.mean_rate).to be_within(0.5).of(1333)
30
-
31
- # Second sample batch after 1s
32
- time_now = Time.local(2014, 10, 5, 12, 0, 1, 400)
33
- meter.sample time_now, 500
34
- expect(meter.rate).to eq(500)
35
- expect(meter.mean_rate).to eq(2250)
36
-
37
- time_now = Time.local(2014, 10, 5, 12, 0, 1, 500)
38
- meter.sample time_now, 500
39
- expect(meter.rate).to eq(500)
40
- expect(meter.mean_rate).to eq(2500)
41
-
42
- # Third sample batch after 3s
43
- time_now = Time.local(2014, 10, 5, 12, 0, 2, 600)
44
- meter.sample time_now, 3000
45
- expect(meter.rate).to eq(3000)
46
- expect(meter.mean_rate).to be_within(0.7).of(2666)
47
-
48
- time_now = Time.local(2014, 10, 5, 12, 0, 2, 700)
49
- meter.sample time_now, 3000
50
- expect(meter.rate).to eq(3000)
51
- expect(meter.mean_rate).to be_within(0.7).of(3666)
37
+ meter.sample Time.at(10, 100_000), 5
38
+ expect(meter.rate).to eq(50)
39
+ expect(meter.mean_rate).to eq(50)
40
+
41
+ meter.sample Time.at(10, 500_000), 5
42
+ expect(meter.rate).to eq(20)
43
+ expect(meter.mean_rate).to eq(20)
44
+
45
+ meter.sample Time.at(11, 000_000), 5
46
+ expect(meter.rate).to eq(15)
47
+ expect(meter.mean_rate).to eq(15)
48
+
49
+ meter.sample Time.at(11, 500_000), 5
50
+ expect(meter.rate).to eq(10)
51
+ expect(meter.mean_rate).to be_within(0.001).of(13.333)
52
+
53
+ meter.sample Time.at(12, 000_000), 10
54
+ expect(meter.rate).to eq(15)
55
+ expect(meter.mean_rate).to eq(15)
52
56
  end
53
57
 
54
58
  it "clears measurements" do
55
59
  meter = TTY::ProgressBar::Meter.new(1)
60
+ start_time = Time.at(10, 0)
61
+ Timecop.freeze(start_time)
56
62
  meter.start
57
- time_now = Time.local(2014, 10, 5, 12, 0, 0)
58
- Timecop.freeze(time_now)
59
63
 
60
- time_now = Time.local(2014, 10, 5, 12, 0, 0, 100)
61
- meter.sample time_now, 1000
62
- expect(meter.rates).to eq([1000])
64
+ meter.sample(start_time + 1, 1000)
65
+ expect(meter.rates).to eq([1000, 1000])
63
66
  expect(meter.rate).to eq(1000)
64
67
 
65
68
  meter.clear
66
- expect(meter.rates).to eq([])
69
+ expect(meter.rates).to eq([0])
67
70
  expect(meter.rate).to eq(0)
68
71
  end
69
72
  end
metadata CHANGED
@@ -1,61 +1,61 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tty-progressbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Murach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-09 00:00:00.000000000 Z
11
+ date: 2016-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tty-screen
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.5.0
34
- - - <
34
+ - - "<"
35
35
  - !ruby/object:Gem::Version
36
36
  version: '2.0'
37
37
  type: :development
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - '>='
41
+ - - ">="
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.5.0
44
- - - <
44
+ - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '2.0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '>='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '>='
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  description: A flexible progress bars drawing in terminal emulators.
@@ -65,10 +65,10 @@ executables: []
65
65
  extensions: []
66
66
  extra_rdoc_files: []
67
67
  files:
68
- - .codeclimate.yml
69
- - .gitignore
70
- - .rspec
71
- - .travis.yml
68
+ - ".codeclimate.yml"
69
+ - ".gitignore"
70
+ - ".rspec"
71
+ - ".travis.yml"
72
72
  - CHANGELOG.md
73
73
  - Gemfile
74
74
  - LICENSE.txt
@@ -147,17 +147,17 @@ require_paths:
147
147
  - lib
148
148
  required_ruby_version: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  requirements:
155
- - - '>='
155
+ - - ">="
156
156
  - !ruby/object:Gem::Version
157
157
  version: '0'
158
158
  requirements: []
159
159
  rubyforge_project:
160
- rubygems_version: 2.0.3
160
+ rubygems_version: 2.5.1
161
161
  signing_key:
162
162
  specification_version: 4
163
163
  summary: A flexible progress bars drawing in terminal emulators.