CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-num2words

Modules to convert numbers to words in multiple languages with support for 50+ locales.

Pending
Overview
Eval results
Files

base-converter.mddocs/

Base Converter Architecture

The foundation of num2words is the Num2Word_Base class, which provides the core architecture and methods that all language-specific converters inherit from. This design enables consistent behavior across all 50+ supported languages while allowing for language-specific customizations.

Capabilities

Base Converter Class

The foundation class that all language converters inherit from.

class Num2Word_Base:
    """
    Base class for all language-specific number-to-word converters.
    
    Attributes:
    - CURRENCY_FORMS: dict - Currency format definitions for the language
    - CURRENCY_ADJECTIVES: dict - Currency adjective forms
    - is_title: bool - Whether to title-case output
    - precision: int - Decimal precision for float handling
    - negword: str - Prefix for negative numbers
    - pointword: str - Word for decimal point
    - cards: OrderedDict - Number word mappings
    - MAXVAL: int - Maximum supported number value
    """
    
    def __init__(self): ...

Usage Examples:

from num2words.base import Num2Word_Base

# Access base converter (not typically used directly)
base_converter = Num2Word_Base()

# Language converters inherit from this base
from num2words import CONVERTER_CLASSES
english_converter = CONVERTER_CLASSES['en']
print(type(english_converter).__bases__)  # Shows Num2Word_Base in inheritance

Cardinal Number Conversion

Core method for converting numbers to cardinal word form.

def to_cardinal(self, value):
    """
    Convert number to cardinal word representation.
    
    Parameters:
    - value: int/float - Number to convert
    
    Returns:
    str - Cardinal number as words
    
    Raises:
    OverflowError - If number exceeds MAXVAL
    """

Usage Examples:

from num2words import CONVERTER_CLASSES

# Access converter directly
en_converter = CONVERTER_CLASSES['en']
result = en_converter.to_cardinal(42)      # "forty-two"
result = en_converter.to_cardinal(-15)     # "minus fifteen"
result = en_converter.to_cardinal(1000)    # "one thousand"

# Different languages
fr_converter = CONVERTER_CLASSES['fr']
result = fr_converter.to_cardinal(42)      # "quarante-deux"

Float Number Conversion

Specialized handling for floating-point numbers.

def to_cardinal_float(self, value):
    """
    Convert floating-point number to word representation.
    
    Handles decimal precision and fractional parts appropriately.
    
    Parameters:
    - value: float - Float number to convert
    
    Returns:
    str - Float number with decimal point as words
    
    Raises:
    TypeError - For invalid number types
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']
result = en_converter.to_cardinal_float(42.5)    # "forty-two point five"
result = en_converter.to_cardinal_float(3.14)    # "three point one four"
result = en_converter.to_cardinal_float(0.001)   # "zero point zero zero one"

Ordinal Number Conversion

Convert numbers to ordinal form (language-dependent implementation).

def to_ordinal(self, value):
    """
    Convert number to ordinal word representation.
    
    Base implementation delegates to to_cardinal.
    Language subclasses override for proper ordinal forms.
    
    Parameters:
    - value: int - Integer to convert to ordinal
    
    Returns:
    str - Ordinal number as words
    
    Raises:
    TypeError - For float inputs or negative numbers
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']
result = en_converter.to_ordinal(1)       # "first"
result = en_converter.to_ordinal(2)       # "second"
result = en_converter.to_ordinal(21)      # "twenty-first"
result = en_converter.to_ordinal(42)      # "forty-second"

# Validation
try:
    en_converter.to_ordinal(42.5)  # Floats not allowed
except TypeError:
    print("Ordinals require integers")

Ordinal Number (Numeric) Conversion

Convert numbers to numeric ordinal form.

def to_ordinal_num(self, value):
    """
    Convert number to numeric ordinal representation.
    
    Base implementation returns the number unchanged.
    Language subclasses override for proper suffixes.
    
    Parameters:
    - value: int - Integer to convert
    
    Returns:
    str - Numeric ordinal (e.g., "42nd")
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']
result = en_converter.to_ordinal_num(1)   # "1st"
result = en_converter.to_ordinal_num(2)   # "2nd"
result = en_converter.to_ordinal_num(3)   # "3rd"
result = en_converter.to_ordinal_num(4)   # "4th"
result = en_converter.to_ordinal_num(21)  # "21st"

Year Conversion

Convert numbers to year word format.

def to_year(self, value, **kwargs):
    """
    Convert number to year word representation.
    
    Base implementation delegates to to_cardinal.
    Language subclasses can override for year-specific formatting.
    
    Parameters:
    - value: int - Year to convert
    - **kwargs: Language-specific year formatting options
    
    Returns:
    str - Year as words
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']
result = en_converter.to_year(1984)       # "nineteen eighty-four"
result = en_converter.to_year(2000)       # "two thousand"
result = en_converter.to_year(2023)       # "twenty twenty-three"

