tty-progressbar 0.9.0 → 0.10.0

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