Recipe 11.1. Showing a Progress Indicator on a Text Console
Credit: Larry Bates
Problem
Your program has
no GUI (i.e., your program just runs on a text console), and yet you
want your program to show to the user a "progress
indicator bar" during lengthy operations, to
communicate that work is progressing and the amount of the total work
that has been completed.
Solution
We can easily code a simple little class to handle this whole task:
import sys
class progressbar(object):
def _ _init_ _(self, finalcount, block_char='.'):
self.finalcount = finalcount
self.blockcount = 0
self.block = block_char
self.f = sys.stdout
if not self.finalcount: return
self.f.write('\n------------------ % Progress -------------------1\n')
self.f.write(' 1 2 3 4 5 6 7 8 9 0\n')
self.f.write('----0----0----0----0----0----0----0----0----0----0\n')
def progress(self, count):
count = min(count, self.finalcount)
if self.finalcount:
percentcomplete = int(round(100.0*count/self.finalcount))
if percentcomplete < 1: percentcomplete = 1
else:
percentcomplete=100
blockcount = int(percentcomplete//2)
if blockcount <= self.blockcount:
return
for i in range(self.blockcount, blockcount):
self.f.write(self.block)
self.f.flush( )
self.blockcount = blockcount
if percentcomplete == 100:
self.f.write("\n")
Discussion
Here is an
example of the use of this progressbar class,
presented, as usual, with a guard of if _ _name_ _ == '_
_main_ _'. We can make it part of the module containing the
class and have it run when the module is executed as a
"main script":
if _ _name_ _ == "_ _main_ _":Programs that run lengthy operations, such as FTP downloads and
from time import sleep
pb = progressbar(8, "*")
for count in range(1, 9):
pb.progress(count)
sleep(0.2)
pb = progressbar(100)
pb.progress(20)
sleep(0.3)
pb.progress(47)
sleep(0.3)
pb.progress(90)
sleep(0.3)
pb.progress(100)
print "testing 1:"
pb = progressbar(1)
pb.progress(1)
database insertions, should normally give visual feedback to the user
regarding the progress of the task that is running. GUI toolkits
generally have such facilities included as
"widgets", but if your program does
not otherwise require a GUI, it's overkill to give
it one just to be able to display a progress bar. This
recipe's progress bar class provides an easy way of
showing the percentage of completion that is updated periodically by
the program.The recipe operates on the basis of a totally arbitrary final count
that the ongoing task is supposed to reach at the end. This makes it
optimally easy for the application that makes use of the
progressbar class: the application can use any handy
unit of measure (such as amount of bytes downloaded for an FTP
download, number of records inserted for a database insertion, etc.)
to track the task's progress and completion. As long
as the same unit of measure applies to both the
"final count" and the
count argument that the application must
periodically pass to the progress method, the
progress bar's display will be accurate.
See Also
Documentation on text-mode console I/O in Python in a
Nutshell.