Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Num2words swahili #539

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 54 additions & 9 deletions num2words/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,58 @@

from __future__ import unicode_literals

from . import (lang_AM, lang_AR, lang_AZ, lang_CZ, lang_DE, lang_DK, lang_EN,
lang_EN_IN, lang_EN_NG, lang_EO, lang_ES, lang_ES_CO,
lang_ES_GT, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_FR,
lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID,
lang_IS, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT,
lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR,
lang_RO, lang_RU, lang_SK, lang_SL, lang_SR, lang_SV, lang_TE,
lang_TG, lang_TH, lang_TR, lang_UK, lang_VI)
from . import (
lang_AM,
lang_AR,
lang_AZ,
lang_CZ,
lang_DE,
lang_DK,
lang_EN,
lang_EN_IN,
lang_EN_NG,
lang_EO,
lang_ES,
lang_ES_CO,
lang_ES_GT,
lang_ES_NI,
lang_ES_VE,
lang_FA,
lang_FI,
lang_FR,
lang_FR_BE,
lang_FR_CH,
lang_FR_DZ,
lang_HE,
lang_HU,
lang_ID,
lang_IS,
lang_IT,
lang_JA,
lang_KN,
lang_KO,
lang_KZ,
lang_LT,
lang_LV,
lang_NL,
lang_NO,
lang_PL,
lang_PT,
lang_PT_BR,
lang_RO,
lang_RU,
lang_SK,
lang_SL,
lang_SR,
lang_SV,
lang_SW,
lang_TE,
lang_TG,
lang_TH,
lang_TR,
lang_UK,
lang_VI,
)

CONVERTER_CLASSES = {
'am': lang_AM.Num2Word_AM(),
Expand Down Expand Up @@ -75,7 +119,8 @@
'uk': lang_UK.Num2Word_UK(),
'te': lang_TE.Num2Word_TE(),
'hu': lang_HU.Num2Word_HU(),
'is': lang_IS.Num2Word_IS()
'is': lang_IS.Num2Word_IS(),
'sw': lang_SW.Num2Word_SW(),
}

CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency']
Expand Down
204 changes: 204 additions & 0 deletions num2words/lang_SW.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
from num2words.base import Num2Word_Base

ONES = [
'sifuri',
'moja',
'mbili',
'tatu',
'nne',
'tano',
'sita',
'saba',
'nane',
'tisa',
]

ONES_STR = {
0: 'sifuri',
1: 'moja',
2: 'mbili',
3: 'tatu',
4: 'nne',
5: 'tano',
6: 'sita',
7: 'saba',
8: 'nane',
9: 'tisa',
}

TENS_STR = {
1: 'kumi',
2: 'ishirini',
3: 'thelathini',
4: 'arobaini',
5: 'hamsini',
6: 'sitini',
7: 'sabini',
8: 'themanini',
9: 'tisini',
}

EXPONENT_PREFIXES = {
6: 'm',
9: 'b',
12: 'tr',
15: 'quadr',
18: 'quint',
21: 'sext',
24: 'sept',
27: 'oct',
30: 'non',
33: 'dec',
}


class Num2Word_SW(Num2Word_Base):
MINUS_PREFIX_WORD = 'hasi '

def tens_to_cardinal(self, number):
'''Converts a number less than 100 to a string.'''
tens = number // 10
remainder = number % 10

prefix = TENS_STR[tens]
postfix = ONES[remainder]

if remainder == 0:
return prefix

return f'{prefix} na {postfix}'

def hundreds_to_cardinal(self, number):
'''Converts a number less than 1000 to a string.'''
hundreds = number // 100
remainder = number % 100

if remainder == 0:
return f'mia {ONES[hundreds]}'
elif remainder < 10:
return f'mia {ONES[hundreds]} na {ONES[remainder]}'
else:
return f'mia {ONES[hundreds]} {self.tens_to_cardinal(remainder)}'

