This commit is contained in:
2026-02-27 05:48:07 +01:00
parent 02993336de
commit 4eae444c93
3 changed files with 228 additions and 125 deletions

View File

@@ -0,0 +1,77 @@
from decimal import Decimal, ROUND_HALF_UP
UNITS = (
"ZERO ONE TWO THREE FOUR FIVE SIX SEVEN EIGHT NINE TEN ELEVEN TWELVE "
"THIRTEEN FOURTEEN FIFTEEN SIXTEEN SEVENTEEN EIGHTEEN NINETEEN"
).split()
TENS = "ZERO TEN TWENTY THIRTY FORTY FIFTY SIXTY SEVENTY EIGHTY NINETY".split()
def _under_thousand(n, use_and=True):
words = []
hundreds = n // 100
remainder = n % 100
if hundreds:
words.append(UNITS[hundreds])
words.append("HUNDRED")
if remainder and use_and:
words.append("AND")
if remainder:
if remainder < 20:
words.append(UNITS[remainder])
else:
words.append(TENS[remainder // 10])
if remainder % 10:
words.append(UNITS[remainder % 10])
return " ".join(words)
def number_to_words(n, decimals_mode="digit", use_and=True):
"""
decimals_mode:
- "digit" → ONE HUNDRED POINT TWO FIVE
- "fraction" → ONE HUNDRED AND 25/100
"""
n = Decimal(str(n)).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
integer_part = int(n)
decimal_part = int((n - integer_part) * 100)
if integer_part == 0:
words = "ZERO"
else:
parts = []
millions = integer_part // 1_000_000
thousands = (integer_part // 1_000) % 1_000
remainder = integer_part % 1_000
if millions:
parts.append(_under_thousand(millions, use_and))
parts.append("MILLION")
if thousands:
parts.append(_under_thousand(thousands, use_and))
parts.append("THOUSAND")
if remainder:
parts.append(_under_thousand(remainder, use_and))
words = " ".join(parts)
# Gestion décimales
if decimal_part:
if decimals_mode == "digit":
digits = " ".join(UNITS[int(d)] for d in f"{decimal_part:02d}")
words = f"{words} POINT {digits}"
elif decimals_mode == "fraction":
words = f"{words} AND {decimal_part:02d}/100"
return words.upper()