46 Commits

Author SHA1 Message Date
Georgios Verigakis
200e1f44da Merge pull request #112 from Precioussheep/feature/build-migration
migrate setup.py to pyproject.toml
2025-07-01 08:18:14 +03:00
precioussheep
715467d4d0 migrate setup.py to pyproject.toml 2025-06-02 10:54:02 +10:00
Georgios Verigakis
1f658bc627 Merge pull request #111 from snoyes/patch-1
Update README.rst
2024-10-29 10:11:14 +02:00
Scott Noyes
eebaa99c82 Update README.rst
Fix spelling error
2024-10-28 07:56:43 -05:00
Georgios Verigakis
52de04b95d Merge pull request #108 from tobek/patch-1
Fix typo in test_progress.py
2023-05-10 08:35:51 +02:00
Toby Fox
bdce3afb5e Fix typo in test_progress.py 2023-05-09 21:49:28 +01:00
Georgios Verigakis
0a5fc077b2 Merge pull request #99 from VSS-DEV/test-install
Update setup.py
2021-11-15 10:09:14 +02:00
VSS-DEV
3beeeb7716 Update setup.py 2021-11-14 15:33:43 +03:00
Georgios Verigakis
e3dbaf52e1 Bump version 2021-07-28 09:51:10 +03:00
Georgios Verigakis
ca6310204e Use the formal form everywhere 2020-07-20 15:42:07 +03:00
Georgios Verigakis
b8fdfc782d Add color support
Fixes #27
2020-07-20 15:34:23 +03:00
Georgios Verigakis
0faea87060 Style change 2020-07-20 13:41:50 +03:00
Georgios Verigakis
64671e1ceb atexit.unregister does not exist in Python 2.7
Implement this with __del__ instead
2020-07-20 13:32:47 +03:00
Georgios Verigakis
12e46ed702 Do not use ANSI to clear line 2020-07-20 13:22:48 +03:00
Georgios Verigakis
d325dab247 Support formatted messages to remaining progress types
This is a followup to the changes for #76. We can now remove the write function.
2020-07-20 12:46:43 +03:00
Georgios Verigakis
e5c2368c6b Merge pull request #79 from mathstuf/avoid-division-by-zero
progress: avoid division by zero
2020-07-20 12:39:10 +03:00
Georgios Verigakis
03d4adbf73 Merge pull request #78 from mathstuf/iter-value-as-property
iter: expose the iteration value to the object
2020-07-20 12:38:34 +03:00
Georgios Verigakis
42fd17f67c Merge pull request #77 from mathstuf/spinner-format-message
spinner: support formatted messages
2020-07-20 12:35:01 +03:00
Ben Boeckel
0d93258f52 progress: avoid division by zero
This occurs otherwise with `bar.iter([])`.
2020-03-31 15:14:55 -04:00
Ben Boeckel
4af220e573 iter: expose the iteration value to the object
Mentioned in #76.
2020-03-30 20:23:15 -04:00
Ben Boeckel
25cefd12db spinner: support formatted messages
Fixes #76
2020-03-30 20:14:43 -04:00
Georgios Verigakis
1ed414290f Merge pull request #69 from frasern/atexit
Fixed #64 -- ensure hidden cursor is reshown at exit.
2019-07-02 15:12:13 +03:00
Fraser Nevett
f6390b76f2 Fixed #64 -- ensure hidden cursor is reshown at exit. 2019-06-04 13:26:06 +01:00
Georgios Verigakis
80a91b9c78 Merge pull request #68 from edwardbarak/patch-1
Add additional help when AttributeError is raised with regards check_tty
2019-05-06 11:47:07 +03:00
Edward Barak
57a36d49f2 Add help message to check_tty AttributeError 2019-04-28 22:44:01 -04:00
Georgios Verigakis
efeb57282b Bump version 2019-03-06 09:25:32 +02:00
Georgios Verigakis
61627a8642 Merge pull request #61 from pquentin/throttle-eta
Update avg/eta/eta_td only once per second
2019-02-01 16:24:21 +02:00
Quentin Pradet
c1e07104e1 Update avg/eta/eta_td less frequently
When the progress bar is updated frequently (every few milliseconds),
the eta can change so quickly that it's impossible to read.

This commit updates the average while sma_window is being filled, then
after every second.

This means we're calling monotonic/time often, but those calls take less
than 100 nsec per loop on Linux, Windows and macOS [0], which is
equivalent to one attribute lookup or two.

