Recipe 11.1. Showing a Progress Indicator on a Text ConsoleCredit: Larry Bates ProblemYour 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. SolutionWe 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") DiscussionHere 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 AlsoDocumentation on text-mode console I/O in Python in a Nutshell. |