def thousands_to_cardinal(self, number):
'''Converts a number less than 1_000_000 to a string.'''
thousands = number // 1000
remainder = number % 1000

if remainder == 0:
if thousands < 10:
# thousands = 1 - 9
return f'elfu {ONES[thousands]}'
elif thousands < 100:
# thousands = 10 - 99
return f'{self.tens_to_cardinal(thousands)} elfu'
else:
# thousands = 100 - 999
return f'{self.hundreds_to_cardinal(thousands)} elfu'
elif remainder < 10:
if thousands < 10:
# thousands = 1 - 9
return f'{ONES[thousands]} elfu na {ONES[remainder]}'
elif thousands < 100:
# thousands = 10 - 99
return f'{self.tens_to_cardinal(thousands)} elfu na {ONES[remainder]}'
elif thousands < 1000:
# thousands = 100 - 999
return (
f'{self.hundreds_to_cardinal(thousands)} elfu na {ONES[remainder]}'
)
elif remainder < 100:
if thousands < 10:
# thousands = 1 - 9
return f'{ONES[thousands]} elfu na {self.tens_to_cardinal(remainder)}'
elif thousands < 100:
# thousands = 10 - 99
return (
f'{self.tens_to_cardinal(thousands)} elfu na '
f'{self.tens_to_cardinal(remainder)}'
)
elif thousands < 1000:
# thousands = 100 - 999
return (
f'{self.hundreds_to_cardinal(thousands)} elfu, '
f'{self.tens_to_cardinal(remainder)}'
)
elif remainder < 1000:
if thousands < 10:
# thousands = 1 - 9
return f'{ONES[thousands]} elfu, {self.hundreds_to_cardinal(remainder)}'
elif thousands < 100:
# thousands = 10 - 99
return (
f'{self.tens_to_cardinal(thousands)} elfu, '
f'{self.hundreds_to_cardinal(remainder)}'
)
else:
# thousands = 100 - 999
return (
f'{self.hundreds_to_cardinal(thousands)} elfu, '
f'{self.hundreds_to_cardinal(remainder)}'
)

def big_number_to_cardinal(self, number):
digits = [c for c in str(number)]
length = len(digits)
if length >= 66:
raise NotImplementedError('The given number is too large.')

predigits = length % 3 or 3
num = int(''.join(digits[:predigits]))
if num < 10:
num_in_words = ONES_STR[num]
elif num < 100:
num_in_words = self.tens_to_cardinal(num)
else:
num_in_words = self.hundreds_to_cardinal(num)

word = EXPONENT_PREFIXES[len(digits[predigits:])] + 'ilioni'
base = f'{num_in_words} {word}'
number = int(''.join(digits[predigits:])) # remaining number

if number == 0:
return f'{word} {num_in_words}'
elif number < 10:
return f'{base} na {ONES[number]}'
elif number < 100:
return f'{base} na {self.tens_to_cardinal(number)}'
elif number < 1000:
return f'{base}, {self.hundreds_to_cardinal(number)}'
elif number < 1_000_000:
return f'{base}, {self.thousands_to_cardinal(number)}'
else:
return f'{base}, {self.big_number_to_cardinal(number)}'

def to_cardinal(self, number):
if number < 0:
# negative number
string = self.MINUS_PREFIX_WORD + self.to_cardinal(-number)
elif number < 10:
# 1 - 9
string = ONES[int(number)]
elif number < 100:
# 10 - 99
string = self.tens_to_cardinal(int(number))
elif number < 1000:
# 100 - 999
string = self.hundreds_to_cardinal(number)
elif number < 1_000_000:
# 100 - 999999
string = self.thousands_to_cardinal(int(number))
else:
# 1_000_000 - Infinity
string = self.big_number_to_cardinal(int(number))
return string

def to_ordinal(self, number):
'''Converts number to ordinal.'''
if number <= 0:
raise Exception('number must be greater than zero to convert to ordinal')
if number == 1:
return 'kwanza'
if number == 2:
return 'pili'
return self.to_cardinal(number)
Loading
Loading