[0]: https://github.com/python-trio/trio/issues/33
2019-02-01 18:16:14 +04:00
Quentin Pradet
326413a271 Use time.monotonic if available 2018-11-16 17:22:45 +04:00
Georgios Verigakis
1b326504ce Merge pull request #57 from Kilo59/patch-1
Add Pypi link and instuctions to ReadMe
2018-10-12 14:00:07 +03:00
Georgios Verigakis
b95b764e37 Merge pull request #54 from dotlambda/patch-1
Include tests in PyPI tarball
2018-10-12 13:59:02 +03:00
Gabriel
2eeff94083 Add Pypi link and instuctions to ReadMe
Made Pypi badge link to Pypi page.

Added Installation instructions
2018-10-11 10:48:10 -04:00
Robert Schütz
8cf7faa4e3 Include tests in PyPI tarball 2018-10-10 09:32:21 +02:00
Georgios Verigakis
4b7c9388f4 Remove SigIntMixin
This was meant mostly as an example, it doesn't justify its own file.
2018-09-13 10:37:21 +03:00
Georgios Verigakis
d9d40736d6 Fold the mixins in __init__.py
The 2 mixins were almost the same, simplify the codebase by merging them in.
2018-09-13 10:34:24 +03:00
Georgios Verigakis
d407334bcf Merge pull request #29 from TobiX/contextmanager
Allow usage as a context manager.
2018-08-01 13:08:02 +03:00
Tobias Gruetzmacher
086cfd5599 Allow usage as a context manager. 2018-08-01 12:01:56 +02:00
Georgios Verigakis
6553b7b207 Implement write using \r instead of \b
This is to appease PyCharm that doesn't implement \b.
2018-07-10 13:32:05 +03:00
Georgios Verigakis
1f19b5b61c Add flag to override tty check 2018-07-10 13:23:43 +03:00
Georgios Verigakis
f5c911ed83 Bump 2018-06-25 09:06:26 +03:00
Georgios Verigakis
5d52c5b299 Avoid unprintable chars on Windows
Fixes #36
2018-05-31 09:47:00 +03:00
Georgios Verigakis
a83f91f4b8 Handles the case where self.file is None
Fixes #46
2018-03-13 15:53:27 +02:00
Georgios Verigakis
292a031c4b Revert "Fixed broken character in windows" 2018-01-31 10:22:22 +02:00
Georgios Verigakis
83f3b79137 Merge pull request #44 from LiamGow/patch-1
Fixed broken character in windows
2018-01-30 09:43:54 +02:00
LiamGow
84c3b9197a Fixed broken character in windows 2018-01-29 21:39:28 -08:00
Georgios Verigakis
715a2e130f Fix copy paste typo 2017-04-10 14:40:06 +03:00
12 changed files with 264 additions and 175 deletions

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
# Copyright (c) 2012 Georgios Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above

View File

@@ -1 +0,0 @@
include README.rst LICENSE

View File

