fluttersmith/py-snippetsGitHub ↗

Map a number from one range to another

Linearly map a value from one range onto another, like Arduino's map().

Numbers#conversionO(1) time✓ 3 examples pass on 3.11–3.14

Turn a 0–1023 sensor reading into 0–100 %, or a score into a colour position.

num_to_range.py✓ ruff · mypy --strict
def num_to_range(
    value: float, in_min: float, in_max: float, out_min: float, out_max: float
) -> float:
    """Map ``value`` from the range ``in_min..in_max`` onto ``out_min..out_max``."""
    if in_min == in_max:
        raise ValueError(f"input range is empty: {in_min} to {in_max}")
    fraction = (value - in_min) / (in_max - in_min)
    return out_min + fraction * (out_max - out_min)
  1. how far along the input range value is, from 0.0 to 1.0
examples✓ 3 doctests · 3.11–3.14
passed on Python 3.11 to 3.14: >>> num_to_range(5, 0, 10, 0, 100)50.0passed on Python 3.11 to 3.14: >>> num_to_range(25, 0, 100, 1, -1)0.5passed on Python 3.11 to 3.14: >>> num_to_range(1, 1, 1, 0, 10)Traceback (most recent call last):...ValueError: input range is empty: 1 to 1
Edit the function or the examples and run the doctests here, on Python 3.14. Python loads only when you click (about 7 MB, cached after the first time).

How it works

  • fraction is how far along the input range the value is.
  • Scaling that fraction to the output range gives the result. Reversed output ranges work too.
  • An empty input range raises instead of dividing by zero.

Complexity: O(1) time and space

Importfrom pysnippets.numbers.num_to_range import num_to_rangeNo dependencies: copy num_to_range.py into your project, or clone the repo.

Adapted from num-to-range in 30-seconds-of-python by the 30 seconds of code contributors, CC BY 4.0. Changed: Clearer names; rejects an empty input range; typed. Suggest an edit.