tqdm 0.1.0 → 0.2.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: 18fbbebb6aadc15bb9b2cea3caf012e49e087908
4
- data.tar.gz: 3da06e2b16e451592014ebdf94b0012ad165d589
3
+ metadata.gz: 3dc522c1cd180b959a8c36c2a3f1fb41ffdd51a8
4
+ data.tar.gz: e17546f682e0adfe9b6970bc02477590b1d355cd
5
5
  SHA512:
6
- metadata.gz: 0aefc092a3fb9a925107689fe03eaf8196393a60331fcb41031bca5159423693e65db4bd5cf60a333cb0d16c1cb0eaf9dfe5682003955665d1bdedcf0ea49d70
7
- data.tar.gz: 7bdd329b81bca2cc2951753815c7459f58ac6009b8dffa8e5a650cbb921f67cc7ac7b4e976478a5fd9d09fcbcea82842757dc80d1f8b83a28ebd55adc711abca
6
+ metadata.gz: 2a5aecb337cfec0e565deabd81741aff57c48c1b1b13b562c08c9173ae6b9e520aeb18561734a317ee9ee2943dc0df3869c71495c17ff584580d7787857011b2
7
+ data.tar.gz: 71e5e62669db44fe2d3b7aa42696c22bf5c34f87f374b48505ea9899536c9a614ae9ce92b874799e3e5df46525f2fc9ea251dea2a5f86c238db7f34468aa291b
data/.yardopts CHANGED
@@ -1,4 +1,4 @@
1
1
  --readme README.md
2
2
  --charset utf-8
3
3
  --markup markdown
