Functional Weave
Code in Python

money.format@1.0.0

impl/python.py

1,135 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 .money_amount import Money  ← from money.amount ^1.0.0 · built alongside by fune
from .money_format_data import CURRENCIES  ← this capability’s own data, compiled from data/currencies.json into the same file by fune build


def format_money(amount: Money) -> str:
    """Render a monetary amount as text.

    Not every currency has two decimal places: yen has none, Kuwaiti dinar has
    three. Dividing by 100 to display an amount is wrong about as often as it
    is right, so the precision comes from the currency table.
    """
    fmt = next((c for c in CURRENCIES if c.code == amount.currency), None)
    if fmt is None:
        raise ValueError('no formatting rules for currency "%s"' % (amount.currency,))

    negative = amount.minor < 0
    digits = str(abs(amount.minor)).rjust(fmt.digits + 1, "0")
    whole = digits[: len(digits) - fmt.digits]
    fraction = digits[len(digits) - fmt.digits :]

    grouped = ""
    for i, ch in enumerate(whole):
        if i > 0 and (len(whole) - i) % 3 == 0:
            grouped += fmt.group_separator
        grouped += ch

    number = grouped + fmt.decimal_separator + fraction if fmt.digits > 0 else grouped
    body = fmt.symbol + number if fmt.symbol_before else number + fmt.symbol
    return "-" + body if negative else body