@@ -6,6 +6,7 @@ Easy progress reporting for Python
|demo|
.. |pypi| image:: https://img.shields.io/pypi/v/progress.svg
:target: https://pypi.org/project/progress/
.. |demo| image:: https://raw.github.com/verigak/progress/master/demo.gif
:alt: Demo
@@ -34,6 +35,17 @@ To use them, just call ``next`` to advance and ``finish`` to finish:
bar.next()
bar.finish()
or use any bar of this class as a context manager:
.. code-block:: python
from progress.bar import Bar
with Bar('Processing', max=20) as bar:
for i in range(20):
# Do some work
bar.next()
The result will be a bar like the following: ::
Processing |############# | 42/100
@@ -74,7 +86,7 @@ eta avg * remaining
eta_td eta as a timedelta (useful for printing as a string)
========== ================================
Instead of passing all configuration options on instatiation, you can create
Instead of passing all configuration options on instantiation, you can create
your custom subclass:
.. code-block:: python
@@ -117,6 +129,15 @@ There are 5 predefined spinners:
- ``LineSpinner``
- ``PixelSpinner``
Installation
============
Download from PyPi
.. code-block:: shell
pip install progress
Other
=====

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
# Copyright (c) 2012 Georgios Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -12,31 +12,54 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import division
from __future__ import division, print_function
from collections import deque
from datetime import timedelta
from math import ceil
from sys import stderr
from time import time
try:
from time import monotonic
except ImportError:
from time import time as monotonic
__version__ = '1.3'
__version__ = '1.6.1'
HIDE_CURSOR = '\x1b[?25l'
SHOW_CURSOR = '\x1b[?25h'
class Infinite(object):
file = stderr
sma_window = 10 # Simple Moving Average window
check_tty = True
hide_cursor = True
def __init__(self, *args, **kwargs):
def __init__(self, message='', **kwargs):
self.index = 0
self.start_ts = time()
self.start_ts = monotonic()
self.avg = 0
self._avg_update_ts = self.start_ts
self._ts = self.start_ts
self._xput = deque(maxlen=self.sma_window)
for key, val in kwargs.items():
setattr(self, key, val)
self._max_width = 0
self._hidden_cursor = False
self.message = message
if self.file and self.is_tty():
if self.hide_cursor:
print(HIDE_CURSOR, end='', file=self.file)
self._hidden_cursor = True
self.writeln('')
def __del__(self):
if self._hidden_cursor:
print(SHOW_CURSOR, end='', file=self.file)
def __getitem__(self, key):
if key.startswith('_'):
return None
@@ -44,7 +67,7 @@ class Infinite(object):
@property
def elapsed(self):
return int(time() - self.start_ts)
return int(monotonic() - self.start_ts)
@property
def elapsed_td(self):
@@ -52,8 +75,14 @@ class Infinite(object):
def update_avg(self, n, dt):
if n > 0:
xput_len = len(self._xput)
self._xput.append(dt / n)
self.avg = sum(self._xput) / len(self._xput)
now = monotonic()
# update when we're still filling _xput, then after every second
if (xput_len < self.sma_window or
now - self._avg_update_ts > 1):
self.avg = sum(self._xput) / len(self._xput)
self._avg_update_ts = now
def update(self):
pass
@@ -61,11 +90,33 @@ class Infinite(object):
def start(self):
pass
def writeln(self, line):
if self.file and self.is_tty():
width = len(line)
if width < self._max_width:
# Add padding to cover previous contents
line += ' ' * (self._max_width - width)
else:
self._max_width = width
print('\r' + line, end='', file=self.file)
self.file.flush()
def finish(self):
pass
if self.file and self.is_tty():
print(file=self.file)
if self._hidden_cursor:
print(SHOW_CURSOR, end='', file=self.file)
self._hidden_cursor = False
def is_tty(self):
try:
return self.file.isatty() if self.check_tty else True
except AttributeError:
msg = "%s has no attribute 'isatty'. Try setting check_tty=False." % self
raise AttributeError(msg)
def next(self, n=1):
now = time()
now = monotonic()
dt = now - self._ts
self.update_avg(n, dt)
self._ts = now
@@ -73,12 +124,20 @@ class Infinite(object):
self.update()
def iter(self, it):
try:
self.iter_value = None
with self:
for x in it:
self.iter_value = x
yield x
self.next()
finally:
self.finish()
del self.iter_value
def __enter__(self):
self.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.finish()
class Progress(Infinite):
@@ -100,6 +159,8 @@ class Progress(Infinite):
@property
def progress(self):
if self.max == 0:
return 0
return min(1, self.index / self.max)
@property
@@ -119,9 +180,10 @@ class Progress(Infinite):
except TypeError:
pass
try:
self.iter_value = None
with self:
for x in it:
self.iter_value = x
yield x
self.next()
finally:
self.finish()
del self.iter_value

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
# Copyright (c) 2012 Georgios Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -15,26 +15,28 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals
import sys
from . import Progress
from .helpers import WritelnMixin
from .colors import color
class Bar(WritelnMixin, Progress):
class Bar(Progress):
width = 32
message = ''
suffix = '%(index)d/%(max)d'
bar_prefix = ' |'
bar_suffix = '| '
empty_fill = ' '
fill = '#'
hide_cursor = True
color = None
def update(self):
filled_length = int(self.width * self.progress)
empty_length = self.width - filled_length
message = self.message % self
bar = self.fill * filled_length
bar = color(self.fill * filled_length, fg=self.color)
empty = self.empty_fill * empty_length
suffix = self.suffix % self
line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix,
@@ -61,7 +63,10 @@ class FillingCirclesBar(ChargingBar):
class IncrementalBar(Bar):
phases = (' ', '', '', '', '', '', '', '', '')
if sys.platform.startswith('win'):
phases = (u' ', u'', u'')
else:
phases = (' ', '', '', '', '', '', '', '', '')
def update(self):
nphases = len(self.phases)
@@ -71,7 +76,7 @@ class IncrementalBar(Bar):
nempty = self.width - nfull # Number of empty chars
message = self.message % self
bar = self.phases[-1] * nfull
bar = color(self.phases[-1] * nfull, fg=self.color)
current = self.phases[phase] if phase > 0 else ''
empty = self.empty_fill * max(0, nempty - len(current))
suffix = self.suffix % self

