import sys def twirler(position): if position == '|': return '/' elif position == '/': return '-' elif position == '-': return '\\' else: return '|' class progbar(): def __init__(self,length,out=sys.stdout,suffix='',subbar=None,text='',maxtextlength=79,twirler=False): self.maxval = None if '__len__' in dir(length): self.maxval = len(length) elif isinstance(length,int): self.maxval = length if not self.maxval: raise Exception('No Max Length Specified') self.current = 0 self.text = text self.out= out self.suffix = suffix self.percent = 0 self.subbar = subbar self.complete = False self.maxtextlength = maxtextlength self.twirler = twirler def incriment(self, amount=1): if self.subbar: if self.subbar.complete: oldbar = self.subbar self.subbar = None del(oldbar) else: self.subbar.incriment() return(True) self.current += amount self.percent = self.current * 100 / self.maxval if self.current == self.maxval: self.complete = True def updatetext(self,text): if self.subbar: if not self.subbar.complete: self.subbar.updatetext(text) return() self.text = text def tick(self,text = '',amount = 1): #updates the progress bar and outputs data if text: self.updatetext(text) self.incriment(amount) self.output() def twirl(self): #Twirls the twirler. Also turns twirler on if off. if not self.twirler: self.twirler = True self.output() def output(self): #outputs the progress bar content to self.out (default: stdout) self.out.write('\r') self.out.write(' ' * self.maxtextlength) self.out.write('\r') if self.twirler: self.twirler = twirler(self.twirler) outtext1 = self.textgen() outtext2 = outtext1 + " "*(self.maxtextlength - len(outtext1)) outtext3 = outtext2[:self.maxtextlength-1] + self.twirler self.out.write(outtext3) else: self.out.write(self.textgen()[:self.maxtextlength]) def textgen(self): #returns the progress bar's content substring = "" if self.subbar: substring = self.subbar.textgen() progstring = '(' + str(self.current) + ' ' + str(self.suffix) + '/' + str(self.maxval) + ' ' + str(self.suffix) + ')' return('|' + str(self.percent) + '% ' + progstring + '| ' + self.text + " | " + substring) def setsubbar(self,subbar): #sets the sub-bar to an already existing progbar instance if isinstance(subbar,progbar): if self.subbar: self.subbar.setsubbar(subbar) else: self.subbar = subbar else: raise Exception('sub progress bar is not of progbar type') def addsubbar(self,length,out=sys.stdout,suffix='',subbar=None,text=''): #creates a new progbar instance and sets it to the sub-bar. See __init__ for details newbar = progbar(length,out,suffix,subbar,text) self.setsubbar(newbar) class twirlbar(progbar): def __init__(self,text='',maxtextlength=79): self.twirler = '|' self.text = text self.maxtextlength=maxtextlength self.complete = False def tick(self): self.incriment() self.output() def incriment(self): self.twirler = twirler(self.twirler) def twirl(self): self.incriment() def output(self): #outputs the progress bar content to self.out (default: stdout) self.out.write('\r') self.out.write(' ' * self.maxtextlength) self.out.write('\r') self.out.write(self.textgen()) def addsubbar(self,*argv,**argc): pass def textgen(self): return(self.text[:self.maxtextlength-1] + self.twirler) def updatetext(self,text): self.text = text def finish(self): self.complete = True if __name__ == '__main__': import time import random #test program which counts to 10 seconds and has a sub-bar which counts tenths of seconds l1 = xrange(10) l2 = xrange(10) mainbar = progbar(l1) for x in l1: mainbar.tick('seconds') mainbar.addsubbar(l2) for y in l2: mainbar.tick('tenths') time.sleep(.1) #test program which sleeps for a tenth of a second a random number of times ten times mainbar = progbar(l1) for x in l1: mainbar.tick('pass' + str(x)) tbar = twirlbar() mainbar.setsubbar(tbar) for y in xrange(random.randrange(10,50)): mainbar.tick('doing thing 1') time.sleep(.1) for z in xrange(random.randrange(10,50)): mainbar.tick('doing thing 2 (' + str(z) + ')') time.sleep(.1) tbar.finish()