Text-based progress bar in Ruby for command line programs
When I’m running tests and tools, I frequently want to know how far through I am. I’d built a class to help with this a while back, but Corey Goldberg’s recent post on a python version prompted me to post this Ruby version.
First, you’ll need to save this to progress_bar.rb:
class Progress_bar
attr_accessor :items_to_do, :items_done
def initialize(items_to_do, items_done=0)
reset(items_to_do, items_done)
end
def percent_complete
return (@items_complete*1.0/@items_to_do*1.0)*100
end
def advance(steps_to_advance=1)
@items_complete+=steps_to_advance
end
def reset(items_to_do, items_done=0)
@items_to_do=items_to_do
@items_complete=items_done
end
def report
$stderr.print "\r#{progress_bar} #{@items_complete} of #{@items_to_do} done"
end
def progress_bar
complete_bar=(percent_complete/2.0).floor
incomplete_bar=((100-percent_complete)/2.0).ceil
return "[#{"*"*complete_bar}#{"-"*incomplete_bar}]"
end
end
You can then mix this in to so that when you iterate through collections, you can report on your progress. Handy for data-driven tests:
require 'progress_bar.rb'
module Enumerable
def each_with_progress
progress=Progress_bar.new(self.size)
self.each do |item |
progress.advance
yield item
progress.report
end
end
end
# Examples:
b={1=>"a",2=>"b"}
puts "Iterating through hash"
b.each_with_progress do | val |
# do stuff
sleep 2
end
puts
puts "Iterating through array"
c=[1,2,3,4]
c.each_with_progress do | val |
# do stuff
sleep 2
end
puts "Manual control..."
pb=Progress_bar.new(40,20)
5.times do
pb.advance
pb.report
sleep 1
end
5.times do
pb.advance(2)
sleep 1
pb.report
end
If you run from the command line, your output will look something like this:
[*******************************************——-] 35 of 40 done
This should all appear on a single line, although anything sent to standard output will force this to go to a new line. I never managed to get ANSI terminal display libraries working.
Enjoy!
Nice! Thank you…..
Exactly what I needed! Awsome implementation! Thanks!