See gist:3306295 for future developments.
Here is a little class that lets you present percent complete information in the form of a progress bar using the '=' character to represent completed portions, spaces to represent incomplete portions, '>' to represent the current portion and the actual percent done (rounded to integer) displayed at the end:
[===========> ] 60%
When you initialize the class, you specify the minimum number (defaults to 0), the maximum number (defaults to 100), and the desired width of the progress bar. The brackets []
are included in the size of the progress bar, but you must allow for up to 4 characters extra to display the percentage.
You'd probably want to use this in conjuction with the curses module, or something like that so you can over-write the same portion of the screen to make your updates 'animated'.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | import sys
class progressBar:
def __init__(self, minValue = 0, maxValue = 100, totalWidth=75):
""" Initializes the progress bar. """
self.progBar = "" # This holds the progress bar string
self.oldprogBar = ""
self.min = minValue
self.max = maxValue
self.span = maxValue - minValue
self.width = totalWidth
self.amount = 0 # When amount == max, we are 100% done
self.updateAmount(0) # Build progress bar string
def appendAmount(self, append):
""" Increases the current amount of the value of append and
updates the progress bar to new ammount. """
self.updateAmount(self.amount + append)
def updatePercentage(self, newPercentage):
""" Updates the progress bar to the new percentage. """
self.updateAmount((newPercentage * float(self.max)) / 100.0)
def updateAmount(self, newAmount = 0):
""" Update the progress bar with the new amount (with min and max
values set at initialization; if it is over or under, it takes the
min or max value as a default. """
if newAmount < self.min: newAmount = self.min
if newAmount > self.max: newAmount = self.max
self.amount = newAmount
# Figure out the new percent done, round to an integer
diffFromMin = float(self.amount - self.min)
percentDone = (diffFromMin / float(self.span)) * 100.0
percentDone = int(round(percentDone))
# Figure out how many hash bars the percentage should be
allFull = self.width - 2
numHashes = (percentDone / 100.0) * allFull
numHashes = int(round(numHashes))
# Build a progress bar with an arrow of equal signs; special cases for
# empty and full
if numHashes == 0:
self.progBar = "[>%s]" % (' '*(allFull-1))
elif numHashes == allFull:
self.progBar = "[%s]" % ('='*allFull)
else:
self.progBar = "[%s>%s]" % ('='*(numHashes-1), ' '*(allFull-numHashes))
# figure out where to put the percentage, roughly centered
percentPlace = (len(self.progBar) / 2) - len(str(percentDone))
percentString = str(percentDone) + "%"
# slice the percentage into the bar
self.progBar = ' '.join([self.progBar, percentString])
def draw(self):
""" Draws the progress bar if it has changed from it's previous value. """
if self.progBar != self.oldprogBar:
self.oldprogBar = self.progBar
sys.stdout.write(self.progBar + '\r')
sys.stdout.flush() # force updating of screen
def __str__(self):
""" Returns the current progress bar. """
return str(self.progBar)
|
I forked this recipe after integrating my own improvements and others found in the original discussion.
I tested it with python 2.6 and 2.7. Please advise if you tested it with another python version.
Example usage:
# Initiates the progessBar
prog = progressBar(maxValue = 50)
# Uses appendAmount to set current value (20).
prog.updateAmount(20)
# Draws the progress bar only if it has changed from previous draw() call.
prog.draw()
# Uses appendAmount to increment the current value (20+2).
prog.appendAmount(2)
# Draws the progress bar only if it has changed from previous draw() call.
prog.draw()
# Uses updatePercentage to set the percentage to the given value (74% of 50).
prog.updatePercentage(74)
# Draws the progress bar only if it has changed from previous draw() call.
prog.draw()
Example of proper usage will be hepfull and appreciated.
@O. Chema I just added an example. Cheers!