class ProgressPrinter

A progress printer which simplifies logging the progress of loops. To use, create a new ProgressPrinter, and then increment inside of a loop.

Example:

printer = ProgressPrinter.new(name: "Counting", total: 250)
printer.start
250.times { printer.increment }
printer.finish

Output:

Counting:   0/250   0% calculating...
Counting: 100/250  40% ~1m30s
Counting: 200/250  80% ~30s
Counting: 250/250 100% 2m30s total

Constants

DEFAULT_EVERY
VERSION

Attributes

silent[RW]
every[R]
name[R]
out[R]
start_time[RW]
total[R]

Public Class Methods

new(total: nil, name: nil, every: DEFAULT_EVERY, out: $stdout) click to toggle source
# File lib/progress_printer.rb, line 36
def initialize(total: nil, name: nil, every: DEFAULT_EVERY, out: $stdout)
  @total = total
  @name = name
  @every = every

  if self.class.silent
    @out = StringIO.new
  else
    @out = out
  end
end
silence() click to toggle source
# File lib/progress_printer.rb, line 24
def silence
  self.silent = true
end
wrap(*args, &block) click to toggle source
# File lib/progress_printer.rb, line 28
def wrap(*args, &block)
  new(*args).wrap(&block)
end

Private Class Methods

format_duration(seconds) click to toggle source
# File lib/progress_printer.rb, line 156
def self.format_duration(seconds)
  seconds = seconds.to_i

  minutes = seconds / 60
  seconds = seconds % 60

  hours = minutes / 60
  minutes = minutes % 60

  days = hours / 24
  hours = hours % 24

  buffer = ""
  buffer.prepend "#{seconds.to_i}s" if seconds.nonzero?
  buffer.prepend "#{minutes.to_i}m" if minutes.nonzero?
  buffer.prepend "#{hours.to_i}h" if hours.nonzero?
  buffer.prepend "#{days.to_i}d" if days.nonzero?
  buffer = "0s" if buffer == ""
  buffer
end

Public Instance Methods

current() click to toggle source
# File lib/progress_printer.rb, line 106
def current
  enum.peek - 1
end
estimated_time_remaining(now = Time.now) click to toggle source
# File lib/progress_printer.rb, line 86
def estimated_time_remaining(now = Time.now)
  return unless total
  return "calculating..." if current == 0

  "~" + self.class.format_duration(seconds_remaining(now))
end
finish() click to toggle source
# File lib/progress_printer.rb, line 66
def finish
  print_progress current, final: true
end
increment(count = 1) click to toggle source
# File lib/progress_printer.rb, line 60
def increment(count = 1)
  n = nil
  count.times { n = enum.next }
  print_progress n if at_milestone?
end
percent_complete() click to toggle source
# File lib/progress_printer.rb, line 70
def percent_complete
  return unless total
  return 1.0 if current >= total
  current / total.to_f
end
percent_complete_string() click to toggle source
# File lib/progress_printer.rb, line 76
def percent_complete_string
  return unless total
  "#{(percent_complete * 100).to_i}%"
end
percent_remaining() click to toggle source
# File lib/progress_printer.rb, line 81
def percent_remaining
  return unless total
  1.0 - percent_complete
end
seconds_remaining(now) click to toggle source
# File lib/progress_printer.rb, line 93
def seconds_remaining(now)
  return unless total
  return if percent_remaining == 1.0
  return 0.0 if percent_remaining == 0.0

  time_passed(now) / percent_complete * (1.0 - percent_complete)
end
start() click to toggle source
# File lib/progress_printer.rb, line 55
def start
  self.start_time = Time.now
  print_progress 0
end
time_passed(now = Time.now) click to toggle source
# File lib/progress_printer.rb, line 101
def time_passed(now = Time.now)
  return unless start_time
  now - start_time
end
wrap() { |self| ... } click to toggle source
# File lib/progress_printer.rb, line 48
def wrap
  start
  yield(self)
ensure
  finish
end

Private Instance Methods

at_milestone?() click to toggle source
# File lib/progress_printer.rb, line 112
def at_milestone?
  current % every == 0
end
enum() click to toggle source
# File lib/progress_printer.rb, line 116
def enum
  @enum ||= (1..Float::INFINITY).enum_for
end
left_pad(string, length) click to toggle source
# File lib/progress_printer.rb, line 146
def left_pad(string, length)
  pad_length = length - string.to_s.length
  return string if pad_length <= 0
  "#{' ' * pad_length}#{string}"
end
print_progress(n, final: false) click to toggle source
total_length() click to toggle source
# File lib/progress_printer.rb, line 152
def total_length
  @total_length ||= total.to_s.length
end