1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
..
Copyright 2017 - 2022 Avram Lubkin, All Rights Reserved
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
:github_url: https://github.com/Rockhopper-Technologies/enlighten
Common Patterns
===============
Enable / Disable
----------------
A program may want to disable progress bars based on a configuration setting as well as if
output redirection occurs.
.. code-block:: python
import sys
import enlighten
# Example configuration object
config = {'stream': sys.stdout,
'useCounter': False}
enableCounter = config['useCounter'] and stream.isatty()
manager = enlighten.Manager(stream=config['stream'], enabled=enableCounter)
The :py:func:`~enlighten.get_manager` function slightly simplifies this
.. code-block:: python
import enlighten
# Example configuration object
config = {'stream': None, # Defaults to sys.__stdout__
'useCounter': False}
manager = enlighten.get_manager(stream=config['stream'], enabled=config['useCounter'])
Context Managers
----------------
Both :py:class:`~enlighten.Counter` and :py:class:`~enlighten.Manager`
can be used as context managers.
.. code-block:: python
import enlighten
SPLINES = 100
with enlighten.Manager() as manager:
with manager.counter(total=SPLINES, desc='Reticulating:', unit='splines') as retic:
for num in range(SPLINES + 1):
retic.update()
Automatic Updating
------------------
Both :py:class:`~enlighten.Counter` and :py:class:`~enlighten.SubCounter` instances can be
called as functions on one or more iterators. A generator is returned which yields each element of
the iterables and then updates the count by 1.
.. note::
When a :py:class:`~enlighten.Counter` instance is called as a function, type checking is lazy
and won't validate an iterable was passed until iteration begins.
.. code-block:: python
import time
import enlighten
flock1 = ['Harry', 'Sally', 'Randy', 'Mandy', 'Danny', 'Joe']
flock2 = ['Punchy', 'Kicky', 'Spotty', 'Touchy', 'Brenda']
total = len(flock1) + len(flock2)
manager = enlighten.Manager()
pbar = manager.counter(total=total, desc='Counting Sheep', unit='sheep')
for sheep in pbar(flock1, flock2):
time.sleep(0.2)
print('%s: Baaa' % sheep)
User-defined fields
-------------------
Both :py:class:`~enlighten.Counter` and :py:class:`~enlighten.StatusBar` accept
user defined fields as keyword arguments at initialization and during an update.
These fields are persistent and only need to be specified when they change.
In the following example, ``source`` is a user-defined field that is periodically updated.
.. code-block:: python
import enlighten
import random
import time
bar_format = u'{desc}{desc_pad}{source} {percentage:3.0f}%|{bar}| ' + \
u'{count:{len_total}d}/{total:d} ' + \
u'[{elapsed}<{eta}, {rate:.2f}{unit_pad}{unit}/s]'
manager = enlighten.get_manager(bar_format=bar_format)
bar = manager.counter(total=100, desc='Loading', unit='files', source='server.a')
for num in range(100):
time.sleep(0.1) # Simulate work
if not num % 5:
bar.update(source=random.choice(['server.a', 'server.b', 'server.c']))
else:
bar.update()
For more information, see the :ref:`Counter Format <counter_format>` and
:ref:`StatusBar Format <status_format>` sections.
Human-readable numeric prefixes
-------------------------------
Enlighten supports automatic `SI (metric)`_ and `IEC (binary)`_ prefixes using the Prefixed_
library.
All ``rate`` and ``interval`` formatting fields are of the type :py:class:`prefixed.Float`.
``total`` and all ``count`` fields default to :py:class:`int`.
If :py:attr:`~Counter.total` or or :py:attr:`~Counter.count` are set to a :py:class:`float`,
or a :py:class:`float` is provided to :py:meth:`~Counter.update`,
these fields will be :py:class:`prefixed.Float` instead.
.. code-block:: python
import time
import random
import enlighten
size = random.uniform(1.0, 10.0) * 2 ** 20 # 1-10 MiB (float)
chunk_size = 64 * 1024 # 64 KiB
bar_format = '{desc}{desc_pad}{percentage:3.0f}%|{bar}| ' \
'{count:!.2j}{unit} / {total:!.2j}{unit} ' \
'[{elapsed}<{eta}, {rate:!.2j}{unit}/s]'
manager = enlighten.get_manager()
pbar = manager.counter(total=size, desc='Downloading', unit='B', bar_format=bar_format)
bytes_left = size
while bytes_left:
time.sleep(random.uniform(0.05, 0.15))
next_chunk = min(chunk_size, bytes_left)
pbar.update(next_chunk)
bytes_left -= next_chunk
.. code-block:: python
import enlighten
counter_format = 'Trying to get to sleep: {count:.2h} sheep'
counter = enlighten.Counter(counter_format=counter_format)
counter.count = 0.0
for num in range(10000000):
counter.update()
For more information, see the :ref:`Counter Format <counter_format>`
and the `Prefixed`_ documentation.
.. _SI (metric): https://en.wikipedia.org/wiki/Metric_prefix
.. _IEC (binary): https://en.wikipedia.org/wiki/Binary_prefix
.. _Prefixed: https://prefixed.readthedocs.io/en/stable/index.html
|