Currency Conversion

Convert numbers to currency format with proper localization.

def to_currency(self, val, currency='EUR', cents=True, separator=',', adjective=False):
    """
    Convert number to currency word representation.
    
    Parameters:
    - val: int/float - Currency value
    - currency: str - Currency code (default: 'EUR')
    - cents: bool - Include verbose cents (default: True)
    - separator: str - Separator between currency and cents (default: ',')
    - adjective: bool - Include currency adjective prefix (default: False)
    
    Returns:
    str - Formatted currency string
    
    Raises:
    NotImplementedError - If currency not supported for language
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']
result = en_converter.to_currency(42.50)
# "forty-two euros, fifty cents"

result = en_converter.to_currency(42.50, currency='USD')
# "forty-two dollars, fifty cents"

result = en_converter.to_currency(42.50, cents=False)
# "forty-two euros, 50"

result = en_converter.to_currency(42.50, separator=' and ')
# "forty-two euros and fifty cents"

String to Number Conversion

Convert string representations to numeric values.

def str_to_number(self, value):
    """
    Convert string to Decimal number for processing.
    
    Parameters:
    - value: str - String representation of number
    
    Returns:
    Decimal - Parsed number
    
    Raises:
    ValueError - For invalid string formats
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']
number = en_converter.str_to_number("42")      # Decimal('42')
number = en_converter.str_to_number("42.5")    # Decimal('42.5')
number = en_converter.str_to_number("-15")     # Decimal('-15')

Number Splitting and Processing

Internal methods for breaking down numbers according to language rules.

def splitnum(self, value):
    """
    Split number into components according to language rules.
    
    Parameters:
    - value: int - Number to split
    
    Returns:
    list - Structured number components for word generation
    """

def float2tuple(self, value):
    """
    Split float into integer and fractional parts.
    
    Parameters:
    - value: float - Float to split
    
    Returns:
    tuple - (integer_part, fractional_part)
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']

# Split complex numbers
components = en_converter.splitnum(1234567)
# Returns structured breakdown for "one million, two hundred..."

# Split floats
integer_part, fractional_part = en_converter.float2tuple(42.567)
# Returns (42, 567) with appropriate precision handling

Language Setup and Customization

Methods for configuring language-specific behavior.

def setup(self):
    """
    Language-specific setup method.
    
    Override in language subclasses to configure:
    - negword: Negative number prefix
    - pointword: Decimal point word
    - exclude_title: Words to exclude from title casing
    - Number word dictionaries and mappings
    """

def set_numwords(self):
    """Set up number word dictionaries from language definitions."""

def set_high_numwords(self, *args):
    """Set up high-value number words (millions, billions, etc.)."""

def set_mid_numwords(self, mid):
    """Set up mid-range number words (tens, hundreds)."""

def set_low_numwords(self, numwords):
    """Set up low-value number words (0-19)."""

Advanced Number Splitting

Specialized method for splitting numbers with custom formatting options.

def to_splitnum(self, val, hightxt="", lowtxt="", jointxt="", divisor=100, longval=True, cents=True):
    """
    Split number into high and low components with custom formatting.
    
    Primarily used for currency and complex number formatting.
    
    Parameters:
    - val: int/float/tuple - Value to split
    - hightxt: str - Text for high component
    - lowtxt: str - Text for low component  
    - jointxt: str - Text to join components
    - divisor: int - Division factor (default: 100)
    - longval: bool - Use verbose format (default: True)
    - cents: bool - Verbose cents representation (default: True)
    
    Returns:
    str - Formatted split number string
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']

# Currency-style splitting
result = en_converter.to_splitnum(42.50, hightxt="dollars", lowtxt="cents")
# "forty-two dollars fifty cents"

# Custom splitting with divisor
result = en_converter.to_splitnum(365, hightxt="years", lowtxt="days", divisor=365)
# Custom format based on divisor

Currency Internal Methods

Internal methods used by to_currency() for formatting currency components.

def _money_verbose(self, number, currency):
    """
    Convert currency major unit to verbose representation.
    
    Parameters:
    - number: int - Major currency unit
    - currency: str - Currency code
    
    Returns:
    str - Verbose representation of major currency unit
    """

def _cents_verbose(self, number, currency):
    """
    Convert currency minor unit to verbose representation.
    
    Parameters:
    - number: int - Minor currency unit (cents)
    - currency: str - Currency code
    
    Returns:
    str - Verbose representation of minor currency unit
    """