79
progress/colors.py Normal file
View File

@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Georgios Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from functools import partial
COLORS = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan',
'white')
STYLES = ('bold', 'faint', 'italic', 'underline', 'blink', 'blink2',
'negative', 'concealed', 'crossed')
def color(s, fg=None, bg=None, style=None):
sgr = []
if fg:
if fg in COLORS:
sgr.append(str(30 + COLORS.index(fg)))
elif isinstance(fg, int) and 0 <= fg <= 255:
sgr.append('38;5;%d' % int(fg))
else:
raise Exception('Invalid color "%s"' % fg)
if bg:
if bg in COLORS:
sgr.append(str(40 + COLORS.index(bg)))
elif isinstance(bg, int) and 0 <= bg <= 255:
sgr.append('48;5;%d' % bg)
else:
raise Exception('Invalid color "%s"' % bg)
if style:
for st in style.split('+'):
if st in STYLES:
sgr.append(str(1 + STYLES.index(st)))
else:
raise Exception('Invalid style "%s"' % st)
if sgr:
prefix = '\x1b[' + ';'.join(sgr) + 'm'
suffix = '\x1b[0m'
return prefix + s + suffix
else:
return s
# Foreground shortcuts
black = partial(color, fg='black')
red = partial(color, fg='red')
green = partial(color, fg='green')
yellow = partial(color, fg='yellow')
blue = partial(color, fg='blue')
magenta = partial(color, fg='magenta')
cyan = partial(color, fg='cyan')
white = partial(color, fg='white')
# Style shortcuts
bold = partial(color, style='bold')
faint = partial(color, style='faint')
italic = partial(color, style='italic')
underline = partial(color, style='underline')
blink = partial(color, style='blink')
blink2 = partial(color, style='blink2')
negative = partial(color, style='negative')
concealed = partial(color, style='concealed')
crossed = partial(color, style='crossed')

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
# Copyright (c) 2012 Georgios Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -16,32 +16,31 @@
from __future__ import unicode_literals
from . import Infinite, Progress
from .helpers import WriteMixin
class Counter(WriteMixin, Infinite):
message = ''
hide_cursor = True
class Counter(Infinite):
def update(self):
self.write(str(self.index))
message = self.message % self
line = ''.join([message, str(self.index)])
self.writeln(line)
class Countdown(WriteMixin, Progress):
hide_cursor = True
class Countdown(Progress):
def update(self):
self.write(str(self.remaining))
message = self.message % self
line = ''.join([message, str(self.remaining)])
self.writeln(line)
class Stack(WriteMixin, Progress):
class Stack(Progress):
phases = (' ', '', '', '', '', '', '', '', '')
hide_cursor = True
def update(self):
nphases = len(self.phases)
i = min(nphases - 1, int(self.progress * nphases))
self.write(self.phases[i])
message = self.message % self
line = ''.join([message, self.phases[i]])
self.writeln(line)
class Pie(Stack):

View File

@@ -1,91 +0,0 @@
# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import print_function
HIDE_CURSOR = '\x1b[?25l'
SHOW_CURSOR = '\x1b[?25h'
class WriteMixin(object):
hide_cursor = False
def __init__(self, message=None, **kwargs):
super(WriteMixin, self).__init__(**kwargs)
self._width = 0
if message:
self.message = message
if self.file.isatty():
if self.hide_cursor:
print(HIDE_CURSOR, end='', file=self.file)
print(self.message, end='', file=self.file)
self.file.flush()
def write(self, s):
if self.file.isatty():
b = '\b' * self._width
c = s.ljust(self._width)
print(b + c, end='', file=self.file)
self._width = max(self._width, len(s))
self.file.flush()
def finish(self):
if self.file.isatty() and self.hide_cursor:
print(SHOW_CURSOR, end='', file=self.file)
class WritelnMixin(object):
hide_cursor = False
def __init__(self, message=None, **kwargs):
super(WritelnMixin, self).__init__(**kwargs)
if message:
self.message = message
if self.file.isatty() and self.hide_cursor:
print(HIDE_CURSOR, end='', file=self.file)
def clearln(self):
if self.file.isatty():
print('\r\x1b[K', end='', file=self.file)
def writeln(self, line):
if self.file.isatty():
self.clearln()
print(line, end='', file=self.file)
self.file.flush()
def finish(self):
if self.file.isatty():
print(file=self.file)
if self.hide_cursor:
print(SHOW_CURSOR, end='', file=self.file)
from signal import signal, SIGINT
from sys import exit
class SigIntMixin(object):
"""Registers a signal handler that calls finish on SIGINT"""
def __init__(self, *args, **kwargs):
super(SigIntMixin, self).__init__(*args, **kwargs)
signal(SIGINT, self._sigint_handler)
def _sigint_handler(self, signum, frame):
self.finish()
exit(0)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com>
# Copyright (c) 2012 Georgios Verigakis <verigak@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -16,17 +16,17 @@
from __future__ import unicode_literals
from . import Infinite
from .helpers import WriteMixin
class Spinner(WriteMixin, Infinite):
message = ''
class Spinner(Infinite):
phases = ('-', '\\', '|', '/')
hide_cursor = True
def update(self):
i = self.index % len(self.phases)
self.write(self.phases[i])
message = self.message % self
line = ''.join([message, self.phases[i]])
self.writeln(line)
class PieSpinner(Spinner):
@@ -40,5 +40,6 @@ class MoonSpinner(Spinner):
class LineSpinner(Spinner):
phases = ['', '', '', '', '', '']
class PixelSpinner(Spinner):
phases = ['','', '', '', '', '', '', '']
phases = ['', '', '', '', '', '', '', '']

