A "utility belt" of commonly needed utility and helper functions
Project description
|Travis| |Pypi| |Codecov|
Purpose
-------
UBelt is a "utility belt" of commonly needed utility and helper
functions. It is a migration of the most useful parts of ``utool``
(https://github.com/Erotemic/utool) into a minimal and standalone
module.
The ``utool`` library contains a number of useful utility functions,
however a number of these are too specific or not well documented. The
goal of this migration is to slowly port over the most re-usable parts
of ``utool`` into a stable package.
In addition to utility functions ``utool`` also contains a custom
doctest harness and code introspection and auto-generation features.
This port will contain a rewrite of the doctest harness. Some of the
code introspection features will be ported, but most auto-generation
abilities will be ported into a new module that depends on ``ubelt``.
Installation:
-------------
>From github:
^^^^^^^^^^^^
::
pip install git+https://github.com/Erotemic/ubelt.git
>From pypi:
^^^^^^^^^^
::
pip install ubelt
Available Functions:
--------------------
This list of functions and classes is currently available. See the
corresponding doc-strings for more details.
::
import ubelt as ub
ub.dict_hist
ub.dict_subset
ub.dict_take
ub.find_duplicates
ub.group_items
ub.map_keys
ub.map_vals
ub.readfrom
ub.writeto
ub.ensuredir
ub.ensure_app_resource_dir
ub.chunks
ub.compress
ub.take
ub.flatten
ub.memoize
ub.NiceRepr
ub.NoParam
ub.CaptureStdout
ub.Timer
ub.Timerit
ub.ProgIter
ub.Cacher
A minimal version of the doctest harness has been completed. This can be
accessed using ``ub.doctest_package``.
Examples
--------
Here are some examples of some features inside ``ubelt``
Caching
~~~~~~~
Cache intermediate results in a script with minimal boilerplate.
.. code:: python
>>> import ubelt as ub
>>> cfgstr = 'repr-of-params-that-uniquely-determine-the-process'
>>> cacher = ub.Cacher('test_process', cfgstr)
>>> data = cacher.tryload()
>>> if data is None:
>>> myvar1 = 'result of expensive process'
>>> myvar2 = 'another result'
>>> data = myvar1, myvar2
>>> cacher.save(data)
>>> myvar1, myvar2 = data
Timing
~~~~~~
Quickly time a single line.
.. code:: python
>>> import ubelt as ub
>>> timer = ub.Timer('Timer demo!', verbose=1)
>>> with timer:
>>> prime = ub.find_nth_prime(40)
tic('Timer demo!')
...toc('Timer demo!')=0.0008s
Robust Timing
~~~~~~~~~~~~~
Easily do robust timings on existing blocks of code by simply indenting
them. There is no need to refactor into a string representation or
convert to a single line. With ``ub.Timerit`` there is no need to resort
to the ``timeit`` module!
The quick and dirty way just requires one indent.
.. code:: python
>>> import ubelt as ub
>>> for _ in ub.Timerit(num=200, verbose=2):
>>> ub.find_nth_prime(100)
Timing for 200 loops
Timing complete, 200 loops
time per loop : 0.003288508653640747 seconds
Use the loop variable as a context manager for more accurate timings or
to incorporate an setup phase that is not timed. You can also access
properties of the ``ub.Timerit`` class to programmatically use results.
.. code:: python
>>> import ubelt as ub
>>> t1 = ub.Timerit(num=200, verbose=2)
>>> for timer in t1:
>>> setup_vars = 100
>>> with timer:
>>> ub.find_nth_prime(setup_vars)
>>> print('t1.total_time = %r' % (t1.total_time,))
Timing for 200 loops
Timing complete, 200 loops
time per loop : 0.003165217638015747 seconds
t1.total_time = 0.6330435276031494
Grouping
~~~~~~~~
Group items in a sequence into a dictionary by a second id list
.. code:: python
>>> import ubelt as ub
>>> item_list = ['ham', 'jam', 'spam', 'eggs', 'cheese', 'bannana']
>>> groupid_list = ['protein', 'fruit', 'protein', 'protein', 'dairy', 'fruit']
>>> result = ub.group_items(item_list, groupid_list)
>>> print(result)
{'dairy': ['cheese'], 'fruit': ['jam', 'bannana'], 'protein': ['ham', 'spam', 'eggs']}
Dictionary Histogram
~~~~~~~~~~~~~~~~~~~~
Find the frequency of items in a sequence
.. code:: python
>>> import ubelt as ub
>>> item_list = [1, 2, 39, 900, 1232, 900, 1232, 2, 2, 2, 900]
>>> hist = ub.dict_hist(item_list)
>>> print(hist)
{1232: 2, 1: 1, 2: 4, 900: 3, 39: 1}
Dictionary Manipulation
~~~~~~~~~~~~~~~~~~~~~~~
Take a subset of a dictionary.
.. code:: python
>>> import ubelt as ub
>>> dict_ = {'K': 3, 'dcvs_clip_max': 0.2, 'p': 0.1}
>>> subdict_ = ub.dict_subset(dict_, ['K', 'dcvs_clip_max'])
>>> print(subdict_)
{'K': 3, 'dcvs_clip_max': 0.2}
Take only the values, optionally specify a default value.
.. code:: python
>>> import ubelt as ub
>>> dict_ = {1: 'a', 2: 'b', 3: 'c'}
>>> print(list(ub.dict_take(dict_, [1, 2, 3, 4, 5], default=None)))
['a', 'b', 'c', None, None]
Apply a function to each value in the dictionary (see also
``ub.map_keys``).
.. code:: python
>>> import ubelt as ub
>>> dict_ = {'a': [1, 2, 3], 'b': []}
>>> newdict = ub.map_vals(len, dict_)
>>> print(newdict)
{'a': 3, 'b': 0}
Loop Progress
~~~~~~~~~~~~~
See also ```tqdm`` <https://pypi-hypernode.com/pypi/tqdm>`__ for an
alternative implementation.
.. code:: python
>>> import ubelt as ub
>>> def is_prime(n):
... return n >= 2 and not any(n % i == 0 for i in range(2, n))
>>> for n in ub.ProgIter(range(1000), verbose=2):
>>> # do some work
>>> is_prime(n)
0/1000... rate=0.00 Hz, eta=?, total=0:00:00, wall=14:05 EST
1/1000... rate=82241.25 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
257/1000... rate=177204.69 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
642/1000... rate=94099.22 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
1000/1000... rate=71886.74 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
.. |Travis| image:: https://img.shields.io/travis/Erotemic/ubelt.svg
:target: https://travis-ci.org/Erotemic/ubelt
.. |Pypi| image:: https://img.shields.io/pypi/v/ubelt.svg
:target: https://pypi-hypernode.com/pypi/ubelt
.. |Codecov| image:: https://codecov.io/github/Erotemic/ubelt/badge.svg?branch=master&service=github
:target: https://codecov.io/github/Erotemic/ubelt?branch=master
Purpose
-------
UBelt is a "utility belt" of commonly needed utility and helper
functions. It is a migration of the most useful parts of ``utool``
(https://github.com/Erotemic/utool) into a minimal and standalone
module.
The ``utool`` library contains a number of useful utility functions,
however a number of these are too specific or not well documented. The
goal of this migration is to slowly port over the most re-usable parts
of ``utool`` into a stable package.
In addition to utility functions ``utool`` also contains a custom
doctest harness and code introspection and auto-generation features.
This port will contain a rewrite of the doctest harness. Some of the
code introspection features will be ported, but most auto-generation
abilities will be ported into a new module that depends on ``ubelt``.
Installation:
-------------
>From github:
^^^^^^^^^^^^
::
pip install git+https://github.com/Erotemic/ubelt.git
>From pypi:
^^^^^^^^^^
::
pip install ubelt
Available Functions:
--------------------
This list of functions and classes is currently available. See the
corresponding doc-strings for more details.
::
import ubelt as ub
ub.dict_hist
ub.dict_subset
ub.dict_take
ub.find_duplicates
ub.group_items
ub.map_keys
ub.map_vals
ub.readfrom
ub.writeto
ub.ensuredir
ub.ensure_app_resource_dir
ub.chunks
ub.compress
ub.take
ub.flatten
ub.memoize
ub.NiceRepr
ub.NoParam
ub.CaptureStdout
ub.Timer
ub.Timerit
ub.ProgIter
ub.Cacher
A minimal version of the doctest harness has been completed. This can be
accessed using ``ub.doctest_package``.
Examples
--------
Here are some examples of some features inside ``ubelt``
Caching
~~~~~~~
Cache intermediate results in a script with minimal boilerplate.
.. code:: python
>>> import ubelt as ub
>>> cfgstr = 'repr-of-params-that-uniquely-determine-the-process'
>>> cacher = ub.Cacher('test_process', cfgstr)
>>> data = cacher.tryload()
>>> if data is None:
>>> myvar1 = 'result of expensive process'
>>> myvar2 = 'another result'
>>> data = myvar1, myvar2
>>> cacher.save(data)
>>> myvar1, myvar2 = data
Timing
~~~~~~
Quickly time a single line.
.. code:: python
>>> import ubelt as ub
>>> timer = ub.Timer('Timer demo!', verbose=1)
>>> with timer:
>>> prime = ub.find_nth_prime(40)
tic('Timer demo!')
...toc('Timer demo!')=0.0008s
Robust Timing
~~~~~~~~~~~~~
Easily do robust timings on existing blocks of code by simply indenting
them. There is no need to refactor into a string representation or
convert to a single line. With ``ub.Timerit`` there is no need to resort
to the ``timeit`` module!
The quick and dirty way just requires one indent.
.. code:: python
>>> import ubelt as ub
>>> for _ in ub.Timerit(num=200, verbose=2):
>>> ub.find_nth_prime(100)
Timing for 200 loops
Timing complete, 200 loops
time per loop : 0.003288508653640747 seconds
Use the loop variable as a context manager for more accurate timings or
to incorporate an setup phase that is not timed. You can also access
properties of the ``ub.Timerit`` class to programmatically use results.
.. code:: python
>>> import ubelt as ub
>>> t1 = ub.Timerit(num=200, verbose=2)
>>> for timer in t1:
>>> setup_vars = 100
>>> with timer:
>>> ub.find_nth_prime(setup_vars)
>>> print('t1.total_time = %r' % (t1.total_time,))
Timing for 200 loops
Timing complete, 200 loops
time per loop : 0.003165217638015747 seconds
t1.total_time = 0.6330435276031494
Grouping
~~~~~~~~
Group items in a sequence into a dictionary by a second id list
.. code:: python
>>> import ubelt as ub
>>> item_list = ['ham', 'jam', 'spam', 'eggs', 'cheese', 'bannana']
>>> groupid_list = ['protein', 'fruit', 'protein', 'protein', 'dairy', 'fruit']
>>> result = ub.group_items(item_list, groupid_list)
>>> print(result)
{'dairy': ['cheese'], 'fruit': ['jam', 'bannana'], 'protein': ['ham', 'spam', 'eggs']}
Dictionary Histogram
~~~~~~~~~~~~~~~~~~~~
Find the frequency of items in a sequence
.. code:: python
>>> import ubelt as ub
>>> item_list = [1, 2, 39, 900, 1232, 900, 1232, 2, 2, 2, 900]
>>> hist = ub.dict_hist(item_list)
>>> print(hist)
{1232: 2, 1: 1, 2: 4, 900: 3, 39: 1}
Dictionary Manipulation
~~~~~~~~~~~~~~~~~~~~~~~
Take a subset of a dictionary.
.. code:: python
>>> import ubelt as ub
>>> dict_ = {'K': 3, 'dcvs_clip_max': 0.2, 'p': 0.1}
>>> subdict_ = ub.dict_subset(dict_, ['K', 'dcvs_clip_max'])
>>> print(subdict_)
{'K': 3, 'dcvs_clip_max': 0.2}
Take only the values, optionally specify a default value.
.. code:: python
>>> import ubelt as ub
>>> dict_ = {1: 'a', 2: 'b', 3: 'c'}
>>> print(list(ub.dict_take(dict_, [1, 2, 3, 4, 5], default=None)))
['a', 'b', 'c', None, None]
Apply a function to each value in the dictionary (see also
``ub.map_keys``).
.. code:: python
>>> import ubelt as ub
>>> dict_ = {'a': [1, 2, 3], 'b': []}
>>> newdict = ub.map_vals(len, dict_)
>>> print(newdict)
{'a': 3, 'b': 0}
Loop Progress
~~~~~~~~~~~~~
See also ```tqdm`` <https://pypi-hypernode.com/pypi/tqdm>`__ for an
alternative implementation.
.. code:: python
>>> import ubelt as ub
>>> def is_prime(n):
... return n >= 2 and not any(n % i == 0 for i in range(2, n))
>>> for n in ub.ProgIter(range(1000), verbose=2):
>>> # do some work
>>> is_prime(n)
0/1000... rate=0.00 Hz, eta=?, total=0:00:00, wall=14:05 EST
1/1000... rate=82241.25 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
257/1000... rate=177204.69 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
642/1000... rate=94099.22 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
1000/1000... rate=71886.74 Hz, eta=0:00:00, total=0:00:00, wall=14:05 EST
.. |Travis| image:: https://img.shields.io/travis/Erotemic/ubelt.svg
:target: https://travis-ci.org/Erotemic/ubelt
.. |Pypi| image:: https://img.shields.io/pypi/v/ubelt.svg
:target: https://pypi-hypernode.com/pypi/ubelt
.. |Codecov| image:: https://codecov.io/github/Erotemic/ubelt/badge.svg?branch=master&service=github
:target: https://codecov.io/github/Erotemic/ubelt?branch=master
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
No source distribution files available for this release.See tutorial on generating distribution archives.
Built Distribution
File details
Details for the file ubelt-0.0.26-py2.py3-none-any.whl
.
File metadata
- Download URL: ubelt-0.0.26-py2.py3-none-any.whl
- Upload date:
- Size: 48.8 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | fd7b352bdff055fa3c2cd9dd33b4ff49e118c091afce42e97fdf26cb90f1740b |
|
MD5 | f3d7dbb1798dd0ed7f07cf1c65b2d099 |
|
BLAKE2b-256 | 627e2ab2c5113b8ba1d711a90c0c5a543698875485d722261d2c22fab7399784 |