New tqdm module structure and add a Makefile

This commit is contained in:
Hadrien Mary 2015-06-06 15:35:28 +02:00
parent ecc79f9629
commit ccb05c2e04
12 changed files with 169 additions and 85 deletions

View File

@ -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

View File

@ -1,3 +0,0 @@
# file GENERATED by distutils, do NOT edit
setup.py
tqdm.py

23
Makefile Normal file
View File

@ -0,0 +1,23 @@
.PHONY: test flake8 coverage clean
help:
@echo "Please use make <target> where <target> 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/

View File

@ -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 ta<i>qa</i>dum, تقدّم) 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 <target> where <target> 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)

View File

@ -1,2 +0,0 @@
[pytest]
python_files = test*.py

View File

@ -1,2 +0,0 @@
[bdist_wheel]
universal = 1

View File

@ -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',

13
tox.ini
View File

@ -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

BIN
tqdm.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

6
tqdm/__init__.py Normal file
View File

@ -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']

View File

@ -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)

View File

@ -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()