from typing import List from .money_amount import Money, money def split_even(amount: Money, parts: int) -> List[Money]: """Split ``amount`` into ``parts`` near-equal shares that sum to exactly ``amount``. The leftover minor units go one each to the first shares, and a negative amount splits as the mirror image of the positive one, so a refund undoes the original split share for share. """ if isinstance(parts, bool) or not isinstance(parts, int): raise TypeError("parts must be a whole number, received %r" % (parts,)) if parts < 1: raise ValueError("parts must be at least 1, received %d" % (parts,)) sign = -1 if amount.minor < 0 else 1 # divmod on the magnitude: Python's floor division would round a negative # amount the other way and put the odd penny last. base, leftover = divmod(abs(amount.minor), parts) return [money(sign * (base + (1 if i < leftover else 0)), amount.currency) for i in range(parts)]