Skip to content

Commit

Permalink
Merge branch 'release/2.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed Mar 3, 2020
2 parents e461155 + 599f54c commit 426276c
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 42 deletions.
8 changes: 8 additions & 0 deletions .coveragerc
Expand Up @@ -10,6 +10,14 @@ omit =
source =
python_utils
[report]
fail_under = 100
exclude_lines =
pragma: no cover
@abc.abstractmethod
def __repr__
if self.debug:
if settings.DEBUG
raise AssertionError
raise NotImplementedError
if 0:
if __name__ == .__main__.:
17 changes: 12 additions & 5 deletions .travis.yml
@@ -1,3 +1,4 @@
dist: xenial
sudo: false
language: python

Expand All @@ -8,18 +9,22 @@ env:

matrix:
include:
- python: '2.7'
- python: '3.6'
env: TOXENV=docs
- python: '2.7'
- python: '3.6'
env: TOXENV=flake8
- python: '2.7'
env: TOXENV=py27
- python: '3.4'
env: TOXENV=py34
- python: '3.5'
env: TOXENV=py35
- python: '3.6'
env: TOXENV=py36
- python: '3.7'
env: TOXENV=py37
- python: '3.8'
env: TOXENV=py38
- python: '3.9-dev'
env: TOXENV=py39
- python: 'pypy'
env: TOXENV=pypy

Expand All @@ -32,13 +37,15 @@ install:
- mkdir -p $PIP_WHEEL_DIR
- pip wheel -r tests/requirements.txt
- pip install -e .
- pip install tox coveralls
- pip install tox

script:
- tox

after_success:
- pip install codecov coveralls
- coveralls
- codecov

notifications:
email:
Expand Down
12 changes: 0 additions & 12 deletions docs/conf.py
Expand Up @@ -65,18 +65,6 @@
# The full version, including alpha/beta/rc tags.
release = __about__.__version__

# Monkey patch to disable nonlocal image warning
import sphinx
if hasattr(sphinx, 'environment'):
original_warn_mode = sphinx.environment.BuildEnvironment.warn_node

def allow_nonlocal_image_warn_node(self, msg, *args, **kwargs):
if not msg.startswith('nonlocal image URI found:'):
original_warn_mode(self, msg, *args, **kwargs)

sphinx.environment.BuildEnvironment.warn_node = \
allow_nonlocal_image_warn_node

