Richard Jones' Log: Just some code - a console progress display class
Fri, 10 Dec 2004
Getting back into the swing of posting to this log... here's my variant on the usual progress display. Percentage with an ETA if it appears to be a long-running task. Examples at the end of the code. And hey, it's my first iterator (using __iter__ and not the old-school __getitem__, that is ;)
import sys,time class Progress: '''Progress display for console applications. See __main__ block at end of file for sample usage. ''' def __init__(self, info, sequence): self.info = info self.sequence = iter(sequence) self.total = len(sequence) self.start = self.now = time.time() self.num = 0 self.stepsize = self.total / 100 or 1 self.steptimes = [] self.display() def __iter__(self): return self def next(self): self.num += 1 if self.num > self.total: print self.info, 'done', ' '*(75-len(self.info)-6) sys.stdout.flush() return self.sequence.next() if self.num % self.stepsize: return self.sequence.next() self.display() return self.sequence.next() def display(self): # figure how long we've spent - guess how long to go now = time.time() steptime = now - self.now self.steptimes.insert(0, steptime) if len(self.steptimes) > 5: self.steptimes.pop() steptime = sum(self.steptimes) / len(self.steptimes) self.now = now eta = steptime * ((self.total - self.num)/self.stepsize) # tell it like it is (or might be) if now - self.start > 3: M = eta / 60 H = M / 60 M = M % 60 S = eta % 60 s = '%s %2d%% (ETA %02d:%02d:%02d)'%(self.info, self.num * 100. / self.total, H, M, S) else: s = '%s %2d%%'%(self.info, self.num * 100. / self.total) sys.stdout.write(s + ' '*(75-len(s)) + '\r') sys.stdout.flush() if __name__ == '__main__': for i in Progress('Testing 3...', range(3)): time.sleep(5) for i in Progress('Testing 1645...', range(1645)): time.sleep(.01)
It looks like there's a couple of entries in the cookbook that produce progress display. While this one has additional features, I don't think it's worth submitting.