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 Sequence
from .math_round_div import RoundingMode, round_div ← from math.round-div ^1.0.0 · built alongside by fune
MAX_SAFE = 9007199254740991
def _whole(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and abs(value) <= MAX_SAFE
def weighted_average(values: Sequence[int], weights: Sequence[int], decimals: int, mode: RoundingMode) -> float:
"""Weighted average of integers, rounded once at the end.
The numerator and denominator are exact integers, so the rounding mode the
caller names is the only rounding that ever happens.
"""
for seq in (values, weights):
if isinstance(seq, (str, bytes)) or not isinstance(seq, (list, tuple)):
raise TypeError("values and weights must be lists of integers")
if len(values) != len(weights):
raise ValueError("values and weights must be the same length, received %d and %d" % (len(values), len(weights)))
if len(values) == 0:
raise ValueError("values must not be empty")
if isinstance(decimals, bool) or not isinstance(decimals, int) or decimals < 0 or decimals > 9:
raise ValueError("decimals must be a whole number from 0 to 9, received %r" % (decimals,))
numerator = 0
denominator = 0
for v, w in zip(values, weights):
if not _whole(v):
raise TypeError("values must be integers, received %r" % (v,))
if not _whole(w):
raise TypeError("weights must be integers, received %r" % (w,))
if w < 0:
raise ValueError("weights must not be negative, received %d" % w)
numerator += v * w
denominator += w
if denominator == 0:
raise ValueError("weights must not all be zero")
scaled = numerator * 10**decimals
# Python ints never overflow, but TypeScript numbers and Rust i64 do; refuse
# the same inputs everywhere so the languages cannot disagree.
if abs(scaled) > MAX_SAFE or denominator > MAX_SAFE:
raise ValueError("weighted sum is too large to average exactly; lower decimals or rescale the values")
return round_div(scaled, denominator, mode) / float(10**decimals) + 0.0