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 List, Sequence
from .money_amount import Money, money ← from money.amount ^1.0.0 · built alongside by fune
def allocate(amount: Money, ratios: Sequence[int]) -> List[Money]:
"""Split ``amount`` across ``ratios`` so the parts add back up to the whole.
Splitting 10.00 three ways gives 3.34, 3.33, 3.33 - never 3.33 three times
with a penny quietly lost. The leftover goes to the largest remainders,
ties broken by position, so the split is stable and reproducible.
"""
if len(ratios) == 0:
raise ValueError("allocate needs at least one ratio")
if any(isinstance(r, bool) or not isinstance(r, int) for r in ratios):
raise TypeError("ratios must be integers")
total = sum(ratios)
if total == 0:
raise ValueError("ratios must not sum to zero")
bases = []
remainders = []
for ratio in ratios:
numerator = amount.minor * ratio
base = numerator // total
bases.append(base)
remainders.append(numerator - base * total)
leftover = amount.minor - sum(bases)
order = sorted(range(len(ratios)), key=lambda i: (-remainders[i], i))
for index in order:
if leftover <= 0:
break
bases[index] += 1
leftover -= 1
return [money(base, amount.currency) for base in bases]