4
- 'lib/**/*.rb'
4
+ 'lib/**/*.rb'
data/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # tqdm-ruby
2
+ [![Gem Version](https://badge.fury.io/rb/tqdm.svg)](https://badge.fury.io/rb/tqdm)
2
3
 
3
- tqdm-ruby is a small utility to show a progress indicator while iterating through an Enumerable object.
4
+ tqdm-ruby allows you to add a progress indicator to your loops with minimal effort.
4
5
 
5
- It is a port of the excellent [tdqm library][tqdm] for python.
6
+ It is a port of the excellent [tqdm library][tqdm] for python. tqdm (read taqadum, تقدّم) means "progress" in Arabic.
6
7
 
7
- Call `#tqdm` on any `Enumerable`, which enhances the object so that iterating over it will produce an animated progress bar on `$stderr`.
8
+ Calling `#tqdm` (or its readable but longer alias `#with_progress`) on any `Enumerable` returns an enhanced clone that animates a meter on `$stderr` during iteration.
8
9
 
9
10
  ```ruby
10
11
  require 'tqdm'
@@ -15,11 +16,14 @@ The default output looks like this:
15
16
 
16
17
  ![|####------| 492/1000 49% [elapsed: 00:05 left: 00:05, 88.81 iters/sec]](http://i.imgur.com/6y0t7XS.gif)
17
18
 
18
- It works equally well from within irb, [pry](http://pryrepl.org/), and [Jupyter notebooks](https://jupyter.org/).
19
+ It works equally well from within irb, [pry](http://pryrepl.org/), and [iRuby notebooks](https://github.com/SciRuby/iruby) as seen here:
19
20
 
20
- *Why not progressbar, ruby-progressbar, etc.?* These have a bazillion formatting options and you typically have to update the progressbar object throughout other code. tqdm pleasantly encourages the laziest imaginable usage, in that you "set it and forget it".
21
+ ![iRuby notebook screencap](http://i.imgur.com/DilrHuX.gif)
22
+
23
+ *Why not progressbar, ruby-progressbar, powerbar, or any of the [other gems][]?* These typically have a bucketload of formatting options and you have to manually send updates to the progressbar object to use them. tqdm pleasantly encourages the laziest usage scenario, in that you "set it and forget it".
21
24
 
22
25
  [tqdm]: https://github.com/tqdm/tqdm
26
+ [other gems]: https://www.ruby-toolbox.com/categories/CLI_Progress_Bars
23
27
 
24
28
  ## Install
25
29
 
@@ -37,22 +41,23 @@ And then execute:
37
41
 
38
42
  ## Usage
39
43
 
40
- All `Enumerable` objects gain access to the `#tqdm` method, which returns an enhanced object wherein any iteration (by calling `#each` or any of its relatives, e.g., `#each_with_index`, `#each_with_object`, etc.) produces an animated progress bar on `$stderr`.
41
-
42
- Options can be provided for `#tqdm`:
44
+ All `Enumerable` objects gain access to the `#with_progress` method (aliased as `#tqdm`), which returns an enhanced object wherein any iteration (by calling `#each` or any of its relatives: `#each_with_index`, `#map`, `#select`, etc.) produces an animated progress bar on `$stderr`.
43
45
 
44
46
  ```ruby
45
47
  require 'tqdm'
46
- Hash[*(1..1000)].tqdm(desc: "working on it", leave: true).each { |x| sleep 0.01 }
48
+ num = 1629241972611353
49
+ (2..Math.sqrt(num)).with_progress.reject { |x| num % x > 0 }.map { |x| [x, num/x] }
50
+ # ... Animates a progress bar while calculating...
51
+ # => [[32599913, 49976881]]
47
52
  ```
48
53
 
49
- The following options are available:
54
+ Options can be provided as a hash, e.g., `.with_progress(desc: "copying", leave: true)`. The following options are available:
50
55
 
51
56
  - `desc`: Short string, describing the progress, added to the beginning of the line
52
- - `total`: Expected number of iterations, if not given, `self.size` is used
57
+ - `total`: Expected number of iterations, if not given, `self.size || self.count` is used
53
58
  - `file`: A file-like object to output the progress message to, by default, `$stderr`
54
- - `leave`: A boolean (default false). Should the progress bar should stay on screen after it's done?
55
- - `min_interval`: Default is `0.5`. If less than `min_interval` seconds or `min_iters` iterations have passed since the last progress meter update, it is not re-printed (decreases IO thrashing).
59
+ - `leave`: A boolean (default `false`). Should the progress bar should stay on screen after it's done?
60
+ - `min_interval`: Default is `0.5`. If less than `min_interval` seconds or `min_iters` iterations have passed since the last progress meter update, it is not re-printed (decreasing IO thrashing).
56
61
  - `min_iters`: Default is `1`. See previous.
57
62
 
58
63
  [Sequel](http://sequel.jeremyevans.net/) is an amazing database library for Ruby. tqdm can enhance its [`Dataset`](http://sequel.jeremyevans.net/rdoc/classes/Sequel/Dataset.html) objects to show progress while iterating (same options as above):
@@ -68,12 +73,20 @@ DB.create_table :items do
68
73
  end
69
74
 
70
75
  # Show progress during big inserts (this isn't new)
71
- (0..100000).tqdm.each { DB[:items].insert(price: rand * 100) }
76
+ (0..100000).with_progress.each { DB[:items].insert(price: rand * 100) }
72
77
 
73
78
  # Show progress during long SELECT queries
74
- DB[:items].where{ price > 10 }.tqdm.each { |row| "do some processing here" }
79
+ DB[:items].where{ price > 10 }.with_progress.each { |row| "do some processing here" }
75
80
  ```
76
81
 
82
+ ## TODO
83
+
84
+ 1. Performance improvements
85
+ 2. Test/benchmark suite
86
+ 3. Add smoothing for speed estimates
87
+ 4. Support unicode output (smooth blocks)
88
+ 5. By default, resize to the apparent width of the output terminal
89
+
77
90
  ## Contributing
78
91
 
79
92
  1. Fork it
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
@@ -1,25 +1,26 @@
1
- require "tqdm"
1
+ require 'tqdm'
2
2
 
3
3
  # We enhance all enumerable objects (e.g. `Array`, `Hash`, `Range`, ...) by extending the `Enumerable` module.
4
4
  # This mixin is only supposed to be present on objects that provide an `#each` method.
5
5
  #
6
6
  # @see http://ruby-doc.org/core-2.2.3/Enumerable.html
7
7
  module Enumerable
8
-
9
- # Returns a clone of `self` where all calls to `#each` and related methods will print an animated progress bar
8
+
9
+ # Returns a *clone* of `self` where all calls to `#each` and related methods will print an animated progress bar
10
10
  # while iterating.
11
11
  #
12
- # @param opts [Hash] more options used to control behavior of the progress bar
13
- # @option opts [String] :desc a short description added to the beginning of the progress bar
14
- # @option opts [Integer] :total (self.size) the expected number of iterations
15
- # @option opts [File, IO] :file ($stderr) a file-like object to output the progress bar to
16
- # @option opts [Boolean] :leave (false) should the progress bar should stay on screen after it's done?
17
- # @option opts [Integer] :min_iters see `:min_interval`
18
- # @option opts [Float] :min_interval If less than min_interval seconds or min_iters iterations have passed since
12
+ # @param options [Hash] more options used to control behavior of the progress bar
13
+ # @option options [String] :desc a short description added to the beginning of the progress bar
14
+ # @option options [Integer] :total (self.size) the expected number of iterations
15
+ # @option options [File, IO] :file ($stderr) a file-like object to output the progress bar to
16
+ # @option options [Boolean] :leave (false) should the progress bar should stay on screen after it's done?
17
+ # @option options [Integer] :min_iters see `:min_interval`
18
+ # @option options [Float] :min_interval If less than min_interval seconds or min_iters iterations have passed since
19
19
  # the last progress meter update, it is not updated again.
20
20
  # @return [Enumerable] `self` with the `#each` method wrapped as described above
21
- def tqdm(opts = {})
22
- Tqdm::TqdmDecorator.new(self, opts).enhance
21
+ def with_progress(options = {})
22
+ Tqdm::Decorator.new(self, options).enhance
23
23
  end
24
-
25
- end
24
+ alias :tqdm :with_progress
25
+
26
+ end
@@ -1,163 +1,24 @@
1
- require "tqdm/version"
2
- require "tqdm/utils"
3
- require "core_ext/enumerable"
1
+ require 'tqdm/version'
2
+ require 'tqdm/decorator'
3
+ require 'core_ext/enumerable'
4
4
 
5
5
  # Add a progress bar to your loops in a second.
6
- # A port of Python's [tqdm library](https://github.com/tqdm/tqdm), although we're currently
6
+ # A port of Python's [tqdm library](https://github.com/tqdm/tqdm), although we're currently
7
7
  # closer to the feature set of [@noamraph's original release](https://github.com/noamraph/tqdm).
8
8
  #
9
- # Specifically, `Tqdm` enhances `Enumerable` by printing a progress indicator whenever
9
+ # Specifically, `Tqdm` enhances `Enumerable` by printing a progress indicator whenever
10
10
  # iterating with `#each` or its close relatives.
11
11
  #
12
12
  # @author Theodore Pak
13
13
  # @see https://github.com/tqdm/tqdm
14
14
  module Tqdm
15
-
16
- # The default width of the progress bar, in characters.
17
- N_BARS = 10
18
-
15
+
19
16
  class << self
20
- # Upgrades `Sequel::Datasets` with the #tqdm method.
21
- # @see Enumerable#tqdm
17
+ # Upgrades `Sequel::Datasets` with the #with_progress method.
18
+ # @see Enumerable#with_progress
22
19
  def enhance_sequel!
23
- require "tqdm/sequel"
24
- end
25
- end
26
-
27
- # Prints a status line, handling the deletion of previously printed lines with carriage
28
- # returns as necessary. Instantiated by a `TqdmDecorator`.
29
- #
30
- # @private
31
- class StatusPrinter
32
- # Initialize a new StatusPrinter.
33
- #
34
- # @param file [File, IO] the status will be printed to this via `#write` and `#flush`
35
- def initialize(file)
36
- @file = file
37
- @last_printed_len = 0
38
- end
39
-
40
- # Prints a line of text to @file, after deleting the previously printed line
41
- #
42
- # @param line [String] a line of text to be printed
43
- # @return [Integer] the number of bytes written
44
- def print_status(line)
45
- @file.write("\r" + line + ' ' * [@last_printed_len - line.size, 0].max)
46
- @file.flush
47
- @last_printed_len = line.size
20
+ require 'tqdm/sequel'
48
21
  end
49
22
  end
50
-
51
-
52
- # Decorates the #each method of an `Enumerable` by wrapping it so that each
53
- # iteration produces a pretty progress bar printed to the console or a file handle.
54
- #
55
- # @note The `Enumerable` is cloned before it is enhanced; it is not modified directly.
56
- #
57
- # @example Enhances `arr` so that an animated progress bar prints while iterating.
58
- # arr = (0...1000)
59
- # arr_tqdm = TqdmDecorator.new(arr).enhance
60
- # arr_tqdm.each { |x| sleep 0.01 }
61
- class TqdmDecorator
62
-
63
- include Utils
64
23
 
65
- # Initialize a new TqdmDecorator. Typically you wouldn't use this object, but
66
- # would immediately call `#enhance` to retrieve the enhanced `Enumerable`.
67
- #
68
- # @param enumerable [Enumerable] the Enumerable object to be enhanced
69
- # @param opts [Hash] more options used to control behavior of the progress bar
70
- # @option opts [String] :desc a short description added to the beginning of the progress bar
71
- # @option opts [Integer] :total (self.size) the expected number of iterations
72
- # @option opts [File, IO] :file ($stderr) a file-like object to output the progress bar to
73
- # @option opts [Boolean] :leave (false) should the progress bar should stay on screen after it's done?
74
- # @option opts [Integer] :min_iters see `:min_interval`
75
- # @option opts [Float] :min_interval If less than min_interval seconds or min_iters iterations have passed since
76
- # the last progress meter update, it is not updated again.
77
- #
78
- # @example
79
- # a = (1...1000)
80
- # TqdmDecorator.new(a).enhance.each { |x| sleep 0.01 }
81
- #
82
- # @example
83
- # a = [1, 2, 3, 4]
84
- # TqdmDecorator.new(a, file: $stdout, leave: true)
85
- def initialize(enumerable, opts={})
86
- @enumerable = enumerable
87
- @total = opts[:total] || @enumerable.size rescue @enumerable.count rescue nil
88
- @prefix = opts[:desc] ? opts[:desc] + ': ' : ''
89
- @file = opts[:file] || $stderr
90
- @sp = StatusPrinter.new(@file)
91
- @min_iters = opts[:min_iters] || 1
92
- @min_interval = opts[:min_interval] || 0.5
93
- @leave = opts[:leave] || false
94
- end
95
-
96
- # Starts the textual progress bar.
97
- def start!
98
- @start_t = @last_print_t = Time.now
99
- @last_print_n = 0
100
- @n = 0
101
-
102
- @sp.print_status(@prefix + format_meter(0, @total, 0))
103
- end
104
-
105
- # Called everytime the textual progress bar might need to be updated (i.e. on
106
- # every iteration). We still check whether the update is appropriate to print to
107
- # the progress bar before doing so, according to the `:min_iters` and `:min_interval`
108
- # options.
109
- #
110
- # @see #initialize
111
- def increment!
112
- @n += 1
113
-
114
- if @n - @last_print_n >= @min_iters
115
- # We check the counter first, to reduce the overhead of Time.now
116
- cur_t = Time.now
117
- if cur_t - @last_print_t >= @min_interval
118
- @sp.print_status(@prefix + format_meter(@n, @total, cur_t - @start_t))
119
- @last_print_n = @n
120
- @last_print_t = cur_t
121
- end
122
- end
123
- end
124
-
125
- # Prints the final state of the textual progress bar. Based on the `:leave` option, this
126
- # may include deleting it entirely.
127
- def finish!
128
- if !@leave
129
- @sp.print_status('')
130
- @file.write("\r")
131
- else
132
- if @last_print_n < @n
133
- @sp.print_status(@prefix + format_meter(@n, @total, Time.now - @start_t))
134
- end
135
- @file.write("\n")
136
- end
137
- end
138
-
139
- # Enhances the wrapped `Enumerable`.
140
- #
141
- # @note The `Enumerable` is cloned (shallow copied) before it is enhanced; it is not modified directly.
142
- #
143
- # @return [Enumerable] a clone of Enumerable enhanced so that every call to `#each` animates the
144
- # progress bar.
145
- def enhance
146
- tqdm = self
147
-
148
- enhanced = @enumerable.clone
149
- enhanced.define_singleton_method(:each) do |*args, &block|
150
- tqdm.start!
151
- super(*args) do |item|
152
- block.call item
153
- tqdm.increment!
154
- end
155
- tqdm.finish!
156
- end
157
-
158
- enhanced
159
- end
160
-
161
- end
162
-
163
24
  end
@@ -0,0 +1,138 @@
1
+ require 'tqdm/printer'
2
+
3
+ module Tqdm
4
+
5
+ # Decorates the #each method of an `Enumerable` by wrapping it so that each
6
+ # iteration produces a pretty progress bar printed to the console or a file handle.
7
+ #
8
+ # @note The `Enumerable` is cloned before it is enhanced; it is not modified directly.
9
+ #
10
+ # @example Enhances `arr` so that an animated progress bar prints while iterating.
11
+ # arr = (0...1000)
12
+ # arr_tqdm = Decorator.new(arr).enhance
13
+ # arr_tqdm.each { |x| sleep 0.01 }
14
+ class Decorator
15
+
16
+ attr_reader :printer, :enumerable, :iteration, :start_time
17
+
18
+ # Initialize a new Decorator. Typically you wouldn't use this object, but
19
+ # would immediately call `#enhance` to retrieve the enhanced `Enumerable`.
20
+ #
21
+ # @param enumerable [Enumerable] the Enumerable object to be enhanced
22
+ # @param options [Hash] more options used to control behavior of the progress bar
23
+ # @option options [String] :desc a short description added to the beginning of the progress bar
24
+ # @option options [Integer] :total (self.size) the expected number of iterations
25
+ # @option options [File, IO] :file ($stderr) a file-like object to output the progress bar to
26
+ # @option options [Boolean] :leave (false) should the progress bar should stay on screen after it's done?
27
+ # @option options [Integer] :min_iters see `:min_interval`
28
+ # @option options [Float] :min_interval If less than min_interval seconds or min_iters iterations have passed since
29
+ # the last progress meter update, it is not updated again.
30
+ #
31
+ # @example
32
+ # a = (1...1000)
33
+ # Decorator.new(a).enhance.each { |x| sleep 0.01 }
34
+ #
35
+ # @example
36
+ # a = [1, 2, 3, 4]
37
+ # Decorator.new(a, file: $stdout, leave: true)
38
+ def initialize(enumerable, options={})
39
+ @enumerable = enumerable
40
+ options.merge!(total: total!) unless options[:total]
41
+ @printer = Printer.new(options)
42
+ @min_iterations = options[:min_iters] || 1
43
+ @min_interval = options[:min_interval] || 0.5
44
+ @leave = options[:leave] || false
45
+ end
46
+
47
+ # Starts the textual progress bar.
48
+ def start!
49
+ @iteration = 0
50
+ @start_time = Time.now
51
+ printer.start
52
+ end
53
+
54
+ # Called everytime the textual progress bar might need to be updated (i.e. on
55
+ # every iteration). We still check whether the update is appropriate to print to
56
+ # the progress bar before doing so, according to the `:min_iters` and `:min_interval`
57
+ # options.
58
+ #
59
+ # @see #initialize
60
+ def increment!
61
+ @iteration += 1
62
+
63
+ return unless (iteration - last_printed_iteration) >= @min_iterations
64
+ # We check the counter first, to reduce the overhead of Time.now
65
+ return unless (current_time! - last_print_time) >= @min_interval
66
+
67
+ printer.status(iteration, elapsed_time!)
68
+ @last_printed_iteration = iteration
69
+ @last_print_time = current_time
70
+ end
71
+
72
+ # Prints the final state of the textual progress bar. Based on the `:leave` option, this
73
+ # may include deleting it entirely.
74
+ def finish!
75
+ return printer.null_finish unless @leave
76
+
77
+ printer.finish(iteration, elapsed_time!, reprint?)
78
+ end
79
+
80
+ # Enhances the wrapped `Enumerable`.
81
+ #
82
+ # @note The `Enumerable` is cloned (shallow copied) before it is enhanced; it is not modified directly.
83
+ #
84
+ # @return [Enumerable] a clone of Enumerable enhanced so that every call to `#each` animates the
85
+ # progress bar.
86
+ def enhance
87
+ decorate_enumerable_each
88
+ enhanced
89
+ end
90
+
91
+ private
92
+
93
+ def decorate_enumerable_each
94
+ tqdm = self
95
+ enhanced.define_singleton_method(:each) do |*args, &block|
96
+ tqdm.start!
97
+ result = super(*args) do |item|
98
+ block.call item if block
99
+ tqdm.increment!
100
+ end
101
+ tqdm.finish!
102
+ result
103
+ end
104
+ end
105
+
106
+ def enhanced
107
+ @enhanced ||= enumerable.clone
108
+ end
109
+
110
+ def total!
111
+ enumerable.size rescue enumerable.count rescue nil
112
+ end
113
+
114
+ def last_printed_iteration
115
+ @last_printed_iteration ||= iteration
116
+ end
117
+
118
+ def last_print_time
119
+ @last_print_time ||= start_time
120
+ end
121
+
122
+ def current_time
123
+ @current_time ||= current_time!
124
+ end
125
+
126
+ def current_time!
127
+ @current_time = Time.now
128
+ end
129
+
130
+ def elapsed_time!
131
+ current_time! - start_time
132
+ end
133
+
134
+ def reprint?
135
+ last_printed_iteration < iteration
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,70 @@
1
+ require 'tqdm/printer/default_format'
2
+ require 'forwardable'
3
+
4
+ module Tqdm
5
+
6
+ # Prints a status line, handling the deletion of previously printed lines with carriage
7
+ # returns as necessary. Instantiated by a `Decorator`.
8
+ #
9
+ # @private
10
+ class Printer
11
+ extend Forwardable
12
+
13
+ attr_reader :total, :format, :file
14
+
15
+ # Initialize a new Printer.
16
+ #
17
+ # @param options [Hash] the options for the instantiating Tqdm::Decorator
18
+ #
19
+ # @see Tqdm::Decorator#initialize
20
+ def initialize(options)
21
+ @total = options[:total]
22
+ @format = Printer::DefaultFormat.new(options)
23
+ @file = options[:file] || $stderr
24
+ @last_printed_length = 0
25
+ end
26
+
27
+ def start
28
+ line(0, 0.0)
29
+ end
30
+
31
+ # Pads a status line so that it is long enough to overwrite the previously written line
32
+ #
33
+ # @param iteration [Integer] number of iterations, out of the total, that are completed
34
+ # @param elapsed_time [Float] number of seconds passed since start
35
+ # @return [String] the padded line
36
+ def padded_line(iteration, elapsed_time)
37
+ meter_line = line(iteration, elapsed_time)
38
+ pad_size = [@last_printed_length - meter_line.size, 0].max
39
+ @last_printed_length = meter_line.size
40
+ meter_line + ' ' * pad_size
41
+ end
42
+
43
+ # Prints a line of text to @file, after deleting the previously printed line
44
+ #
45
+ # @param iteration [Integer] number of iterations, out of the total, that are completed
46
+ # @param elapsed_time [Float] number of seconds passed since start
47
+ def status(iteration, elapsed_time)
48
+ file.write("\r" + padded_line(iteration, elapsed_time))
49
+ file.flush
50
+ end
51
+
52
+ # Prints a line of text to @file, after deleting the previously printed line
53
+ #
54
+ # @param iteration [Integer] number of iterations, out of the total, that are completed
55
+ # @param elapsed_time [Float] number of seconds passed since start
56
+ # @param reprint [Boolean] do we need to reprint the line one last time?
57
+ def finish(iteration, elapsed_time, reprint)
58
+ file.write("\r" + padded_line(iteration, elapsed_time)) if reprint
59
+ file.write("\n")
60
+ file.flush
61
+ end
62
+
63
+ # Disappear without a trace.
64
+ def null_finish
65
+ file.write("\r" + ' ' * @last_printed_length + "\r")
66
+ end
67
+
68
+ def_delegators :format, :line, :meter
69
+ end
70
+ end
@@ -0,0 +1,74 @@
1
+ module Tqdm
2
+ class Printer
3
+ class DefaultFormat
4
+ PROGRESS_BAR_WIDTH = 10
5
+ SPACE = '-'
6
+ PROGRESS = '#'
7
+
8
+ # Initialize a new DefaultFormat.
9
+ #
10
+ # @param options [Hash] the options for the Tqdm::Decorator
11
+ #
12
+ # @see Tqdm::Decorator#initialize
13
+ def initialize(options)
14
+ @total = options[:total]
15
+ @prefix = options[:desc] ? options[:desc] + ': ' : ''
16
+ end
17
+
18
+ # Formats the prefix, progress bar and meter as a complete line to be printed
19
+ #
20
+ # @param iteration [Integer] number of finished iterations
21
+ # @param elapsed_time [Float] total number of seconds passed since start
22
+ # @return [String] the complete line to print
23
+ #
24
+ # @see #meter
25
+ def line(iteration, elapsed_time)
26
+ prefix + meter(iteration, total, elapsed_time)
27
+ end
28
+
29
+ # Formats a count (n) of total items processed + an elapsed time into a
30
+ # textual progress bar + meter.
31
+ #
32
+ # @param n [Integer] number of finished iterations
33
+ # @param total [Integer, nil] total number of iterations, or nil
34
+ # @param elapsed [Float] number of seconds passed since start
35
+ # @return [String] a textual progress bar + meter
36
+ def meter(n, total, elapsed)
37
+ total = (n > total ? nil : total) if total
38
+
39
+ elapsed_str = interval(elapsed)
40
+ rate = elapsed && elapsed > 0 ? ('%5.2f' % (n / elapsed)) : '?'
41
+
42
+ if total
43
+ frac = n.to_f / total
44
+
45
+ bar_length = (frac * PROGRESS_BAR_WIDTH).to_i
46
+ bar = PROGRESS * bar_length + SPACE * (PROGRESS_BAR_WIDTH - bar_length)
47
+
48
+ percentage = '%3d%%' % (frac * 100)
49
+
50
+ left_str = n > 0 ? (interval(elapsed / n * (total - n))) : '?'
51
+
52
+ '|%s| %d/%d %s [elapsed: %s left: %s, %s iters/sec]' % [bar, n, total,
53
+ percentage, elapsed_str, left_str, rate]
54
+ else
55
+ '%d [elapsed: %s, %s iters/sec]' % [n, elapsed_str, rate]
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ attr_reader :total, :prefix
62
+
63
+ # Formats a number of seconds into an hh:mm:ss string.
64
+ #
65
+ # @param t [Integer] a number of seconds
66
+ # @return [String] an hh:mm:ss string
67
+ def interval(seconds)
68
+ m, s = seconds.to_i.divmod(60)
69
+ h, m = m.divmod(60)
70
+ if h > 0 then '%d:%02d:%02d' % [h, m, s]; else '%02d:%02d' % [m, s]; end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -1,25 +1,28 @@
1
- require "sequel"
2
- require "tqdm"
1
+ require 'sequel'
2
+ require 'tqdm'
3
3
 
4
4
  # @see Sequel::Dataset
5
5
  module Sequel
6
-
6
+
7
7
  # In order to use `Tqdm` with Sequel Datasets, we can simply extend `Sequel::Dataset`
8
- # with the same `#tqdm` method
8
+ # with the same `#with_progress` method
9
9
  #
10
- # @see Enumerable#tqdm
10
+ # @see Enumerable#with_progress
11
11
  # @see http://sequel.jeremyevans.net/
12
12
  # @see http://sequel.jeremyevans.net/rdoc/classes/Sequel/Dataset.html
13
13
  class Dataset
14
-
15
- # Returns a clone of `self` where all calls to `#each` and related methods will print an animated progress bar
14
+
15
+ # Returns a clone of `self` where all calls to `#each` and related methods will print an animated progress bar
16
16
  # while iterating.
17
17
  #
18
- # @see Enumerable#tqdm
19
- def tqdm(opts = {})
20
- Tqdm::TqdmDecorator.new(self, opts).enhance
18
+ # @param options [Hash] options are the same as Enumerable#with_progress
19
+ #
20
+ # @see Enumerable#with_progress
21
+ def with_progress(options = {})
22
+ Tqdm::Decorator.new(self, options).enhance
21
23
  end
22
-
24
+ alias :tqdm :with_progress
25
+
23
26
  end
24
-
25
- end
27
+
28
+ end
@@ -1,4 +1,4 @@
1
1
  module Tqdm
2
2
  # The version of this module and gem by the same name.
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
@@ -20,6 +20,6 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
-
23
+
24
24
  spec.required_ruby_version = '>= 1.9.2'
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tqdm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theodore Pak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-20 00:00:00.000000000 Z
11
+ date: 2016-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -54,8 +54,10 @@ files:
54
54
  - Rakefile
55
55
  - lib/core_ext/enumerable.rb
56
56
  - lib/tqdm.rb
57
+ - lib/tqdm/decorator.rb
58
+ - lib/tqdm/printer.rb
59
+ - lib/tqdm/printer/default_format.rb
57
60
  - lib/tqdm/sequel.rb
58
- - lib/tqdm/utils.rb
59
61
  - lib/tqdm/version.rb
60
62
  - tqdm.gemspec
61
63
  homepage: https://github.com/powerpak/tqdm-ruby
@@ -1,50 +0,0 @@
1
- require "tqdm"
2
-
3
- module Tqdm
4
-
5
- # Utility functions related to `Tqdm`.
6
- module Utils
7
-
8
- # Formats a number of seconds into an hh:mm:ss string.
9
- #
10
- # @param t [Integer] a number of seconds
11
- # @return [String] an hh:mm:ss string
12
- def format_interval(t)
13
- mins, s = t.to_i.divmod(60)
14
- h, m = mins.divmod(60)
15
- if h > 0 then '%d:%02d:%02d' % [h, m, s]; else '%02d:%02d' % [m, s]; end
16
- end
17
-
18
- # Formats a count (n) of total items processed + an elapsed time into a
19
- # textual progress bar + meter.
20
- #
21
- # @param n [Integer] number of finished iterations
22
- # @param total [Integer, nil] total number of iterations, or nil
23
- # @param elapsed [Integer] number of seconds passed since start
24
- # @return [String] a textual progress bar + meter
25
- def format_meter(n, total, elapsed)
26
- total = (n > total ? nil : total) if total
27
-
28
- elapsed_str = format_interval(elapsed)
29
- rate = elapsed && elapsed > 0 ? ('%5.2f' % (n / elapsed)) : '?'
30
-
31
- if total
32
- frac = n.to_f / total
33
-
34
- bar_length = (frac * N_BARS).to_i
35
- bar = '#' * bar_length + '-' * (N_BARS - bar_length)
36
-
37
- percentage = '%3d%%' % (frac * 100)
38
-
39
- left_str = n > 0 ? (format_interval(elapsed / n * (total - n))) : '?'
40
-
41
- '|%s| %d/%d %s [elapsed: %s left: %s, %s iters/sec]' % [bar, n, total,
42
- percentage, elapsed_str, left_str, rate]
43
- else
44
- '%d [elapsed: %s, %s iters/sec]' % [n, elapsed_str, rate]
45
- end
46
- end
47
-
48
- end
49
-
50
- end