def _cents_terse(self, number, currency):
    """
    Convert currency minor unit to terse numeric representation.
    
    Parameters:
    - number: int - Minor currency unit (cents)
    - currency: str - Currency code
    
    Returns:
    str - Terse numeric representation (e.g., "50")
    """

Usage Examples:

en_converter = CONVERTER_CLASSES['en']

# These are internal methods used by to_currency()
money_part = en_converter._money_verbose(42, 'EUR')      # "forty-two"
cents_part = en_converter._cents_verbose(50, 'EUR')     # "fifty"
cents_terse = en_converter._cents_terse(50, 'EUR')      # "50"

Text Formatting and Utilities

Helper methods for text processing and formatting.

def title(self, value):
    """
    Apply title casing based on is_title setting.
    
    Parameters:
    - value: str - Text to potentially title-case
    
    Returns:
    str - Formatted text
    """

def inflect(self, value, text):
    """
    Basic pluralization for currency and other forms.
    
    Parameters:
    - value: int - Number for pluralization decision
    - text: str - Text with plural forms (format: "singular/plural")
    
    Returns:
    str - Appropriately inflected text
    """

def parse_minus(self, num_str):
    """
    Extract minus sign from number string.
    
    Parameters:
    - num_str: str - Number string that may start with '-'
    
    Returns:
    tuple - (minus_prefix, cleaned_number_string)
    """

Abstract Methods

Methods that must be implemented by language subclasses.

def pluralize(self, n, forms):
    """
    Language-specific pluralization rules.
    
    Must be implemented by language subclasses.
    
    Parameters:
    - n: int - Number for pluralization decision
    - forms: tuple - Available forms for pluralization
    
    Returns:
    str - Correctly pluralized form
    
    Raises:
    NotImplementedError - If not implemented by subclass
    """

def merge(self, curr, next):
    """
    Language-specific number component merging.
    
    Must be implemented by language subclasses.
    
    Parameters:
    - curr: tuple - Current number component
    - next: tuple - Next number component
    
    Returns:
    tuple - Merged component
    
    Raises:
    NotImplementedError - If not implemented by subclass
    """

Inheritance Hierarchy

The language converters follow a clear inheritance pattern:

# Base class
Num2Word_Base
├── Num2Word_EU (European base class)
│   ├── Num2Word_EN (English)
│   │   ├── Num2Word_EN_IN (English India)
│   │   └── Num2Word_EN_NG (English Nigeria)
│   ├── Num2Word_FR (French)
│   │   ├── Num2Word_FR_BE (French Belgium)
│   │   ├── Num2Word_FR_CH (French Switzerland)
│   │   └── Num2Word_FR_DZ (French Algeria)
│   ├── Num2Word_ES (Spanish)
│   │   ├── Num2Word_ES_CO (Spanish Colombia)
│   │   ├── Num2Word_ES_CR (Spanish Costa Rica)
│   │   └── ...
│   └── ... (other European languages)
├── Num2Word_AR (Arabic)
├── Num2Word_JA (Japanese)
├── Num2Word_KO (Korean)
└── ... (other non-European languages)

Configuration Attributes

Each converter can be configured with various attributes:

class ConverterAttributes:
    """Common configuration attributes for converters."""
    
    # Text formatting
    is_title: bool = False           # Enable title casing
    exclude_title: list = []         # Words to exclude from title casing
    
    # Number representation
    negword: str = "(-) "           # Negative number prefix
    pointword: str = "(.)"          # Decimal point representation
    precision: int = 2              # Decimal precision
    
    # Currency support
    CURRENCY_FORMS: dict = {}       # Currency name forms
    CURRENCY_ADJECTIVES: dict = {}  # Currency adjectives
    
    # Number limits
    MAXVAL: int                     # Maximum supported number
    
    # Error messages
    errmsg_nonnum: str             # Non-numeric input error
    errmsg_floatord: str           # Float ordinal error
    errmsg_negord: str             # Negative ordinal error
    errmsg_toobig: str             # Number too large error

Error Handling

The base converter provides standardized error handling:

# Type validation
converter = CONVERTER_CLASSES['en']

try:
    converter.to_ordinal(42.5)  # Floats not allowed for ordinals
except TypeError as e:
    print(e)  # "Cannot treat float 42.5 as ordinal."

try:
    converter.to_ordinal(-5)  # Negative numbers not allowed for ordinals
except TypeError as e:
    print(e)  # "Cannot treat negative num -5 as ordinal."

# Overflow protection
try:
    converter.to_cardinal(10**100)  # Exceeds MAXVAL
except OverflowError as e:
    print(e)  # "abs(value) must be less than MAXVAL."

Install with Tessl CLI

npx tessl i tessl/pypi-num2words

docs

base-converter.md

currency-conversion.md

index.md

language-support.md

number-conversion.md

utility-functions.md

tile.json