Merge pull request #465 from devEyosiyas/master

Fix Amharic language support
This commit is contained in:
Marlon Rodriguez Garcia
2022-08-10 10:57:25 -04:00
committed by GitHub
4 changed files with 233 additions and 8 deletions

View File

@@ -76,6 +76,7 @@ Besides the numerical argument, there are two main optional arguments.
**lang:** The language in which to convert the number. Supported values are: **lang:** The language in which to convert the number. Supported values are:
* ``en`` (English, default) * ``en`` (English, default)
* ``am`` (Amharic)
* ``ar`` (Arabic) * ``ar`` (Arabic)
* ``cz`` (Czech) * ``cz`` (Czech)
* ``de`` (German) * ``de`` (German)
@@ -150,4 +151,4 @@ added Lithuanian support, but didn't take over maintenance of the project.
I am thus basing myself on Marius Grigaitis' improvements and re-publishing I am thus basing myself on Marius Grigaitis' improvements and re-publishing
``pynum2word`` as ``num2words``. ``pynum2word`` as ``num2words``.
Virgil Dupras, Savoir-faire Linux Virgil Dupras, Savoir-faire Linux

View File

@@ -17,15 +17,16 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN,
lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE, lang_FA, lang_FI, lang_EN_IN, lang_ES, lang_ES_CO, lang_ES_NI, lang_ES_VE,
lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ,
lang_ID, lang_IT, lang_JA, lang_KN, lang_KO, lang_KZ, lang_LT, lang_HE, lang_HU, lang_ID, lang_IT, lang_JA, lang_KN, lang_KO,
lang_LV, lang_NL, lang_NO, lang_PL, lang_PT, lang_PT_BR, lang_KZ, lang_LT, lang_LV, lang_NL, lang_NO, lang_PL, lang_PT,
lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, lang_TE, lang_TG, lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV,
lang_TH, lang_TR, lang_UK, lang_VI) lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI)
CONVERTER_CLASSES = { CONVERTER_CLASSES = {
'am': lang_AM.Num2Word_AM(),
'ar': lang_AR.Num2Word_AR(), 'ar': lang_AR.Num2Word_AR(),
'cz': lang_CZ.Num2Word_CZ(), 'cz': lang_CZ.Num2Word_CZ(),
'en': lang_EN.Num2Word_EN(), 'en': lang_EN.Num2Word_EN(),

129
num2words/lang_AM.py Normal file
View File

@@ -0,0 +1,129 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
from __future__ import division, print_function, unicode_literals
from . import lang_EU
class Num2Word_AM(lang_EU.Num2Word_EU):
CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))}
GIGA_SUFFIX = 'ቢሊዮን'
MEGA_SUFFIX = 'ሚሊዮን'
def set_high_numwords(self, high):
cap = 3 * (len(high) + 1)
for word, n in zip(high, range(cap, 5, -3)):
if n == 9:
self.cards[10 ** n] = word + self.GIGA_SUFFIX
else:
self.cards[10 ** n] = word + self.MEGA_SUFFIX
def setup(self):
super(Num2Word_AM, self).setup()
self.negword = 'አሉታዊ '
self.pointword = 'ነጥብ'
self.exclude_title = ['እና', 'ነጥብ', 'አሉታዊ']
self.mid_numwords = [(1000, 'ሺህ'), (100, 'መቶ'), (90, 'ዘጠና'),
(80, 'ሰማኒያ'), (70, 'ሰባ'), (60, 'ስድሳ'),
(50, 'አምሳ'), (40, 'አርባ'), (30, 'ሠላሳ')]
self.low_numwords = ['ሃያ', 'አሥራ ዘጠኝ', 'አሥራ ስምንት', 'አሥራ ሰባት',
'አስራ ስድስት', 'አሥራ አምስት', 'አሥራ አራት', 'አሥራ ሦስት',
'አሥራ ሁለት', 'አሥራ አንድ', 'አሥር', 'ዘጠኝ', 'ስምንት',
'ሰባት', 'ስድስት', 'አምስት', 'አራት', 'ሦስት', 'ሁለት',
'አንድ', 'ዜሮ']
self.ords = {'አንድ': 'አንደኛ',
'ሁለት': 'ሁለተኛ',
'ሦስት': 'ሦስተኛ',
'አራት': 'አራተኛ',
'አምስት': 'አምስተኛ',
'ስድስት': 'ስድስተኛ',
'ሰባት': 'ሰባተኛ',
'ስምንት': 'ስምንተኛ',
'ዘጠኝ': 'ዘጠነኛ',
'አሥር': 'አሥረኛ',
'አሥራ አንድ': 'አሥራ አንደኛ',
'አሥራ ሁለት': 'አሥራ ሁለተኛ',
'አሥራ ሦስት': 'አሥራ ሦስተኛ',
'አሥራ አራት': 'አሥራ አራተኛ',
'አሥራ አምስት': 'አሥራ አምስተኛ',
'አሥራ ስድስት': 'አሥራ ስድስተኛ',
'አሥራ ሰባት': 'አሥራ ሰባተኛ',
'አሥራ ስምንት': 'አሥራ ስምንተኛ',
'አሥራ ዘጠኝ': 'አሥራ ዘጠነኛ'}
def to_cardinal(self, value):
try:
assert int(value) == value
except (ValueError, TypeError, AssertionError):
return self.to_cardinal_float(value)
out = ''
if value >= self.MAXVAL:
raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL))
if value == 100:
return self.title(out + 'መቶ')
else:
val = self.splitnum(value)
words, num = self.clean(val)
return self.title(out + words)
def merge(self, lpair, rpair):
ltext, lnum = lpair
rtext, rnum = rpair
if lnum == 1 and rnum < 100:
return rtext, rnum
elif 100 > lnum > rnum:
return '%s %s' % (ltext, rtext), lnum + rnum
elif lnum >= 100 > rnum:
return '%s %s' % (ltext, rtext), lnum + rnum
elif rnum > lnum:
return '%s %s' % (ltext, rtext), lnum * rnum
def to_ordinal(self, value):
self.verify_ordinal(value)
outwords = self.to_cardinal(value).split(' ')
lastwords = outwords[-1].split('-')
lastword = lastwords[-1].lower()
try:
lastword = self.ords[lastword]
except KeyError:
lastword += ''
lastwords[-1] = self.title(lastword)
outwords[-1] = ' '.join(lastwords)
return ' '.join(outwords)
def to_ordinal_num(self, value):
self.verify_ordinal(value)
return '%s%s' % (value, self.to_ordinal(value)[-1:])
def to_currency(self, val, currency='ብር', cents=True, separator='',
adjective=True):
result = super(Num2Word_AM, self).to_currency(
val, currency=currency, cents=cents, separator=separator,
adjective=adjective)
return result
def to_year(self, val, longval=True):
if not (val // 100) % 10:
return self.to_cardinal(val)
return self.to_splitnum(val, hightxt='መቶ', longval=longval)

94
tests/test_am.py Normal file
View File

@@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2003, Taro Ogawa. All Rights Reserved.
# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved.
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
from unittest import TestCase
from num2words import num2words
class Num2WordsAMTest(TestCase):
def test_cardinal(self):
self.assertEqual(num2words(100, lang='am'), 'መቶ')
self.assertEqual(num2words(100000, lang='am'), 'አንድ መቶ ሺህ')
self.assertEqual(num2words(101, lang='am'), 'አንድ መቶ አንድ')
def test_and_join_199(self):
self.assertEqual(num2words(199, lang='am'), 'አንድ መቶ ዘጠና ዘጠኝ')
def test_to_ordinal(self):
self.assertEqual(
num2words(1, lang='am', to='ordinal'),
'አንደኛ'
)
self.assertEqual(
num2words(13, lang='am', to='ordinal'),
'አሥራ ሦስተኛ'
)
self.assertEqual(
num2words(22, lang='am', to='ordinal'),
'ሃያ ሁለተኛ'
)
self.assertEqual(
num2words(10000, lang='am', to='ordinal'),
'አሥር ሺህኛ'
)
def test_to_ordinal_num(self):
self.assertEqual(num2words(10, lang='am', to='ordinal_num'), '10ኛ')
self.assertEqual(num2words(21, lang='am', to='ordinal_num'), '21ኛ')
self.assertEqual(num2words(102, lang='am', to='ordinal_num'), '102ኛ')
def test_cardinal_for_float_number(self):
self.assertEqual(num2words(12.5, lang='am'), 'አሥራ ሁለት ነጥብ አምስት')
self.assertEqual(num2words(12.51, lang='am'), 'አሥራ ሁለት ነጥብ አምስት አንድ')
self.assertEqual(num2words(12.53, lang='am'), 'አሥራ ሁለት ነጥብ አምስት ሦስት')
def test_to_overflow(self):
with self.assertRaises(OverflowError):
num2words('1000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'0000000000000000000000000000000000000000000000000000000'
'00000000000000000000000000000000', lang='am')
def test_to_currency(self):
self.assertEqual(
num2words('38.4', lang='am', to='currency', cents=False,
currency='ETB'), 'ሠላሳ ስምንት ብር ከ 40 ሳንቲም'
)
self.assertEqual(
num2words('0', lang='am', to='currency', separator=' እና',
cents=True, currency='ETB'), 'ዜሮ ብር እና ዜሮ ሳንቲም'
)
self.assertEqual(
num2words('1.50', lang='am', to='currency', cents=True,
currency='ETB'), 'አንድ ብር ከ አምሳ ሳንቲም'
)
def test_to_year(self):
self.assertEqual(num2words(1990, lang='am', to='year'),
'አሥራ ዘጠኝ መቶ ዘጠና')
self.assertEqual(num2words(5555, lang='am', to='year'),
'አምሳ አምስት መቶ አምሳ አምስት')
self.assertEqual(num2words(2017, lang='am', to='year'),
'ሁለት ሺህ አሥራ ሰባት')
self.assertEqual(num2words(1066, lang='am', to='year'),
'አንድ ሺህ ስድሳ ስድስት')
self.assertEqual(num2words(1865, lang='am', to='year'),
'አሥራ ስምንት መቶ ስድሳ አምስት')