From ed97e11bfbc8521bffc74ead59927f83d813cfc2 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:19:49 +0300 Subject: [PATCH 01/10] Add Amharic language --- num2words/lang_AM.py | 107 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 num2words/lang_AM.py diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py new file mode 100644 index 0000000..5d1e7bb --- /dev/null +++ b/num2words/lang_AM.py @@ -0,0 +1,107 @@ +# -*- 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): + def set_high_numwords(self, high): + max = 3 + 3 * len(high) + for word, n in zip(high, range(max, 3, -3)): + self.cards[10 ** n] = word + "ሊዮን" + + 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 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) + 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: + if lastword[-1] == "y": + lastword = lastword[:-1] + "ie" + lastword += "th" + 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)[-2:]) + + def to_currency(self, val, currency='ብር', cents=True, separator='.', + adjective=False): + 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) \ + .replace(' ', '') From c06ff54f6485b67f4d0819be4cf88627eb1ca891 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:30:30 +0300 Subject: [PATCH 02/10] Update init for Amharic language --- num2words/__init__.py | 3 ++- tests/test_am.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tests/test_am.py diff --git a/num2words/__init__.py b/num2words/__init__.py index 1dfb5b0..baba5bd 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -23,10 +23,11 @@ from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_ID, 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_SL, lang_SR, lang_SV, lang_TE, lang_TH, - lang_TR, lang_UK, lang_VI) + lang_TR, lang_UK, lang_VI, lang_AM) CONVERTER_CLASSES = { 'ar': lang_AR.Num2Word_AR(), + 'am': lang_AM.Num2Word_AM(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/tests/test_am.py b/tests/test_am.py new file mode 100644 index 0000000..1a8436c --- /dev/null +++ b/tests/test_am.py @@ -0,0 +1,23 @@ +# -*- 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): From 47d63acabf78005bc8d71a853425416047dce2b6 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 22:34:49 +0300 Subject: [PATCH 03/10] Update Amharic language --- num2words/lang_AM.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 5d1e7bb..6e4f2f9 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -67,9 +67,9 @@ class Num2Word_AM(lang_EU.Num2Word_EU): if lnum == 1 and rnum < 100: return (rtext, rnum) elif 100 > lnum > rnum: - return ("%s-%s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) elif lnum >= 100 > rnum: - return ("%s እና %s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) elif rnum > lnum: return ("%s %s" % (ltext, rtext), lnum * rnum) return ("%s, %s" % (ltext, rtext), lnum + rnum) @@ -86,7 +86,7 @@ class Num2Word_AM(lang_EU.Num2Word_EU): lastword = lastword[:-1] + "ie" lastword += "th" lastwords[-1] = self.title(lastword) - outwords[-1] = "-".join(lastwords) + outwords[-1] = " ".join(lastwords) return " ".join(outwords) def to_ordinal_num(self, value): From d1a85b315a5401e3313d0023dbe6f19e6b9c5aae Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 23:02:25 +0300 Subject: [PATCH 04/10] Add Amharic currency form --- num2words/lang_AM.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 6e4f2f9..024e3e1 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -21,6 +21,8 @@ from . import lang_EU class Num2Word_AM(lang_EU.Num2Word_EU): + CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))} + def set_high_numwords(self, high): max = 3 + 3 * len(high) for word, n in zip(high, range(max, 3, -3)): @@ -93,8 +95,8 @@ class Num2Word_AM(lang_EU.Num2Word_EU): self.verify_ordinal(value) return "%s%s" % (value, self.to_ordinal(value)[-2:]) - def to_currency(self, val, currency='ብር', cents=True, separator='.', - adjective=False): + 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) From 308965bb993a46138fdf9585bccfa940f295f631 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Sun, 7 Aug 2022 23:06:48 +0300 Subject: [PATCH 05/10] Add test cases --- num2words/lang_AM.py | 3 +-- tests/test_am.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 024e3e1..4072559 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -105,5 +105,4 @@ class Num2Word_AM(lang_EU.Num2Word_EU): 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) \ - .replace(' ', '') + return self.to_splitnum(val, hightxt="መቶ", longval=longval) diff --git a/tests/test_am.py b/tests/test_am.py index 1a8436c..6c47955 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -21,3 +21,46 @@ from num2words import num2words class Num2WordsAMTest(TestCase): + def test_and_join_199(self): + self.assertEqual(num2words(199, lang='am'), "አንድ መቶ ዘጠና ዘጠኝ") + + def test_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'), + 'ሃያ ሁለተኛ' + ) + + 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'), + 'አሥራ ስምንት መቶ ስድሳ አምስት') From c586bef2d6cdd0e18e8941177674c9ed5ec80c14 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 11:14:40 +0300 Subject: [PATCH 06/10] Fix flake 8 requirements in python3.1 and increase test coverage. --- num2words/__init__.py | 16 ++++++++-------- num2words/lang_AM.py | 2 +- tests/test_am.py | 31 +++++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index baba5bd..dc42220 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,17 +17,17 @@ from __future__ import unicode_literals -from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, 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_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_SL, lang_SR, lang_SV, lang_TE, lang_TH, - lang_TR, lang_UK, lang_VI, lang_AM) +from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, + lang_EN_IN, lang_ES, lang_ES_CO, 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_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_SL, lang_SR, lang_SV, lang_TE, + lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { - 'ar': lang_AR.Num2Word_AR(), 'am': lang_AM.Num2Word_AM(), + 'ar': lang_AR.Num2Word_AR(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 4072559..4e40bda 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -93,7 +93,7 @@ class Num2Word_AM(lang_EU.Num2Word_EU): def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + return "%s%s" % (value, self.to_ordinal(value)[-1:]) def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', adjective=True): diff --git a/tests/test_am.py b/tests/test_am.py index 6c47955..a3dc95d 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -38,19 +38,38 @@ class Num2WordsAMTest(TestCase): 'ሃያ ሁለተኛ' ) + def test_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_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 ሳንቲም" + 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'), - "ዜሮ ብር እና ዜሮ ሳንቲም" + num2words('0', lang='am', to='currency', separator=' እና', + cents=True, currency='ETB'), "ዜሮ ብር እና ዜሮ ሳንቲም" ) self.assertEqual( - num2words('1.50', lang='am', to='currency', cents=True, currency='ETB'), - "አንድ ብር ከ አምሳ ሳንቲም" + num2words('1.50', lang='am', to='currency', cents=True, + currency='ETB'), "አንድ ብር ከ አምሳ ሳንቲም" ) def test_to_year(self): From 6ea21b82005e0faf5d2fb0b0ae58a80237aa37e8 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 17:00:56 +0300 Subject: [PATCH 07/10] Fix line too long __init__.py --- num2words/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index dc42220..86f1b63 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -22,8 +22,8 @@ from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_FA, lang_FI, lang_FR, lang_FR_BE, lang_FR_CH, lang_FR_DZ, lang_HE, lang_HU, lang_ID, 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_SL, lang_SR, lang_SV, lang_TE, - lang_TH, lang_TR, lang_UK, lang_VI) + lang_PT_BR, lang_RO, lang_RU, lang_SL, lang_SR, lang_SV, + lang_TE, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), From 75fdd6289f80926d0870206e257436917433b18c Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 21:13:53 +0300 Subject: [PATCH 08/10] Update Amharic language support --- README.rst | 3 +- num2words/lang_AM.py | 120 ++++++++++++++++++++++++++----------------- tests/test_am.py | 39 ++++++++------ 3 files changed, 98 insertions(+), 64 deletions(-) diff --git a/README.rst b/README.rst index 0414531..7b9b487 100644 --- a/README.rst +++ b/README.rst @@ -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: * ``en`` (English, default) +* ``am`` (Amharic) * ``ar`` (Arabic) * ``cz`` (Czech) * ``de`` (German) @@ -149,4 +150,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 ``pynum2word`` as ``num2words``. -Virgil Dupras, Savoir-faire Linux +Virgil Dupras, Savoir-faire Linux \ No newline at end of file diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 4e40bda..3efd9c2 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -23,45 +23,73 @@ from . import lang_EU class Num2Word_AM(lang_EU.Num2Word_EU): CURRENCY_FORMS = {'ETB': (('ብር', 'ብር'), ('ሳንቲም', 'ሳንቲም'))} + GIGA_SUFFIX = 'ቢሊዮን' + MEGA_SUFFIX = 'ሚሊዮን' + def set_high_numwords(self, high): - max = 3 + 3 * len(high) - for word, n in zip(high, range(max, 3, -3)): - self.cards[10 ** n] = word + "ሊዮን" + 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.negword = 'አሉታዊ ' + self.pointword = 'ነጥብ' + self.exclude_title = ['እና', 'ነጥብ', 'አሉታዊ'] - self.mid_numwords = [(1000, "ሺህ"), (100, "መቶ"), (90, "ዘጠና"), - (80, "ሰማኒያ"), (70, "ሰባ"), (60, "ስድሳ"), - (50, "አምሳ"), (40, "አርባ"), (30, "ሠላሳ")] - self.low_numwords = ["ሃያ", "አሥራ ዘጠኝ", "አሥራ ስምንት", "አሥራ ሰባት", - "አስራ ስድስት", "አሥራ አምስት", "አሥራ አራት", "አሥራ ሦስት", - "አሥራ ሁለት", "አሥራ አንድ", "አሥር", "ዘጠኝ", "ስምንት", - "ሰባት", "ስድስት", "አምስት", "አራት", "ሦስት", "ሁለት", - "አንድ", "ዜሮ"] - self.ords = {"አንድ": "አንደኛ", - "ሁለት": "ሁለተኛ", - "ሦስት": "ሦስተኛ", - "አራት": "አራተኛ", - "አምስት": "አምስተኛ", - "ስድስት": "ስድስተኛ", - "ሰባት": "ሰባተኛ", - "ስምንት": "ስምንተኛ", - "ዘጠኝ": "ዘጠነኛ", - "አሥር": "አሥረኛ", - "አሥራ አንድ": "አሥራ አንድ", - "አሥራ ሁለት": "አሥራ ሁለተኛ", - "አሥራ ሦስት": "አሥራ ሦስተኛ", - "አሥራ አራት": "አሥራ አራተኛ", - "አሥራ አምስት": "አሥራ አምስተኛ", - "አሥራ ስድስት": "አሥራ ስድስተኛ", - "አሥራ ሰባት": "አሥራ ሰባተኛ", - "አሥራ ስምንት": "አሥራ ስምንተኛ", - "አሥራ ዘጠኝ": "አሥራ ዘጠነኛ"} + 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 < 0: + value = abs(value) + out = self.negword + + 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 @@ -69,31 +97,31 @@ class Num2Word_AM(lang_EU.Num2Word_EU): if lnum == 1 and rnum < 100: return (rtext, rnum) elif 100 > lnum > rnum: - return ("%s %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum + rnum) elif lnum >= 100 > rnum: - return ("%s %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum + rnum) elif rnum > lnum: - return ("%s %s" % (ltext, rtext), lnum * rnum) - return ("%s, %s" % (ltext, rtext), lnum + rnum) + return ('%s %s' % (ltext, rtext), lnum * rnum) + 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("-") + outwords = self.to_cardinal(value).split(' ') + lastwords = outwords[-1].split('-') lastword = lastwords[-1].lower() try: lastword = self.ords[lastword] except KeyError: - if lastword[-1] == "y": - lastword = lastword[:-1] + "ie" - lastword += "th" + if lastword[-1] == 'y': + lastword = lastword[:-1] + 'ie' + lastword += 'th' lastwords[-1] = self.title(lastword) - outwords[-1] = " ".join(lastwords) - return " ".join(outwords) + 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:]) + return '%s%s' % (value, self.to_ordinal(value)[-1:]) def to_currency(self, val, currency='ብር', cents=True, separator=' ከ', adjective=True): @@ -105,4 +133,4 @@ class Num2Word_AM(lang_EU.Num2Word_EU): 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) + return self.to_splitnum(val, hightxt='መቶ', longval=longval) diff --git a/tests/test_am.py b/tests/test_am.py index a3dc95d..460ca6e 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -21,10 +21,15 @@ from num2words import num2words class Num2WordsAMTest(TestCase): - def test_and_join_199(self): - self.assertEqual(num2words(199, lang='am'), "አንድ መቶ ዘጠና ዘጠኝ") + def test_cardinal(self): + self.assertEqual(num2words(100, lang='am'), 'መቶ') + self.assertEqual(num2words(100000, lang='am'), 'አንድ መቶ ሺህ') + self.assertEqual(num2words(101, lang='am'), 'አንድ መቶ አንድ') - def test_ordinal(self): + 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'), 'አንደኛ' @@ -38,38 +43,38 @@ class Num2WordsAMTest(TestCase): 'ሃያ ሁለተኛ' ) - def test_ordinal_num(self): + 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'), "አሥራ ሁለት ነጥብ አምስት ሦስት") + self.assertEqual(num2words(12.5, lang='am'), 'አሥራ ሁለት ነጥብ አምስት') + self.assertEqual(num2words(12.51, lang='am'), 'አሥራ ሁለት ነጥብ አምስት አንድ') + self.assertEqual(num2words(12.53, lang='am'), 'አሥራ ሁለት ነጥብ አምስት ሦስት') - def test_overflow(self): + def test_to_overflow(self): with self.assertRaises(OverflowError): - num2words("1000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000", lang='am') + 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 ሳንቲም" + currency='ETB'), 'ሠላሳ ስምንት ብር ከ 40 ሳንቲም' ) self.assertEqual( num2words('0', lang='am', to='currency', separator=' እና', - cents=True, currency='ETB'), "ዜሮ ብር እና ዜሮ ሳንቲም" + cents=True, currency='ETB'), 'ዜሮ ብር እና ዜሮ ሳንቲም' ) self.assertEqual( num2words('1.50', lang='am', to='currency', cents=True, - currency='ETB'), "አንድ ብር ከ አምሳ ሳንቲም" + currency='ETB'), 'አንድ ብር ከ አምሳ ሳንቲም' ) def test_to_year(self): From b7277ffb93f2421899831dfe3efc53df5467b53e Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Tue, 9 Aug 2022 21:19:56 +0300 Subject: [PATCH 09/10] Update __init__.py --- num2words/__init__.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/num2words/__init__.py b/num2words/__init__.py index 236f2c7..3c9171a 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,15 +17,16 @@ from __future__ import unicode_literals -from . import (lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, - lang_ES, lang_ES_CO, 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_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_SL, lang_SR, lang_SV, lang_TE, lang_TG, - lang_TH, lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_CZ, lang_DE, lang_DK, lang_EN, + lang_EN_IN, lang_ES, lang_ES_CO, 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_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_SL, lang_SR, lang_SV, + lang_TE, lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) CONVERTER_CLASSES = { + 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), From 4c873a6a88e90333c53a753fcf2f520265258bf6 Mon Sep 17 00:00:00 2001 From: Eyosiyas Bereketab Date: Wed, 10 Aug 2022 09:34:03 +0300 Subject: [PATCH 10/10] Add additional test case --- num2words/lang_AM.py | 19 ++++++------------- tests/test_am.py | 4 ++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py index 3efd9c2..77922db 100644 --- a/num2words/lang_AM.py +++ b/num2words/lang_AM.py @@ -60,7 +60,7 @@ class Num2Word_AM(lang_EU.Num2Word_EU): 'ስምንት': 'ስምንተኛ', 'ዘጠኝ': 'ዘጠነኛ', 'አሥር': 'አሥረኛ', - 'አሥራ አንድ': 'አሥራ አንድ', + 'አሥራ አንድ': 'አሥራ አንደኛ', 'አሥራ ሁለት': 'አሥራ ሁለተኛ', 'አሥራ ሦስት': 'አሥራ ሦስተኛ', 'አሥራ አራት': 'አሥራ አራተኛ', @@ -77,10 +77,6 @@ class Num2Word_AM(lang_EU.Num2Word_EU): return self.to_cardinal_float(value) out = '' - if value < 0: - value = abs(value) - out = self.negword - if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) @@ -95,14 +91,13 @@ class Num2Word_AM(lang_EU.Num2Word_EU): ltext, lnum = lpair rtext, rnum = rpair if lnum == 1 and rnum < 100: - return (rtext, rnum) + return rtext, rnum elif 100 > lnum > rnum: - return ('%s %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum + rnum elif lnum >= 100 > rnum: - return ('%s %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum + rnum elif rnum > lnum: - return ('%s %s' % (ltext, rtext), lnum * rnum) - return ('%s, %s' % (ltext, rtext), lnum + rnum) + return '%s %s' % (ltext, rtext), lnum * rnum def to_ordinal(self, value): self.verify_ordinal(value) @@ -112,9 +107,7 @@ class Num2Word_AM(lang_EU.Num2Word_EU): try: lastword = self.ords[lastword] except KeyError: - if lastword[-1] == 'y': - lastword = lastword[:-1] + 'ie' - lastword += 'th' + lastword += 'ኛ' lastwords[-1] = self.title(lastword) outwords[-1] = ' '.join(lastwords) return ' '.join(outwords) diff --git a/tests/test_am.py b/tests/test_am.py index 460ca6e..58709c3 100644 --- a/tests/test_am.py +++ b/tests/test_am.py @@ -42,6 +42,10 @@ class Num2WordsAMTest(TestCase): 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ኛ')