suppress_warnings = [
'image.nonlocal_uri',
]
Expand Down
2 changes: 1 addition & 1 deletion python_utils/__about__.py
@@ -1,5 +1,5 @@
__package_name__ = 'python-utils'
__version__ = '2.3.0'
__version__ = '2.4.0'
__author__ = 'Rick van Hattem'
__author_email__ = 'Wolph@wol.ph'
__description__ = (
Expand Down
100 changes: 82 additions & 18 deletions python_utils/converters.py
Expand Up @@ -37,23 +37,23 @@ def to_int(input_, default=0, exception=(ValueError, TypeError), regexp=None):
123
>>> to_int('abc123abc456', regexp=True)
123
>>> to_int('abc123', regexp=re.compile('(\d+)'))
>>> to_int('abc123', regexp=re.compile(r'(\d+)'))
123
>>> to_int('123abc', regexp=re.compile('(\d+)'))
>>> to_int('123abc', regexp=re.compile(r'(\d+)'))
123
>>> to_int('abc123abc', regexp=re.compile('(\d+)'))
>>> to_int('abc123abc', regexp=re.compile(r'(\d+)'))
123
>>> to_int('abc123abc456', regexp=re.compile('(\d+)'))
>>> to_int('abc123abc456', regexp=re.compile(r'(\d+)'))
123
>>> to_int('abc123', regexp='(\d+)')
>>> to_int('abc123', regexp=r'(\d+)')
123
>>> to_int('123abc', regexp='(\d+)')
>>> to_int('123abc', regexp=r'(\d+)')
123
>>> to_int('abc', regexp='(\d+)')
>>> to_int('abc', regexp=r'(\d+)')
0
>>> to_int('abc123abc', regexp='(\d+)')
>>> to_int('abc123abc', regexp=r'(\d+)')
123
>>> to_int('abc123abc456', regexp='(\d+)')
>>> to_int('abc123abc456', regexp=r'(\d+)')
123
>>> to_int('1234', default=1)
1234
Expand Down Expand Up @@ -110,23 +110,23 @@ def to_float(input_, default=0, exception=(ValueError, TypeError),
'123.00'
>>> '%.2f' % to_float('abc0.456', regexp=True)
'0.46'
>>> '%.2f' % to_float('abc123.456', regexp=re.compile('(\d+\.\d+)'))
>>> '%.2f' % to_float('abc123.456', regexp=re.compile(r'(\d+\.\d+)'))
'123.46'
>>> '%.2f' % to_float('123.456abc', regexp=re.compile('(\d+\.\d+)'))
>>> '%.2f' % to_float('123.456abc', regexp=re.compile(r'(\d+\.\d+)'))
'123.46'
>>> '%.2f' % to_float('abc123.46abc', regexp=re.compile('(\d+\.\d+)'))
>>> '%.2f' % to_float('abc123.46abc', regexp=re.compile(r'(\d+\.\d+)'))
'123.46'
>>> '%.2f' % to_float('abc123abc456', regexp=re.compile('(\d+(\.\d+|))'))
>>> '%.2f' % to_float('abc123abc456', regexp=re.compile(r'(\d+(\.\d+|))'))
'123.00'
>>> '%.2f' % to_float('abc', regexp='(\d+)')
>>> '%.2f' % to_float('abc', regexp=r'(\d+)')
'0.00'
>>> '%.2f' % to_float('abc123', regexp='(\d+)')
>>> '%.2f' % to_float('abc123', regexp=r'(\d+)')
'123.00'
>>> '%.2f' % to_float('123abc', regexp='(\d+)')
>>> '%.2f' % to_float('123abc', regexp=r'(\d+)')
'123.00'
>>> '%.2f' % to_float('abc123abc', regexp='(\d+)')
>>> '%.2f' % to_float('abc123abc', regexp=r'(\d+)')
'123.00'
>>> '%.2f' % to_float('abc123abc456', regexp='(\d+)')
>>> '%.2f' % to_float('abc123abc456', regexp=r'(\d+)')
'123.00'
>>> '%.2f' % to_float('1234', default=1)
'1234.00'
Expand Down Expand Up @@ -234,3 +234,67 @@ def scale_1024(x, n_prefixes):
scaled = float(x) / (2 ** (10 * power))
return scaled, power


def remap(value, old_min, old_max, new_min, new_max):
"""
remap a value from one range into another.
>>> remap(500, 0, 1000, 0, 100)
50
>>> remap(250.0, 0.0, 1000.0, 0.0, 100.0)
25.0
>>> remap(-75, -100, 0, -1000, 0)
-750
>>> remap(33, 0, 100, -500, 500)
-170
This is a great use case example. Take an AVR that has dB values the
minimum being -80dB and the maximum being 10dB and you want to convert
volume percent to the equilivint in that dB range
>>> remap(46.0, 0.0, 100.0, -80.0, 10.0)
-38.6
Some edge cases to test
>>> remap(0, 0, 0, 0, 0)
0
>>> remap(0, 0, 0, 1, 0)
1
:param value: value to be converted
:type value: int, float
:param old_min: minimum of the range for the value that has been passed
:type old_min: int, float
:param old_max: maximum of the range for the value that has been passed
:type old_max: int, float
:param new_min: the minimum of the new range
:type new_min: int, float
:param new_max: the maximum of the new range
:type new_max: int, float
:return: value that has been re ranged, if the value is an int floor
division is used so the returned value will always be rounded down
to the closest whole number.
:rtype: int, float
"""
old_range = old_max - old_min
new_range = new_max - new_min
if new_range == 0:
return 0

if old_range == 0:
new_value = new_min
else:
new_value = (value - old_min) * new_range
if isinstance(value, int):
new_value = new_value // old_range
else:
new_value = new_value / old_range

new_value += new_min

return new_value
4 changes: 2 additions & 2 deletions python_utils/time.py
Expand Up @@ -71,9 +71,9 @@ def format_time(timestamp, precision=datetime.timedelta(seconds=1)):
seconds = seconds - (seconds % precision_seconds)

return str(datetime.timedelta(seconds=seconds))
elif isinstance(timestamp, datetime.datetime):
elif isinstance(timestamp, datetime.datetime): # pragma: no cover
# Python 2 doesn't have the timestamp method
if hasattr(timestamp, 'timestamp'): # pragma: no cover
if hasattr(timestamp, 'timestamp'):
seconds = timestamp.timestamp()
else:
seconds = timedelta_to_seconds(timestamp - epoch)
Expand Down
10 changes: 6 additions & 4 deletions tox.ini
@@ -1,25 +1,27 @@
[tox]
envlist = py27, py33, py34, py35, py36, pypy, flake8, docs
envlist = py27, py35, py36, py37, py38, py39, pypy, flake8, docs
skip_missing_interpreters = True

[testenv]
basepython =
py27: python2.7
py34: python3.4
py35: python3.5
py36: python3.6
py37: python3.7
py38: python3.8
py39: python3.9
pypy: pypy
deps = -r{toxinidir}/tests/requirements.txt

commands = python setup.py test {posargs}

[testenv:flake8]
basepython = python2.7
basepython = python3.7
deps = flake8
commands = flake8 --ignore=W391 python_utils {posargs}

[testenv:docs]
basepython = python2.7
basepython = python3.7
whitelist_externals =
rm
cd
Expand Down

0 comments on commit 426276c

Please sign in to comment.