Skip to content

Instantly share code, notes, and snippets.

@aalin
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aalin/f8b004d066a779616e9c to your computer and use it in GitHub Desktop.
Save aalin/f8b004d066a779616e9c to your computer and use it in GitHub Desktop.
class Progress
class DefaultFormatter
def progress_format(current, total)
format("\e[K\e[G %5.2f%% (%s / %s)", current / total.to_f * 100.0, format_number(current), format_number(total))
end
def format_number(number)
number.to_s.chars.reverse.each_slice(3).map(&:reverse).reverse.map(&:join).join(" ")
end
end
UPDATE_FREQUENCY = 0.01
attr_accessor :current
attr_reader :total
def initialize(total, formatter: DefaultFormatter.new, out: $stdout)
@out = out
@current = 0
@total = total
@formatter = formatter
@last_print_at = nil
if block_given?
@out.print "\e[?25l"
begin
yield self
ensure
@out.puts "\e[?25h"
end
end
end
def print
return unless should_print?
@last_print_at = Time.now
@out.print @formatter.progress_format(@current.succ, @total)
@out.flush
end
private
def should_print?
return true unless @last_print_at
return true if Time.now - @last_print_at > UPDATE_FREQUENCY
return true if @current.succ >= @total
false
end
end
count = 10_000_000
Progress.new(count) do |progress|
count.times do |i|
progress.current = i
progress.print
sleep Math.sin(i * 3000).abs * 0.000001
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment