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 Dict, List, Tuple
from .money_amount import Money ← from money.amount ^1.0.0 · built alongside by fune
from .text_integer_to_words import integer_to_words ← from text.integer-to-words ^1.0.0 · built alongside by fune
#: English unit names: (major one, major many, minor one, minor many). All
#: three currencies have two decimal places, so the split below is by 100. A
#: currency is not added here without its real unit names: they cannot be
#: derived from a code.
_UNITS: Dict[str, Tuple[str, str, str, str]] = {
"GBP": ("pound", "pounds", "penny", "pence"),
"EUR": ("euro", "euros", "cent", "cents"),
"USD": ("dollar", "dollars", "cent", "cents"),
}
def amount_in_words(amount: Money) -> str:
"""Write a money amount in words, cheque style: 123456 GBP minor units is
"one thousand two hundred and thirty-four pounds and fifty-six pence".
"""
units = _UNITS.get(amount.currency)
if units is None:
raise ValueError('no words for currency "%s"' % (amount.currency,))
major_one, major_many, minor_one, minor_many = units
# Validate the whole amount first, so an out-of-range value fails with the
# same message it would as a plain number.
integer_to_words(amount.minor)
major, minor = divmod(abs(amount.minor), 100)
parts: List[str] = []
if major > 0 or minor == 0:
parts.append("%s %s" % (integer_to_words(major), major_one if major == 1 else major_many))
if minor > 0:
parts.append("%s %s" % (integer_to_words(minor), minor_one if minor == 1 else minor_many))
body = " and ".join(parts)
return "minus " + body if amount.minor < 0 else body