From ccb05c2e041bbb2f9b3acccb2a80b48993d36f12 Mon Sep 17 00:00:00 2001 From: Hadrien Mary Date: Sat, 6 Jun 2015 15:35:28 +0200 Subject: [PATCH] New tqdm module structure and add a Makefile --- .travis.yml | 24 +++++---- MANIFEST | 3 -- Makefile | 23 ++++++++ README.md | 77 +++++++++++++++++++-------- pytest.ini | 2 - setup.cfg | 2 - setup.py | 4 +- tox.ini | 13 ----- tqdm.gif | Bin 0 -> 62278 bytes tqdm/__init__.py | 6 +++ tqdm.py => tqdm/_tqdm.py | 62 +++++++++++---------- tests.py => tqdm/tests/tests_tqdm.py | 38 ++++++++++++- 12 files changed, 169 insertions(+), 85 deletions(-) delete mode 100644 MANIFEST create mode 100644 Makefile delete mode 100644 pytest.ini delete mode 100644 setup.cfg delete mode 100644 tox.ini create mode 100644 tqdm.gif create mode 100644 tqdm/__init__.py rename tqdm.py => tqdm/_tqdm.py (72%) rename tests.py => tqdm/tests/tests_tqdm.py (67%) diff --git a/.travis.yml b/.travis.yml index b5097753..3694df63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,16 @@ language: python -python: 2.7 -env: -- TOXENV=py26 -- TOXENV=py27 -- TOXENV=py32 -- TOXENV=py33 -- TOXENV=py34 -- TOXENV=pypy -- TOXENV=pypy3 + +python: + - "2.7" + - "3.4" + install: -- pip install tox + - pip install nose flake8 coverage python-coveralls + - pip install . + script: -- tox + - make flake8 + - make coverage + +after_success: + - coveralls diff --git a/MANIFEST b/MANIFEST deleted file mode 100644 index 7cd0a5d2..00000000 --- a/MANIFEST +++ /dev/null @@ -1,3 +0,0 @@ -# file GENERATED by distutils, do NOT edit -setup.py -tqdm.py diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..a1cca4a2 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +.PHONY: test flake8 coverage clean + +help: + @echo "Please use make where is one of" + @echo " test : run tests" + @echo " flake8 : run flake8 to check PEP8" + @echo " coverage : run tests and check code coverage" + @echo " clean : clean current repository" + +test: + nosetests tqdm/ -v + +flake8: + flake8 --exclude "test_*" --max-line-length=100 --count --statistics --exit-zero tqdm/ + +coverage: + nosetests --with-coverage --cover-package=tqdm -v tqdm/ + +clean: + find . -name "*.so" -exec rm -rf {} \; + find . -name "*.pyc" -exec rm -rf {} \; + find . -depth -name "__pycache__" -type d -exec rm -rf '{}' \; + rm -rf build/ dist/ tqdm.egg-info/ diff --git a/README.md b/README.md index b749ccf6..c0055983 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,49 @@ -tqdm -==== +# tqdm -[![Build Status](https://img.shields.io/travis/kmike/tqdm.svg?branch=all-fixes)](https://travis-ci.org/kmike/tqdm) +[![Build Status](https://travis-ci.org/tqdm/tqdm.svg?branch=master)](https://travis-ci.org/tqdm/tqdm) +[![Coverage Status](https://coveralls.io/repos/tqdm/tqdm/badge.svg)](https://coveralls.io/r/tqdm/tqdm) -Instantly make your loops show a progress meter - just wrap any iterable with "tqdm(iterable)", and you're done! - -![ScreenShot](https://i.imgur.com/he9Aw5C.gif) +Instantly make your loops show a progress meter - just wrap any iterable with "tqdm(iterable)", and you're done ! tqdm (read taqadum, تقدّم) means "progress" in arabic. +![ScreenShot](tqdm.gif) + You can also use trange(N) as a shortcut for tqdm(xrange(N)) -Here's the doc: +## Installation + +```sh +pip install tqdm +# or +pip install -e git+https://github.com/tqdm/tqdm.git#egg=master +``` + +## Documentation ```python -def tqdm(iterable, desc='', total=None, leave=False, mininterval=0.5, miniters=1): - """ - Get an iterable object, and return an iterator which acts exactly like the +def tqdm(iterable, desc='', total=None, + leave=False, file=sys.stderr, + min_interval=0.5, miniters=1): + + """Get an iterable object, and return an iterator which acts exactly like the iterable, but prints a progress meter and updates it every time a value is requested. - 'desc' can contain a short string, describing the progress, that is added - in the beginning of the line. - 'total' can give the number of expected iterations. If not given, - len(iterable) is used if it is defined. - If leave is False, tqdm deletes its traces from screen after it has finished - iterating over all elements. - If less than mininterval seconds or miniters iterations have passed since - the last progress meter update, it is not updated again. + + Parameters + ---------- + desc: str + A short string, describing the progress, that is added in the beginning of the line. + total : int + The number of expected iterations. If not given, len(iterable) is used if it is defined. + file : `io.TextIOWrapper` or `io.StringIO` + A file-like object to output the progress message to. + leave : bool + If it is False, tqdm deletes its traces from screen after it has finished iterating over + all elements. + min_interval : float + If less than min_interval seconds or miniters iterations have passed since the last + progress meter update, it is not updated again. """ def trange(*args, **kwargs): @@ -34,8 +51,24 @@ def trange(*args, **kwargs): return tqdm(xrange(*args), **kwargs) ``` -Running tests -------------- +## Contributions -Please make sure tox (http://tox.testrun.org/) is installed and type -`tox` from the command line. +During development you may want to use these commands : + +```sh +$ make help +Please use make where is one of + test : run tests + flake8 : run flake8 to check PEP8 + coverage : run tests and check code coverage + clean : clean current repository +``` + +## License + +[MIT LICENSE](LICENSE). + + +## Authors + +- noamraph (original author) diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 87226211..00000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -python_files = test*.py diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2a9acf13..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py index 2b9a035f..a3f8f146 100644 --- a/setup.py +++ b/setup.py @@ -4,12 +4,12 @@ from setuptools import setup setup( name='tqdm', - version='1.0', + version='2.0', description='A Simple Python Progress Meter', license='MIT License', author='Noam Yorav-Raphael', author_email='noamraph@gmail.com', - url='https://github.com/noamraph/tqdm', + url='https://github.com/tqdm/tqdm', py_modules=['tqdm'], classifiers=[ 'Development Status :: 5 - Production/Stable', diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 00fd9477..00000000 --- a/tox.ini +++ /dev/null @@ -1,13 +0,0 @@ -# Tox (http://tox.testrun.org/) is a tool for running tests -# in multiple virtualenvs. This configuration file will run the -# test suite on all supported python versions. To use it, "pip install tox" -# and then run "tox" from this directory. - -[tox] -envlist = py26, py27, py32, py33, py34, pypy, pypy3 - -[testenv] -commands = py.test -deps = - six - pytest diff --git a/tqdm.gif b/tqdm.gif new file mode 100644 index 0000000000000000000000000000000000000000..a5c13275126f319479647897b456941deb823748 GIT binary patch literal 62278 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 GdG0?rpjl}E literal 0 HcmV?d00001 diff --git a/tqdm/__init__.py b/tqdm/__init__.py new file mode 100644 index 00000000..f8953cd4 --- /dev/null +++ b/tqdm/__init__.py @@ -0,0 +1,6 @@ +from ._tqdm import tqdm +from ._tqdm import trange +from ._tqdm import format_interval +from ._tqdm import format_meter + +__all__ = ['tqdm', 'trange', 'format_interval', 'format_meter'] diff --git a/tqdm.py b/tqdm/_tqdm.py similarity index 72% rename from tqdm.py rename to tqdm/_tqdm.py index 14fcbe5c..10fe4873 100644 --- a/tqdm.py +++ b/tqdm/_tqdm.py @@ -4,7 +4,7 @@ import sys import time -__all__ = ['tqdm', 'trange'] +__all__ = ['tqdm', 'trange', 'format_interval', 'format_meter'] def format_interval(t): @@ -22,24 +22,24 @@ def format_meter(n, total, elapsed): # elapsed - number of seconds passed since start if total and n > total: total = None - + elapsed_str = format_interval(elapsed) rate = '%5.2f' % (n / elapsed) if elapsed else '?' - + if total: frac = float(n) / total - + N_BARS = 10 bar_length = int(frac*N_BARS) bar = '#'*bar_length + '-'*(N_BARS-bar_length) - + percentage = '%3d%%' % (frac * 100) - + left_str = format_interval(elapsed / n * (total-n)) if n else '?' - + return '|%s| %d/%d %s [elapsed: %s left: %s, %s iters/sec]' % ( bar, n, total, percentage, elapsed_str, left_str, rate) - + else: return '%d [elapsed: %s, %s iters/sec]' % (n, elapsed_str, rate) @@ -48,40 +48,46 @@ class StatusPrinter(object): def __init__(self, file): self.file = file self.last_printed_len = 0 - + def print_status(self, s): self.file.write('\r'+s+' '*max(self.last_printed_len-len(s), 0)) self.file.flush() self.last_printed_len = len(s) -def tqdm(iterable, desc='', total=None, leave=False, file=sys.stderr, - mininterval=0.5, miniters=1): - """ - Get an iterable object, and return an iterator which acts exactly like the +def tqdm(iterable, desc='', total=None, + leave=False, file=sys.stderr, + min_interval=0.5, miniters=1): + """Get an iterable object, and return an iterator which acts exactly like the iterable, but prints a progress meter and updates it every time a value is requested. - 'desc' can contain a short string, describing the progress, that is added - in the beginning of the line. - 'total' can give the number of expected iterations. If not given, - len(iterable) is used if it is defined. - 'file' can be a file-like object to output the progress message to. - If leave is False, tqdm deletes its traces from screen after it has - finished iterating over all elements. - If less than mininterval seconds or miniters iterations have passed since - the last progress meter update, it is not updated again. + + Parameters + ---------- + desc: str + A short string, describing the progress, that is added in the beginning of the line. + total : int + The number of expected iterations. If not given, len(iterable) is used if it is defined. + file : `io.TextIOWrapper` or `io.StringIO` + A file-like object to output the progress message to. + leave : bool + If it is False, tqdm deletes its traces from screen after it has finished iterating over + all elements. + min_interval : float + If less than min_interval seconds or miniters iterations have passed since the last + progress meter update, it is not updated again. """ if total is None: try: total = len(iterable) except (TypeError, AttributeError): total = None - + prefix = desc+': ' if desc else '' - + sp = StatusPrinter(file) sp.print_status(prefix + format_meter(0, total, 0)) - + start_t = last_print_t = time.time() last_print_n = 0 n = 0 @@ -92,11 +98,11 @@ def tqdm(iterable, desc='', total=None, leave=False, file=sys.stderr, if n - last_print_n >= miniters: # We check the counter first, to reduce the overhead of time.time() cur_t = time.time() - if cur_t - last_print_t >= mininterval: + if cur_t - last_print_t >= min_interval: sp.print_status(prefix + format_meter(n, total, cur_t-start_t)) last_print_n = n last_print_t = cur_t - + if not leave: sp.print_status('') sys.stdout.write('\r') @@ -113,5 +119,5 @@ def trange(*args, **kwargs): f = xrange except NameError: f = range - + return tqdm(f(*args), **kwargs) diff --git a/tests.py b/tqdm/tests/tests_tqdm.py similarity index 67% rename from tests.py rename to tqdm/tests/tests_tqdm.py index c377bf14..25f7aaba 100644 --- a/tests.py +++ b/tqdm/tests/tests_tqdm.py @@ -1,8 +1,16 @@ from __future__ import unicode_literals import csv -from six import StringIO -from tqdm import format_interval, format_meter, tqdm + +try: + from StringIO import StringIO +except: + from io import StringIO + +from tqdm import format_interval +from tqdm import format_meter +from tqdm import tqdm +from tqdm import trange def test_format_interval(): @@ -18,6 +26,8 @@ def test_format_meter(): assert format_meter(231, 1000, 392) == \ "|##--------| 231/1000 23% [elapsed: " \ "06:32 left: 21:44, 0.59 iters/sec]" + assert format_meter(10000, 1000, 13) == \ + "10000 [elapsed: 00:13, 769.23 iters/sec]" def test_nothing_fails(): @@ -67,3 +77,27 @@ def test_leave_option(): our_file2.seek(0) assert '3/3 100%' not in our_file2.read() our_file2.close() + + +def test_trange(): + our_file = StringIO() + for i in trange(3, file=our_file, leave=True): + pass + our_file.seek(0) + assert '3/3 100%' in our_file.read() + our_file.close() + + our_file2 = StringIO() + for i in trange(3, file=our_file2, leave=False): + pass + our_file2.seek(0) + assert '3/3 100%' not in our_file2.read() + our_file2.close() + + +def test_min_interval(): + our_file = StringIO() + for i in tqdm(range(3), file=our_file, min_interval=1e-10): + pass + our_file.seek(0) + assert "|----------| 0/3 0% [elapsed: 00:00 left" in our_file.read()