From 045f20061c17e75df69845218bb65f4b8e212e12 Mon Sep 17 00:00:00 2001 From: Zak Timson Date: Wed, 25 Jan 2017 09:34:06 -0500 Subject: [PATCH] Ready for upload to pip --- MANIFEST | 4 + ZProgressbar/ZProgressbar.py | 140 ++++++++++++++++++ ZProgressbar/__init__.py | 1 + .../__pycache__/ZProgressbar.cpython-35.pyc | Bin 0 -> 5831 bytes dist/ZProgressbar-1.0.tar.gz | Bin 0 -> 2279 bytes setup.py | 8 +- 6 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 MANIFEST create mode 100644 ZProgressbar/ZProgressbar.py create mode 100644 ZProgressbar/__init__.py create mode 100644 ZProgressbar/__pycache__/ZProgressbar.cpython-35.pyc create mode 100644 dist/ZProgressbar-1.0.tar.gz diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..8ead968 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,4 @@ +# file GENERATED by distutils, do NOT edit +setup.py +ZProgressbar/ZProgressbar.py +ZProgressbar/__init__.py diff --git a/ZProgressbar/ZProgressbar.py b/ZProgressbar/ZProgressbar.py new file mode 100644 index 0000000..1db4dcc --- /dev/null +++ b/ZProgressbar/ZProgressbar.py @@ -0,0 +1,140 @@ +from time import time +from sys import stdout + + +class ZProgressbar: + """ + 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) diff --git a/ZProgressbar/__init__.py b/ZProgressbar/__init__.py new file mode 100644 index 0000000..c5f405e --- /dev/null +++ b/ZProgressbar/__init__.py @@ -0,0 +1 @@ +from ZProgressbar.py import Progressbar \ No newline at end of file diff --git a/ZProgressbar/__pycache__/ZProgressbar.cpython-35.pyc b/ZProgressbar/__pycache__/ZProgressbar.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..153d4def1f79ef18a67d6cab4d2815120497c008 GIT binary patch literal 5831 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