# -*- coding: utf-8 -*-
"""Swahili language module."""
from .base import AbstractNumber
[docs]class Number(AbstractNumber):
ZERO = 'sifuri'
NEGATIVE = 'hasi'
ONES = ['', 'moja', 'mbili', 'tatu', 'nne', 'tano', 'sita', 'saba', 'nane', 'tisa']
TENS = [
'', 'kumi', 'ishirini', 'thelathini', 'arobaini', 'hamsini', 'sitini',
'sabini', 'themanini', 'tisini'
]
HUNDREDS = [
'', 'mia moja', 'mia mbili', 'mia tatu', 'mia nne', 'mia tano',
'mia sita', 'mia saba', 'mia nane', 'mia tisa'
]
RANKS = [
'', 'elfu', 'milioni', 'bilioni', 'trilioni', 'kuadrilioni',
'kuintilioni', 'seksitilioni', 'septilioni', 'oktilioni', 'nonilioni',
'desilioni', 'anidesilioni', 'dodesilioni', 'tradesilioni',
'kuatuordesilion', 'kuindesilioni', 'seksidesilioni',
'septendesilioni', 'oktodesilioni', 'novemdesilioni', 'vijintilioni'
]
CONJUNCTION = 'na'
POINT = 'nukta'
def __init__(self, number, **kwargs):
super(Number, self).__init__(number)
kwargs = kwargs or {}
self.use_lakh = kwargs.get('use_lakh', False)
[docs] @classmethod
def digits_to_words(cls, number):
"""Get words for each digit in a number
Args:
number (numeric): A whole number
Returns:
str: words for each digit in a number.
"""
words = []
digits = str(number)
for i in digits:
if int(i) == 0:
words.append(cls.ZERO)
else:
words.append(cls.ONES[int(i)])
return ' '.join(words)
[docs] @classmethod
def hundreds_to_words(cls, number):
"""Get a whole number within range less than one thousand in words.
Args:
number (numeric): a numeric value to be converted
Returns
str: numeric value in words.
"""
words = []
number = int(number) % 1000
if number >= 100:
hundred = number // 100
hundredr = number % 100
if hundredr:
ten = hundredr // 10
one = hundredr % 10
words.append(cls.HUNDREDS[hundred])
if ten:
words.append(cls.CONJUNCTION)
words.append(cls.TENS[ten])
if one:
words.append(cls.CONJUNCTION)
words.append(cls.ONES[one])
else:
words.append(cls.HUNDREDS[hundred])
elif 100 > number >= 10:
ten = number // 10
one = number % 10
words.append(cls.TENS[ten])
if one:
words.append(cls.CONJUNCTION)
words.append(cls.ONES[one])
else:
words.append(cls.ONES[number])
if not words:
return ''
return ' '.join(words)
[docs] @classmethod
def short_scale_to_words(cls, number, use_lakh=False):
"""Get a value within a short scale range of a number in words.
Args:
number (numeric): An integer or a numeric string to be converted.
use_lakh (bool): Use Lakh (Laki) numbering system.
Defaults to False.
Returns:
str: numeric value within numbers short scale in words.
"""
number = int(number)
words = []
rank = cls.get_short_scale(number)
hundred = number // 10**(3*rank)
if rank == 1 and hundred >= 100 and use_lakh:
laki = hundred // 100
lakir = hundred % 100
words += ['laki', cls.ONES[laki]]
if lakir:
words += [cls.CONJUNCTION, 'elfu', cls.hundreds_to_words(lakir)]
else:
words = [cls.RANKS[rank], cls.hundreds_to_words(hundred)]
return ' '.join(words)
[docs] @classmethod
def short_scale_to_words_r(cls, number):
"""Get a value within the short scale range of a number in words
with words representing scale added at the end.
Args:
number (numeric): An integer or a numeric string to be converted.
use_lakh (bool): Use Lakh (Laki) numbering system.
Defaults to False.
Returns:
str: numeric value within numbers short scale in words.
"""
number = int(number)
words = []
rank = cls.get_short_scale(number)
words = [cls.hundreds_to_words(number // 10**(3*rank)), cls.RANKS[rank]]
return ' '.join(words)
[docs] def to_words(self):
"""Get words representing the instance number.
Returns:
str: number in words.
"""
words = []
cls = self.__class__
quotient = abs(int(self.quotient))
if self.is_negative:
words.append(cls.NEGATIVE)
if quotient == 0:
words.append(cls.ZERO)
elif quotient < 1000:
words.append(cls.hundreds_to_words(self.quotient))
else:
if quotient % 1000:
if (quotient % 1000) < 100:
conjunction = cls.CONJUNCTION
else:
conjunction = ','
else:
conjunction = None
while quotient >= 1000:
rank = self.get_short_scale(quotient)
_next = quotient - (quotient // 10**(3*rank)) * (10**(3*rank))
if (100000 <= quotient < 1000000) and not self.use_lakh:
words.append(cls.short_scale_to_words_r(quotient))
else:
words.append(cls.short_scale_to_words(quotient, self.use_lakh))
if _next >= 1000:
words.append(',') # TODO: should allow either ',' or 'na'
quotient = _next
else:
if conjunction:
words += [conjunction, cls.hundreds_to_words(quotient)]
if self.is_decimal:
words += [cls.POINT, cls.digits_to_words(self.fraction)]
return ' '.join(words).replace(' , ', ', ')