ProgressBar_py

#!/usr/bin/env python
'''
    NAME: progressBar.py
    AUTHOR: Augix
    DATE: 2009-05-20
    
    FUNCTION: this module prints a progress bar to show how much time you have to wait until the program finish.
    It simply reads a percentage to update the progress bar.
    
    USAGE: from progressBar import progressBar
    bar = progressBar(min=0, max=200, barLength=None, output=sys.stderr)
    for i in range(200):
        bar.update(i)
        time.sleep(0.1)
        
    Reference: http://code.activestate.com/recipes/168639/
'''

# === Dependencies ===
import sys, time

# === variables ===

# === functions ===

# === classes ===
class progressBar:
    def __init__(self, min = 0, max = 100, barLength = None, output=sys.stderr):
        self.output = output
        self.progBar = "[]"   # This holds the progress bar string
        self.min = min
        self.max = max - 1
        self.span = self.max - self.min + 1
        self.barLength = self.calBarLength(barLength)
        self.percentDone = 0
        self.timeStart = time.time()
        self.timePrevious = self.timeStart
        self.timePass = 0
        self.finish = False
        self.update(0)  # Build progress bar string
        
    def calBarLength(self, barLength):
        if barLength == None:
            from fcntl import ioctl
            from termios import TIOCGWINSZ
            from array import array
            a = ioctl(self.output,TIOCGWINSZ,'\0'*8)
            h,w=array('h',a)[:2]
            return w
        else: return barLength
        
    def calPercent(self, newAmount):
        diffFromMin = float(newAmount - self.min + 1)
        percentDone = (diffFromMin / float(self.span)) * 100.0
        return percentDone
        
    def calWaitingTime(self):
        self.timePass = time.time() - self.timeStart
        timeWait = self.timePass / float(self.percentDone) * (100.0 - self.percentDone)
        return timeWait
        
    def formatTime(self, seconds):
        seconds = int(round(seconds))
        hour = seconds / 3600
        if hour == 0: hour = ""
        else: hour = " " + str(hour) + " hour"
        minute = seconds % 3600 / 60
        if minute == 0: minute = ""
        else: minute = " " + str(minute) + " min"
        second = seconds % 60
        second = " " + str(second) + " sec"
        s = hour + minute + second
        return s
        
    def formatPercent(self, percent):
        i = str(int(round(percent)))
        s = " "*(3-len(i)) + i + "%"
        return s
        
    def update(self, newAmount = 0):
        timeNow = time.time()
        if timeNow - self.timePrevious < 0.5:
            if newAmount < self.max: return None
        self.timePrevious = timeNow
        # Calculate the percentage finished
        if newAmount < self.min: newAmount = self.min
        if newAmount >= self.max: newAmount = self.max; self.finish = True;
        self.percentDone = self.calPercent(newAmount)
        printPercent = self.formatPercent(self.percentDone)
        
        # Calculate the waiting time
        if self.percentDone == 0: printETA = ""
        elif self.finish == True: printETA = self.formatTime(self.timePass) + " used"
        else:
            timeWait = self.calWaitingTime()
            printETA = self.formatTime(timeWait) + " left"
       
        # Figure out how many '=' and spaces the bar should be
        spaceAndEqual = self.barLength - 11 - len(printETA)
        numEqual = (self.percentDone / 100.0) * spaceAndEqual
        numEqual = int(round(numEqual))
        
        # the rotating thing
        animation = '\|/-'
        printAnimation = animation[int(timeNow % 4)]
        
        # build a progress bar with "=" and spaces
        self.progBar = " " + printPercent + " [" + printAnimation + '='*numEqual + ">" + ' '*(spaceAndEqual-numEqual) + "] " + printETA
        if self.finish == True:
            self.output.write(self.progBar + "\n")
        else:
            self.output.write(self.progBar + "\r")
        
    def __str__(self):
        return str(self.progBar)

# === Main ===
if __name__ == '__main__':
    bar = progressBar(max=200)
    for i in range(200):
        bar.update(i)
        time.sleep(0.1)
Homepage
Comments

Hide Comments