Functional Weave
Code in Python

math.percent-change@1.0.0

impl/python.py

1,014 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from typing import Optional

from .math_round_div import RoundingMode, round_div  ← from math.round-div ^1.0.0 · built alongside by fune

# (difference * 10000) must stay an exact integer in a JavaScript number, and
# the three languages must agree on what is too large.
MAX_DIFFERENCE = 900719925474


def percent_change(from_value: int, to_value: int, mode: RoundingMode) -> Optional[int]:
    """Percentage change from ``from_value`` to ``to_value``, in basis points.

    Divides by |from_value| so the sign always says which way the value moved,
    even when the starting value is negative.
    """
    for v in (from_value, to_value):
        if isinstance(v, bool) or not isinstance(v, int):
            raise TypeError("percent_change operates on integers only")
    if from_value == 0:
        return None
    difference = to_value - from_value
    if abs(difference) > MAX_DIFFERENCE:
        raise ValueError("the change from %d to %d is too large to express exactly" % (from_value, to_value))
    return round_div(difference * 10000, abs(from_value), mode)