39
pyproject.toml Normal file
View File

@@ -0,0 +1,39 @@
[build-system]
requires = ["setuptools >= 77.0.3"]
build-backend = "setuptools.build_meta"
[project]
name = "progress"
dynamic = ["version"]
description = "Easy to use progress bars"
readme = "README.rst"
authors = [{ name = "Georgios Verigakis", email = "verigak@gmail.com" }]
maintainers = [{ name = "Georgios Verigakis", email = "verigak@gmail.com" }]
license = "ISC"
license-files = ["LICENSE"]
requires-python = ">=3.6"
keywords = ["progress", "bar"]
classifiers = [
"Environment :: Console",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
[project.urls]
Homepage = "https://github.com/verigak/progress/"
Repository = "https://github.com/verigak/progress.git"
Issues = "https://github.com/verigak/progress/issues"
[tool.setuptools]
packages = ["progress"]
[tool.setuptools.dynamic]
version = {attr = "progress.__version__"}

View File

@@ -1,29 +0,0 @@
#!/usr/bin/env python
from setuptools import setup
import progress
setup(
name='progress',
version=progress.__version__,
description='Easy to use progress bars',
long_description=open('README.rst').read(),
author='Giorgos Verigakis',
author_email='verigak@gmail.com',
url='http://github.com/verigak/progress/',
license='ISC',
packages=['progress'],
classifiers=[
'Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: ISC License (ISCL)',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3'
'Programming Language :: Python :: 3.4'
'Programming Language :: Python :: 3.5'
'Programming Language :: Python :: 3.6'
]
)

View File

@@ -11,6 +11,7 @@ from progress.bar import (Bar, ChargingBar, FillingSquaresBar,
from progress.spinner import (Spinner, PieSpinner, MoonSpinner, LineSpinner,
PixelSpinner)
from progress.counter import Counter, Countdown, Stack, Pie
from progress.colors import bold
def sleep():
@@ -20,26 +21,29 @@ def sleep():
for bar_cls in (Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar):
suffix = '%(index)d/%(max)d [%(elapsed)d / %(eta)d / %(eta_td)s]'
suffix = '%(index)d/%(max)d [%(elapsed)d / %(eta)d / %(eta_td)s] (%(iter_value)s)'
bar = bar_cls(bar_cls.__name__, suffix=suffix)
for i in bar.iter(range(200)):
for i in bar.iter(range(200, 400)):
sleep()
for bar_cls in (IncrementalBar, PixelBar, ShadyBar):
suffix = '%(percent)d%% [%(elapsed_td)s / %(eta)d / %(eta_td)s]'
bar = bar_cls(bar_cls.__name__, suffix=suffix)
for i in bar.iter(range(200)):
sleep()
with bar_cls(bar_cls.__name__, suffix=suffix, max=200) as bar:
for i in range(200):
bar.next()
sleep()
bar = IncrementalBar(bold('Colored'), color='green')
for i in bar.iter(range(200)):
sleep()
for spin in (Spinner, PieSpinner, MoonSpinner, LineSpinner, PixelSpinner):
for i in spin(spin.__name__ + ' ').iter(range(100)):
for i in spin(spin.__name__ + ' %(index)d ').iter(range(100)):
sleep()
print()
for singleton in (Counter, Countdown, Stack, Pie):
for i in singleton(singleton.__name__ + ' ').iter(range(100)):
sleep()
print()
bar = IncrementalBar('Random', suffix='%(index)d')
for i in range(100):