Added progress bar script

This commit is contained in:
Zakary Timson 2016-05-10 20:37:47 -04:00
parent d7e95ab4dd
commit 21054a246e

140
progress_bar.py Normal file
View File

@ -0,0 +1,140 @@
from time import time
from sys import stdout
class ProgressBar:
"""
An iterable object that can display statics about its self such as time elapsed, percentage, progress as a fraction,
iterations per second, estimated time and can generate an ascii progressbar.
"""
def __init__(self, start, end=None, step=1, length=20, unit="/s", color="\033[0;31m", display=True,
bar_format="{elapsed} {percentage} {bar} {rate} {eta}"):
"""
Create an iterable object with the following properties. If no end is specified the start is assumed the end.
:param start: starting position of iterator (inclusive)
:param end: ending position of iterator (exclusive)
:param step: how many integers to add each iteration
:param length: length of the progress bar (default is 20)
:param unit: unit to display with the rate (default is /s)
:param color: ANSI escape codes prepended to output to change color (default is \033[0;31m )
:param display: automatically display statistics on every iteration (default True)
:param bar_format: format the way statistics are displayed. Components to display are: elapsed, percentage, bar,
fraction, rate and eta. These keywords are swapped out for the actual information. (default is
"{elapsed} {percentage} {bar} {rate} {eta}")
"""
if end is None:
self.start = 0
self.end = start
else:
self.start = start
self.end = end
self.step = step
self.length = length
self.unit = unit
self.color = color
self.display = display
self.bar_format = bar_format
def __iter__(self):
"""
initiate iterator which sets the starting point and gets the current time which is used for statistics
:return: returns the new object
"""
self.start_time = time()
self.current = self.start
return self
def __next__(self):
"""
next overload. If display is true the latest stetistics are displayed
:return: The next number in iterator
"""
if self.display:
self.__restart_line()
stdout.write(str(self))
stdout.flush()
if self.current >= self.end:
raise StopIteration
self.current += self.step
return self.current - self.step
def __str__(self):
"""
displays the iterator as a string of statistics
:return: formatted string
"""
return self.color + self.bar_format.format(bar=self.generate_bar(),
elapsed=self.__time_format(self.elapsed()),
eta=self.__time_format(self.estimated_time()),
fraction=self.fraction(),
percentage=(str(int(self.percentage() * 100)) + "%").rjust(4),
rate=str(self.per_second()) + self.unit)
def elapsed(self):
"""
calculate the time that has elapsed
:return: long elapsed time
"""
return time() - self.start_time
def estimated_time(self):
"""
Use the current percentage and elapsed time to determine an ETA
:return: how much time is left
"""
try:
return self.elapsed() / self.percentage() - self.elapsed()
except ZeroDivisionError:
return 0
def fraction(self):
"""
create a fraction representing the progress and the end of the iterator
:return: string representing current/end of iterator
"""
return "%s/%d" % (str(self.current).rjust(len(str(self.end))), self.end)
def generate_bar(self):
"""
creates an ascii progressbar
:return: string progressbar
"""
bar = "[{0}]".format(("=" * int(self.percentage() * self.length)).ljust(self.length))
return bar
def per_second(self):
"""
use the current number of iterations and the amount of elapsed time to determine how many iterations per second
:return:
"""
try:
return round(self.current / self.step / self.elapsed(), 2)
except ZeroDivisionError:
return 0
def percentage(self):
"""
use current position / (end - start) to calculate percentage of completion
:return: float of percentage to completion
"""
return self.current / (self.end - self.start)
@staticmethod
def __restart_line():
"""
Writes return carriage to stdout and flushes. This allows writing to the same line.
:return: None
"""
stdout.write('\r')
stdout.flush()
@staticmethod
def __time_format(time_to_format):
"""
formats time to mm:ss
:param time_to_format: long to format
:return: string of time
"""
m, s = divmod(time_to_format, 60)
return "%02d:%02d" % (m, s)