Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources]

David Ascher, Alex Martelli, Anna Ravenscroft

نسخه متنی -صفحه : 394/ 227
نمايش فراداده

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_ _":
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)

Programs that run lengthy operations, such as FTP downloads and 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.