diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68330d4c..f843e4e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v2 diff --git a/CHANGES.rst b/CHANGES.rst index ea33f3e2..32a6e616 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,23 @@ Changelog ========= +Version 0.5.14 -- 2024/12/16 +---------------------------- + +* Fixed a typo in PL (#466) +* Run tests against Python 3.12 (#544) +* ADD num2words: es_CR language (#565) +* New languages: Welsh (Celtic) and Chechen (Nakho-Dagestanian) (#543) +* Add catalan language support (#581) +* Adding Tetum Language (#576) +* FIX ISO code for Belarusian language is be, not by. (#574) +* Add test to improve coverage (#595) +* Added Bangla language support to num2word for Bangladesh. (#589) +* Czech language ISO 639-1 code fix (#587) +* Added support for Tunisian Dinar (#593) +* Change danish language code to DA (#596) + + Version 0.5.13 -- 2023/10/18 --------------------------- diff --git a/README.rst b/README.rst index c207324d..29f8d064 100644 --- a/README.rst +++ b/README.rst @@ -80,27 +80,30 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``ar`` (Arabic) * ``az`` (Azerbaijani) * ``be`` (Belarusian) +* ``bn`` (Bangladeshi) +* ``ca`` (Catalan) * ``ce`` (Chechen) +* ``cs`` (Czech) * ``cy`` (Welsh) -* ``cz`` (Czech) +* ``da`` (Danish) * ``de`` (German) -* ``dk`` (Danish) * ``en_GB`` (English - Great Britain) * ``en_IN`` (English - India) * ``en_NG`` (English - Nigeria) * ``es`` (Spanish) * ``es_CO`` (Spanish - Colombia) * ``es_CR`` (Spanish - Costa Rica) -* ``es_VE`` (Spanish - Venezuela) * ``es_GT`` (Spanish - Guatemala) +* ``es_VE`` (Spanish - Venezuela) * ``eu`` (EURO) * ``fa`` (Farsi) * ``fi`` (Finnish) * ``fr`` (French) -* ``fr_CH`` (French - Switzerland) * ``fr_BE`` (French - Belgium) +* ``fr_CH`` (French - Switzerland) * ``fr_DZ`` (French - Algeria) * ``he`` (Hebrew) +* ``hi`` (Hindi) * ``hu`` (Hungarian) * ``id`` (Indonesian) * ``is`` (Icelandic) @@ -111,23 +114,24 @@ Besides the numerical argument, there are two main optional arguments, ``to:`` a * ``kz`` (Kazakh) * ``lt`` (Lithuanian) * ``lv`` (Latvian) +* ``nl`` (Dutch) * ``no`` (Norwegian) * ``pl`` (Polish) * ``pt`` (Portuguese) * ``pt_BR`` (Portuguese - Brazilian) +* ``ro`` (Romanian) +* ``ru`` (Russian) * ``sl`` (Slovene) +* ``sk`` (Slovak) * ``sr`` (Serbian) * ``sv`` (Swedish) -* ``ro`` (Romanian) -* ``ru`` (Russian) * ``te`` (Telugu) * ``tet`` (Tetum) * ``tg`` (Tajik) * ``tr`` (Turkish) * ``th`` (Thai) -* ``vi`` (Vietnamese) -* ``nl`` (Dutch) * ``uk`` (Ukrainian) +* ``vi`` (Vietnamese) You can supply values like ``fr_FR``; if the country doesn't exist but the language does, the code will fall back to the base language (i.e. ``fr``). If @@ -160,4 +164,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 \ No newline at end of file +Virgil Dupras, Savoir-faire Linux diff --git a/bin/num2words b/bin/num2words index 359d1bdb..c6dbd52f 100755 --- a/bin/num2words +++ b/bin/num2words @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.13" +__version__ = "0.5.14" __license__ = "LGPL" diff --git a/num2words/__init__.py b/num2words/__init__.py index c513d853..9e5d44bd 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,25 +17,27 @@ from __future__ import unicode_literals -from . import (lang_AM, lang_AR, lang_AZ, lang_BE, lang_CA, lang_CE, lang_CY, - lang_CZ, lang_DE, lang_DK, lang_EN, lang_EN_IN, lang_EN_NG, - lang_EO, lang_ES, lang_ES_CO, lang_ES_CR, 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_TET, - lang_TG, lang_TH, lang_TR, lang_UK, lang_VI) +from . import (lang_AM, lang_AR, lang_AZ, lang_BE, lang_BN, lang_CA, lang_CE, + lang_CS, lang_CY, lang_DA, lang_DE, lang_EN, lang_EN_IN, + lang_EN_NG, lang_EO, lang_ES, lang_ES_CO, lang_ES_CR, + 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_HI, 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_TET, lang_TG, lang_TH, lang_TR, lang_UK, + lang_VI) CONVERTER_CLASSES = { 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), 'az': lang_AZ.Num2Word_AZ(), 'be': lang_BE.Num2Word_BE(), + 'bn': lang_BN.Num2Word_BN(), 'ca': lang_CA.Num2Word_CA(), 'ce': lang_CE.Num2Word_CE(), + 'cs': lang_CS.Num2Word_CS(), 'cy': lang_CY.Num2Word_CY(), - 'cz': lang_CZ.Num2Word_CZ(), 'en': lang_EN.Num2Word_EN(), 'en_IN': lang_EN_IN.Num2Word_EN_IN(), 'en_NG': lang_EN_NG.Num2Word_EN_NG(), @@ -68,7 +70,7 @@ 'sr': lang_SR.Num2Word_SR(), 'sv': lang_SV.Num2Word_SV(), 'no': lang_NO.Num2Word_NO(), - 'dk': lang_DK.Num2Word_DK(), + 'da': lang_DA.Num2Word_DA(), 'pt': lang_PT.Num2Word_PT(), 'pt_BR': lang_PT_BR.Num2Word_PT_BR(), 'he': lang_HE.Num2Word_HE(), @@ -83,6 +85,7 @@ 'tet': lang_TET.Num2Word_TET(), 'hu': lang_HU.Num2Word_HU(), 'is': lang_IS.Num2Word_IS(), + 'hi': lang_HI.Num2Word_HI(), } CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency'] diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 7195dd47..7813d3aa 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -31,6 +31,8 @@ ("قرش", "قرشان", "قروش", "قرش")] CURRENCY_KWD = [("دينار", "ديناران", "دينارات", "ديناراً"), ("فلس", "فلسان", "فلس", "فلس")] +CURRENCY_TND = [("دينار", "ديناران", "دينارات", "ديناراً"), + ("مليماً", "ميلمان", "مليمات", "مليم")] ARABIC_ONES = [ "", "واحد", "اثنان", "ثلاثة", "أربعة", "خمسة", "ستة", "سبعة", "ثمانية", @@ -352,15 +354,22 @@ def validate_number(self, number): return number def set_currency_prefer(self, currency): - if currency == 'EGP': + if currency == 'TND': + self.currency_unit = CURRENCY_TND[0] + self.currency_subunit = CURRENCY_TND[1] + self.partPrecision = 3 + elif currency == 'EGP': self.currency_unit = CURRENCY_EGP[0] self.currency_subunit = CURRENCY_EGP[1] + self.partPrecision = 2 elif currency == 'KWD': self.currency_unit = CURRENCY_KWD[0] self.currency_subunit = CURRENCY_KWD[1] + self.partPrecision = 2 else: self.currency_unit = CURRENCY_SR[0] self.currency_subunit = CURRENCY_SR[1] + self.partPrecision = 2 def to_currency(self, value, currency='SR', prefix='', suffix=''): self.set_currency_prefer(currency) diff --git a/num2words/lang_BN.py b/num2words/lang_BN.py new file mode 100644 index 00000000..ef86ed71 --- /dev/null +++ b/num2words/lang_BN.py @@ -0,0 +1,203 @@ +# -*- coding: utf-8 -*- +# Author: Mehedi Hasan Khondoker +# Email: mehedihasankhondoker [at] gmail.com +# Copyright (c) 2024, Mehedi Hasan Khondoker. All Rights Reserved. + +# This library is build for Bangladesh format Number to Word conversion. +# You are welcome as contributor to the library. + +# 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. + + +from decimal import Decimal + +RANKING = ['', 'প্রথম', 'দ্বিতীয়', 'তৃতীয়', 'চতুর্থ', 'পঞ্চম', 'ষষ্ঠ', + 'সপ্তম', 'অষ্টম', 'নবম', 'দশম'] # pragma: no cover + +AKOK = ['', 'এক', 'দুই', 'তিন', 'চার', 'পাঁচ', 'ছয়', + 'সাত', 'আট', 'নয়'] # pragma: no cover + +DOSOK = [ + 'দশ', 'এগারো', 'বারো', 'তেরো', 'চৌদ্দ', 'পনের', + 'ষোল', 'সতের', 'আঠারো', 'উনিশ', + 'বিশ', 'একুশ', 'বাইশ', 'তেইশ', 'চব্বিশ', 'পঁচিশ', + 'ছাব্বিশ', 'সাতাশ', 'আটাশ', 'উনত্রিশ', + 'ত্রিশ', 'একত্রিশ', 'বত্রিশ', 'তেত্রিশ', 'চৌত্রিশ', 'পঁইত্রিশ', + 'ছত্রিশ', 'সাতত্রিশ', 'আটত্রিশ', 'উনচল্লিশ', 'চল্লিশ', + 'একচল্লিশ', 'বিয়াল্লিশ', 'তেতাল্লিশ', 'চৌচল্লিশ', + 'পঁয়তাল্লিশ', 'ছেচল্লিশ', 'সাতচল্লিশ', 'আটচল্লিশ', 'উনপঞ্চাশ', + 'পঞ্চাশ', 'একান্ন', 'বাহান্ন', 'তিপ্পান্ন', 'চুয়ান্ন', 'পঞ্চান্ন', + 'ছাপ্পান্ন', 'সাতান্ন', 'আটান্ন', 'উনষাট', 'ষাট', + 'একষট্টি', 'বাষট্টি', 'তেষট্টি', 'চৌষট্টি', 'পঁয়ষট্টি', + 'ছিষট্টি', 'সাতষট্টি', 'আটষট্টি', 'উনসত্তর', 'সত্তর', + 'একাত্তর ', 'বাহাত্তর', 'তিয়াত্তর', 'চুয়াত্তর', 'পঁচাত্তর', + 'ছিয়াত্তর', 'সাতাত্তর', 'আটাত্তর', 'উনআশি', 'আশি', + 'একাশি', 'বিরাশি', 'তিরাশি', 'চুরাশি', 'পঁচাশি', + 'ছিয়াশি', 'সাতাশি', 'আটাশি', 'উননব্বই', 'নব্বই', + 'একানব্বই', 'বিরানব্বই', 'তিরানব্বই', 'চুরানব্বই', 'পঁচানব্বই', + 'ছিয়ানব্বই', 'সাতানব্বই', 'আটানব্বই', 'নিরানব্বই' +] # pragma: no cover +HAZAR = ' হাজার ' # pragma: no cover +LAKH = ' লাখ ' # pragma: no cover +KOTI = ' কোটি ' # pragma: no cover +MAX_NUMBER = 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 # noqa: E501 # pragma: no cover + + +class NumberTooLargeError(Exception): + """Custom exception for numbers that are too large.""" + pass + + +class Num2Word_BN: + + @staticmethod + def str_to_number(number): + return abs(Decimal(str(number))) # pragma: no cover + + @staticmethod + def parse_number(number: Decimal): + dosomik = str(number - int(number)).split('.')[1:] + dosomik_str = ''.join(dosomik) if dosomik else 0 + return int(number), int(dosomik_str) + + @staticmethod + def parse_paisa(number: Decimal): + # 1-99 for paisa count so two digits are valid. + paisa = str(number - int(number)).split('.')[1:] + paisa_str = ''.join(paisa) if paisa else 0 + + # this is need, when we parse to decimal it removes trailing 0 . + if paisa_str: + paisa_str = str(int(paisa_str) * 100)[:2] + return int(number), int(paisa_str) + + def _is_smaller_than_max_number(self, number): + if MAX_NUMBER >= number: + return True + raise NumberTooLargeError(f'Too Large number maximum ' + f'value={MAX_NUMBER}') + + def _dosomik_to_bengali_word(self, number): + word = '' + for i in str(number): + word += ' ' + AKOK[int(i)] + return word + + def _number_to_bengali_word(self, number): + if number == 0: + return 'শূন্য' + + words = '' + + if number >= 10 ** 7: + words += self._number_to_bengali_word(number // 10 ** 7) + KOTI + number %= 10 ** 7 + + if number >= 10 ** 5: + words += self._number_to_bengali_word(number // 10 ** 5) + LAKH + number %= 10 ** 5 + + if number >= 1000: + words += self._number_to_bengali_word(number // 1000) + HAZAR + number %= 1000 + + if number >= 100: + words += AKOK[number // 100] + 'শত ' + number %= 100 + + if 10 <= number <= 99: + words += DOSOK[number - 10] + ' ' + number = 0 + + if 0 < number < 10: + words += AKOK[number] + ' ' + + return words.strip() + + def to_currency(self, val): + """ + This function represent a number to word in bangla taka and paisa. + example: + 1 = এক টাকা, + 101 = একশত এক টাকা, + 9999.15 = নয় হাজার নয়শত নিরানব্বই টাকা পনের পয়সা + and so on. + """ + + dosomik_word = None + number = self.str_to_number(val) + number, decimal_part = self.parse_paisa(number) + self._is_smaller_than_max_number(number) + + if decimal_part > 0: + dosomik_word = f' {self._number_to_bengali_word(decimal_part)} পয়সা' # noqa: E501 + + words = f'{self._number_to_bengali_word(number)} টাকা' + + if dosomik_word: + return (words + dosomik_word).strip() + return words.strip() + + def to_cardinal(self, number): + """ + This function represent a number to word in bangla. + example: + 1 = এক, + 101 = একশত এক, + 9999 = নয় হাজার নয়শত নিরানব্বই + and so on. + """ + + dosomik_word = None + number = self.str_to_number(number) + number, decimal_part = self.parse_number(number) + self._is_smaller_than_max_number(number) + + if decimal_part > 0: + dosomik_word = f' দশমিক{self._dosomik_to_bengali_word(decimal_part)}' # noqa: E501 + + words = self._number_to_bengali_word(number) + + if dosomik_word: + return (words + dosomik_word).strip() + return words.strip() + + def to_ordinal(self, number): + return self.to_cardinal(number) + + def to_ordinal_num(self, number): + """ + This function represent a number to ranking in bangla. + example: + 1 = প্রথম, + 2 = দ্বিতীয়, + 1001 = এক হাজার একতম + and so on. + """ + self._is_smaller_than_max_number(number) + + if number in range(1, 11): + return RANKING[number] + else: + rank = self.to_cardinal(int(abs(number))) + if rank.endswith('ত'): + return rank + 'ম' + return rank + 'তম' + + def to_year(self, number): + """ + This function represent a number to year in bangla. + example: + 2002 = দুই হাজার দুই সাল, + 2024 = দুই হাজার চব্বিশ সাল + and so on. + """ + self._is_smaller_than_max_number(number) + return self.to_cardinal(int(abs(number))) + ' সাল' diff --git a/num2words/lang_CZ.py b/num2words/lang_CS.py similarity index 99% rename from num2words/lang_CZ.py rename to num2words/lang_CS.py index 04c44a07..6024b77d 100644 --- a/num2words/lang_CZ.py +++ b/num2words/lang_CS.py @@ -84,7 +84,7 @@ } -class Num2Word_CZ(Num2Word_Base): +class Num2Word_CS(Num2Word_Base): CURRENCY_FORMS = { 'CZK': ( ('koruna', 'koruny', 'korun'), ('halíř', 'halíře', 'haléřů') diff --git a/num2words/lang_DK.py b/num2words/lang_DA.py similarity index 98% rename from num2words/lang_DK.py rename to num2words/lang_DA.py index 50ab110c..c6607383 100644 --- a/num2words/lang_DK.py +++ b/num2words/lang_DA.py @@ -20,12 +20,12 @@ from . import lang_EU -class Num2Word_DK(lang_EU.Num2Word_EU): +class Num2Word_DA(lang_EU.Num2Word_EU): GIGA_SUFFIX = "illiarder" MEGA_SUFFIX = "illioner" def setup(self): - super(Num2Word_DK, self).setup() + super(Num2Word_DA, self).setup() self.negword = "minus " self.pointword = "komma" diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 0ff74ab2..8579fb60 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -47,7 +47,9 @@ class Num2Word_EU(Num2Word_Base): 'HUF': (('forint', 'forint'), ('fillér', 'fillér')), 'ISK': (('króna', 'krónur'), ('aur', 'aurar')), 'UZS': (('sum', 'sums'), ('tiyin', 'tiyins')), - 'SAR': (('saudi riyal', 'saudi riyals'), ('halalah', 'halalas')) + 'SAR': (('saudi riyal', 'saudi riyals'), ('halalah', 'halalas')), + 'JPY': (('yen', 'yen'), ('sen', 'sen')), + 'KRW': (('won', 'won'), ('jeon', 'jeon')), } @@ -65,7 +67,9 @@ class Num2Word_EU(Num2Word_Base): 'HUF': 'Hungarian', 'ISK': 'íslenskar', 'UZS': 'Uzbekistan', - 'SAR': 'Saudi' + 'SAR': 'Saudi', + 'JPY': 'Japanese', + 'KRW': 'Korean', } GIGA_SUFFIX = "illiard" diff --git a/num2words/lang_HI.py b/num2words/lang_HI.py new file mode 100644 index 00000000..b397f3c4 --- /dev/null +++ b/num2words/lang_HI.py @@ -0,0 +1,199 @@ +# -*- encoding: 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 unicode_literals + +import string + +from num2words.base import Num2Word_Base + + +class Num2Word_HI(Num2Word_Base): + """ + Hindi (HI) Num2Word class + """ + + _irregular_ordinals = { + 0: "शून्य", + 1: "पहला", + 2: "दूसरा", + 3: "तीसरा", + 4: "चौथा", + 6: "छठा", + } + _irregular_ordinals_nums = { + 0: "०", + 1: "१ला", + 2: "२रा", + 3: "३रा", + 4: "४था", + 6: "६ठा", + } + _hindi_digits = "०१२३४५६७८९" # 0-9 + _digits_to_hindi_digits = dict(zip(string.digits, _hindi_digits)) + _regular_ordinal_suffix = "वाँ" + + def setup(self): + # Note: alternative forms are informal + self.low_numwords = [ + "निन्यानवे", + "अट्ठानवे", + "सत्तानवे", # alternative "सतानवे" + "छियानवे", + "पचानवे", + "चौरानवे", + "तिरानवे", + "बानवे", + "इक्यानवे", + "नब्बे", + "नवासी", + "अट्ठासी", + "सतासी", + "छियासी", + "पचासी", + "चौरासी", + "तिरासी", + "बयासी", + "इक्यासी", + "अस्सी", + "उनासी", # alternative "उन्नासी" + "अठहत्तर", # alternative "अठहतर" + "सतहत्तर", # alternative "सतहतर" + "छिहत्तर", # alternative "छिहतर" + "पचहत्तर", # alternative "पचहतर" + "चौहत्तर", # alternative "चौहतर" + "तिहत्तर", # alternative "तिहतर" + "बहत्तर", # alternative "बहतर" + "इकहत्तर", # alternative "इकहतर" + "सत्तर", + "उनहत्तर", # alternative "उनहतर" + "अड़सठ", # alternative "अड़सठ" + "सड़सठ", # alternative "सड़सठ" + "छियासठ", + "पैंसठ", + "चौंसठ", + "तिरसठ", + "बासठ", + "इकसठ", + "साठ", + "उनसठ", + "अट्ठावन", # alternative "अठावन" + "सत्तावन", # alternative "सतावन" + "छप्पन", + "पचपन", + "चौवन", + "तिरेपन", # alternative "तिरपन" + "बावन", + "इक्यावन", + "पचास", + "उनचास", + "अड़तालीस", # alternative "अड़तालीस" + "सैंतालीस", + "छियालीस", # alternative "छयालिस" + "पैंतालीस", + "चौवालीस", # alternative "चवालीस" + "तैंतालीस", # alternative "तैतालीस" + "बयालीस", + "इकतालीस", + "चालीस", + "उनतालीस", + "अड़तीस", # alternative "अड़तीस" + "सैंतीस", + "छत्तीस", # alternative "छतीस" + "पैंतीस", + "चौंतीस", + "तैंतीस", + "बत्तीस", # alternative "बतीस" + "इकत्तीस", # alternative "इकतीस" + "तीस", + "उनतीस", + "अट्ठाईस", # alternative "अट्ठाइस" + "सत्ताईस", # alternative "सताइस" + "छब्बीस", + "पच्चीस", + "चौबीस", + "तेईस", # alternative "तेइस" + "बाईस", + "इक्कीस", # alternative "इकीस" + "बीस", + "उन्नीस", + "अट्ठारह", # alternative "अठारह" + "सत्रह", + "सोलह", + "पंद्रह", + "चौदह", + "तेरह", + "बारह", + "ग्यारह", + "दस", + "नौ", + "आठ", + "सात", + "छः", # alternative "छह" + "पाँच", # alternative "पांच" + "चार", + "तीन", + "दो", + "एक", + "शून्य", + ] + + self.mid_numwords = [(100, "सौ")] + self.high_numwords = [ + (11, "ख़रब"), + (9, "अरब"), + (7, "करोड़"), # alternative "करोड़" + (5, "लाख"), + (3, "हज़ार"), # alternative "हज़ार" + ] + self.pointword = "दशमलव" + self.negword = "माइनस " + + def set_high_numwords(self, high): + for n, word in self.high_numwords: + self.cards[10**n] = word + + def merge(self, lpair, rpair): + ltext, lnum = lpair + rtext, rnum = rpair + if lnum == 1 and rnum < 100: + return rtext, 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): + if value in self._irregular_ordinals: + return self._irregular_ordinals[value] + + # regular Hindi ordinals are derived from cardinals + # by modifying the last member of the expression. + cardinal = self.to_cardinal(value) + return cardinal + self._regular_ordinal_suffix + + def _convert_to_hindi_numerals(self, value): + return "".join(map(self._digits_to_hindi_digits.__getitem__, + str(value))) + + def to_ordinal_num(self, value): + if value in self._irregular_ordinals_nums: + return self._irregular_ordinals_nums[value] + + return self._convert_to_hindi_numerals(value) \ + + self._regular_ordinal_suffix diff --git a/setup.py b/setup.py index 4ca9fda6..df9c30ba 100644 --- a/setup.py +++ b/setup.py @@ -27,12 +27,12 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: GNU Library or Lesser General Public License ' '(LGPL)', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Software Development :: Internationalization', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Localization', diff --git a/tests/test_ar.py b/tests/test_ar.py index 91e648a6..5781db52 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -66,6 +66,12 @@ def test_currency_parm(self): self.assertEqual( num2words(1000000.99, to='currency', lang='ar', currency="KWD"), 'مليون دينار و تسع و تسعون فلس') + self.assertEqual( + num2words(1000.42, to='currency', lang='ar', currency="TND"), + 'ألف دينار و أربعمائة و عشرون مليم') + self.assertEqual( + num2words(123.21, to='currency', lang='ar', currency="TND"), + 'مائة و ثلاثة و عشرون ديناراً و مئتان و عشر مليمات') def test_ordinal(self): diff --git a/tests/test_base.py b/tests/test_base.py index 9169a40a..c9abe14d 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -65,4 +65,24 @@ def test_is_title(self): def test_set_high_numwords_not_implemented(self): with self.assertRaises(NotImplementedError): - self.base.set_high_numwords(['cent', 'novemnonagint']) + self.base.set_high_numwords() + + def test_to_ordinal_num(self): + from num2words.base import Num2Word_Base + self.base = Num2Word_Base() + self.assertEqual( + self.base.to_ordinal_num(1), + 1 + ) + self.assertEqual( + self.base.to_ordinal_num(100), + 100 + ) + self.assertEqual( + self.base.to_ordinal_num(1000), + 1000 + ) + + def test_pluralize_not_implemented(self): + with self.assertRaises(NotImplementedError): + self.base.pluralize(n=None, forms=None) diff --git a/tests/test_bn.py b/tests/test_bn.py new file mode 100644 index 00000000..9147916c --- /dev/null +++ b/tests/test_bn.py @@ -0,0 +1,365 @@ +# -*- coding: utf-8 -*- +# Author: Mehedi Hasan Khondoker +# Email: mehedihasankhondoker [at] gmail.com +# Copyright (c) 2024, Mehedi Hasan Khondoker. All Rights Reserved. + +# This library is build for Bangladesh format Number to Word conversion. +# You are welcome as contributor to the library. + +# 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. + +from __future__ import unicode_literals + +from decimal import Decimal +from unittest import TestCase + +from num2words import num2words +from num2words.lang_BN import Num2Word_BN, NumberTooLargeError + + +class Num2WordsBNTest(TestCase): + maxDiff = None + + def test_negative(self): + self.assertEqual(num2words(-1, lang="bn"), u'এক') + + def test_0(self): + self.assertEqual(num2words(0, lang="bn"), u'শূন্য') + + def test_1_to_10(self): + self.assertEqual(num2words(1, lang="bn"), u'এক') + self.assertEqual(num2words(2, lang="bn"), u'দুই') + self.assertEqual(num2words(7, lang="bn"), u'সাত') + self.assertEqual(num2words(10, lang="bn"), u'দশ') + + def test_11_to_19(self): + self.assertEqual(num2words(11, lang="bn"), u'এগারো') + self.assertEqual(num2words(13, lang="bn"), u'তেরো') + self.assertEqual(num2words(15, lang="bn"), u'পনের') + self.assertEqual(num2words(16, lang="bn"), u'ষোল') + self.assertEqual(num2words(19, lang="bn"), u'উনিশ') + + def test_20_to_99(self): + self.assertEqual(num2words(20, lang="bn"), u'বিশ') + self.assertEqual(num2words(23, lang="bn"), u'তেইশ') + self.assertEqual(num2words(28, lang="bn"), u'আটাশ') + self.assertEqual(num2words(31, lang="bn"), u'একত্রিশ') + self.assertEqual(num2words(40, lang="bn"), u'চল্লিশ') + self.assertEqual(num2words(66, lang="bn"), u'ছিষট্টি') + self.assertEqual(num2words(92, lang="bn"), u'বিরানব্বই') + + def test_100_to_999(self): + self.assertEqual(num2words(100, lang="bn"), u'একশত') + self.assertEqual(num2words(111, lang="bn"), u'একশত এগারো') + self.assertEqual(num2words(150, lang="bn"), u'একশত পঞ্চাশ') + self.assertEqual(num2words(196, lang="bn"), u'একশত ছিয়ানব্বই') + self.assertEqual(num2words(200, lang="bn"), u'দুইশত') + self.assertEqual(num2words(210, lang="bn"), u'দুইশত দশ') + self.assertEqual(num2words(701, lang="bn"), u'সাতশত এক') + self.assertEqual(num2words(999, lang="bn"), u'নয়শত নিরানব্বই') + + def test_1000_to_9999(self): + self.assertEqual(num2words(1000, lang="bn"), u'এক হাজার') + self.assertEqual(num2words(1001, lang="bn"), u'এক হাজার এক') + self.assertEqual(num2words(1002, lang="bn"), u'এক হাজার দুই') + self.assertEqual(num2words(1010, lang="bn"), u'এক হাজার দশ') + self.assertEqual(num2words(1110, lang="bn"), u'এক হাজার একশত দশ') + self.assertEqual(num2words(1111, lang="bn"), u'এক হাজার একশত এগারো') + self.assertEqual(num2words(1500, lang="bn"), u'এক হাজার পাঁচশত') + self.assertEqual(num2words(2000, lang="bn"), u'দুই হাজার') + self.assertEqual(num2words(2042, lang="bn"), u'দুই হাজার বিয়াল্লিশ') + self.assertEqual(num2words(3000, lang="bn"), u'তিন হাজার') + self.assertEqual(num2words(3301, lang="bn"), u'তিন হাজার তিনশত এক') + self.assertEqual(num2words(3108, lang="bn"), u'তিন হাজার একশত আট') + self.assertEqual(num2words(6870, lang="bn"), u'ছয় হাজার আটশত সত্তর') + self.assertEqual(num2words(7378, lang="bn"), + u'সাত হাজার তিনশত আটাত্তর') + self.assertEqual(num2words(9999, lang="bn"), + u'নয় হাজার নয়শত নিরানব্বই') + + def test_10000_to_99999(self): + self.assertEqual(num2words(10000, lang="bn"), + u'দশ হাজার') + self.assertEqual(num2words(10501, lang="bn"), + u'দশ হাজার পাঁচশত এক') + self.assertEqual(num2words(10999, lang="bn"), + u'দশ হাজার নয়শত নিরানব্বই') + self.assertEqual(num2words(13000, lang="bn"), u'তেরো হাজার') + self.assertEqual(num2words(15333, lang="bn"), + u'পনের হাজার তিনশত তেত্রিশ') + self.assertEqual(num2words(21111, lang="bn"), u'একুশ হাজার একশত এগারো') + self.assertEqual(num2words(21003, lang="bn"), u'একুশ হাজার তিন') + self.assertEqual(num2words(25020, lang="bn"), u'পঁচিশ হাজার বিশ') + self.assertEqual(num2words(68700, lang="bn"), + u'আটষট্টি হাজার সাতশত') + self.assertEqual(num2words(73781, lang="bn"), + u'তিয়াত্তর হাজার সাতশত একাশি') + self.assertEqual(num2words(99999, lang="bn"), + u'নিরানব্বই হাজার নয়শত নিরানব্বই') + + def test_100000_to_999999(self): + self.assertEqual(num2words(100000, lang="bn"), u'এক লাখ') + self.assertEqual(num2words('100000', lang="bn"), u'এক লাখ') + self.assertEqual(num2words(199999, lang="bn"), + u'এক লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') + self.assertEqual(num2words(110000, lang="bn"), u'এক লাখ দশ হাজার') + self.assertEqual(num2words(150010, lang="bn"), + u'এক লাখ পঞ্চাশ হাজার দশ') + self.assertEqual(num2words('200200', lang="bn"), u'দুই লাখ দুইশত') + self.assertEqual(num2words(737812, lang="bn"), + u'সাত লাখ সাতত্রিশ হাজার আটশত বারো') + self.assertEqual(num2words('999999', lang="bn"), + u'নয় লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') + + def test_1000000_to_9999999999999999(self): + self.assertEqual(num2words(1000000, lang="bn"), u'দশ লাখ') + self.assertEqual(num2words(20000000, lang="bn"), u'দুই কোটি') + self.assertEqual(num2words(300000000, lang="bn"), u'ত্রিশ কোটি') + self.assertEqual(num2words(4000000000, lang="bn"), u'চারশত কোটি') + self.assertEqual(num2words(50000000000, lang="bn"), u'পাঁচ হাজার কোটি') + self.assertEqual(num2words(600000000000, lang="bn"), u'ষাট হাজার কোটি') + self.assertEqual(num2words(7000000000000, lang="bn"), u'সাত লাখ কোটি') + self.assertEqual(num2words(80000000000000, lang="bn"), u'আশি লাখ কোটি') + self.assertEqual(num2words + (900000000000000, lang="bn"), u'নয় কোটি কোটি') + self.assertEqual(num2words(999999999999999, lang="bn"), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') # noqa: E501 + self.assertEqual(num2words(9999999999999999, lang="bn"), + u'নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই') # noqa: E501 + + def test_dosomik_0_to_999999999999999999(self): + self.assertEqual(num2words(0.56, lang="bn"), u'শূন্য দশমিক পাঁচ ছয়') + self.assertEqual(num2words(1.11, lang="bn"), u'এক দশমিক এক এক') + self.assertEqual(num2words(2.66, lang="bn"), u'দুই দশমিক ছয় ছয়') + self.assertEqual(num2words(7.68, lang="bn"), u'সাত দশমিক ছয় আট') + self.assertEqual(num2words('10.35', lang="bn"), u'দশ দশমিক তিন পাঁচ') + self.assertEqual(num2words('11.47', lang="bn"), u'এগারো দশমিক চার সাত') + self.assertEqual(num2words(13.69, lang="bn"), u'তেরো দশমিক ছয় নয়') + self.assertEqual(num2words(15.96, lang="bn"), u'পনের দশমিক নয় ছয়') + self.assertEqual(num2words(16.9999, lang="bn"), + u'ষোল দশমিক নয় নয় নয় নয়') + self.assertEqual(num2words(19.56587, lang="bn"), + u'উনিশ দশমিক পাঁচ ছয় পাঁচ আট সাত') + self.assertEqual(num2words(31.31, lang="bn"), u'একত্রিশ দশমিক তিন এক') + self.assertEqual(num2words(40.85, lang="bn"), u'চল্লিশ দশমিক আট পাঁচ') + self.assertEqual(num2words(66.66, lang="bn"), u'ছিষট্টি দশমিক ছয় ছয়') + self.assertEqual(num2words(92.978, lang="bn"), + u'বিরানব্বই দশমিক নয় সাত আট') + self.assertEqual(num2words(1000001.10, lang="bn"), + u'দশ লাখ এক দশমিক এক') + self.assertEqual(num2words(20000000.22, lang="bn"), + u'দুই কোটি দশমিক দুই দুই') + self.assertEqual(num2words(300030000.33, lang="bn"), + u'ত্রিশ কোটি ত্রিশ হাজার দশমিক তিন তিন') + self.assertEqual(num2words('4004000444.44', lang="bn"), + u'চারশত কোটি চল্লিশ লাখ চারশত চৌচল্লিশ দশমিক চার চার') + self.assertEqual(num2words(50000000001.50, lang="bn"), + u'পাঁচ হাজার কোটি এক দশমিক পাঁচ') + self.assertEqual(num2words(600000000600.66, lang="bn"), + u'ষাট হাজার কোটি ছয়শত দশমিক ছয় ছয়') + self.assertEqual(num2words(7000000000000.77, lang="bn"), + u'সাত লাখ কোটি দশমিক সাত সাত') + self.assertEqual(num2words(80000000000888.88, lang="bn"), + u'আশি লাখ কোটি আটশত আটাশি দশমিক আট আট') + self.assertEqual(num2words(900000000000000.9, lang="bn"), + u'নয় কোটি কোটি দশমিক নয়') + self.assertEqual(num2words(999999999999999.9, lang="bn"), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + self.assertEqual(num2words(9999999999999999.99, lang="bn"), + u'একশত কোটি কোটি') + self.assertEqual(num2words(99999999999999999.99, lang="bn"), + u'এক হাজার কোটি কোটি') + self.assertEqual(num2words('999999999999999999.9', lang="bn"), + u'নয় হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + + def test_to_currency(self): + n = Num2Word_BN() + self.assertEqual(n.to_currency(20.0), u'বিশ টাকা') + self.assertEqual(n.to_currency(20.50), u'বিশ টাকা পঞ্চাশ পয়সা') + self.assertEqual(n.to_currency(33.51), u'তেত্রিশ টাকা একান্ন পয়সা') + self.assertEqual(n.to_currency(99.99), + u'নিরানব্বই টাকা নিরানব্বই পয়সা') + self.assertEqual(n.to_currency(10000.1), + u'দশ হাজার টাকা দশ পয়সা') + self.assertEqual(n.to_currency(555555.50), + u'পাঁচ লাখ পঞ্চান্ন হাজার পাঁচশত পঞ্চান্ন টাকা পঞ্চাশ পয়সা') # noqa: E501 + self.assertEqual(n.to_currency(6666676), + u'ছিষট্টি লাখ ছিষট্টি হাজার ছয়শত ছিয়াত্তর টাকা') + self.assertEqual(n.to_currency(777777777), + u'সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত সাতাত্তর টাকা') # noqa: E501 + self.assertEqual(n.to_currency(7777777778), + u'সাতশত সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত আটাত্তর টাকা') # noqa: E501 + self.assertEqual(n.to_currency(97777777778), + u'নয় হাজার সাতশত সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত আটাত্তর টাকা') # noqa: E501 + self.assertEqual(n.to_currency(977777777781), + u'সাতানব্বই হাজার সাতশত সাতাত্তর কোটি সাতাত্তর লাখ সাতাত্তর হাজার সাতশত একাশি টাকা') # noqa: E501 + self.assertEqual(n.to_currency(9777777779781), + u'নয় লাখ সাতাত্তর হাজার সাতশত সাতাত্তর কোটি সাতাত্তর লাখ উনআশি হাজার সাতশত একাশি টাকা') # noqa: E501 + + def test_to_cardinal(self): + n = Num2Word_BN() + self.assertEqual(n.to_cardinal(0.56), u'শূন্য দশমিক পাঁচ ছয়') + self.assertEqual(n.to_cardinal(1.11), u'এক দশমিক এক এক') + self.assertEqual(n.to_cardinal(2.66), u'দুই দশমিক ছয় ছয়') + self.assertEqual(n.to_cardinal(7.68), u'সাত দশমিক ছয় আট') + self.assertEqual(n.to_cardinal('10.35'), u'দশ দশমিক তিন পাঁচ') + self.assertEqual(n.to_cardinal('11.47'), u'এগারো দশমিক চার সাত') + self.assertEqual(n.to_cardinal(13.69), u'তেরো দশমিক ছয় নয়') + self.assertEqual(n.to_cardinal(15.96), u'পনের দশমিক নয় ছয়') + self.assertEqual(n.to_cardinal(16.9999), u'ষোল দশমিক নয় নয় নয় নয়') + self.assertEqual(n.to_cardinal(19.56587), + u'উনিশ দশমিক পাঁচ ছয় পাঁচ আট সাত') + self.assertEqual(n.to_cardinal(31.31), u'একত্রিশ দশমিক তিন এক') + self.assertEqual(n.to_cardinal(40.85), u'চল্লিশ দশমিক আট পাঁচ') + self.assertEqual(n.to_cardinal(66.66), u'ছিষট্টি দশমিক ছয় ছয়') + self.assertEqual(n.to_cardinal(92.978), u'বিরানব্বই দশমিক নয় সাত আট') + self.assertEqual(n.to_cardinal(1000001.10), u'দশ লাখ এক দশমিক এক') + self.assertEqual(n.to_cardinal(20000000.22), u'দুই কোটি দশমিক দুই দুই') + self.assertEqual(n.to_cardinal(300030000.33), + u'ত্রিশ কোটি ত্রিশ হাজার দশমিক তিন তিন') + self.assertEqual(n.to_cardinal('4004000444.44'), + u'চারশত কোটি চল্লিশ লাখ চারশত চৌচল্লিশ দশমিক চার চার') + self.assertEqual(n.to_cardinal(50000000001.50), + u'পাঁচ হাজার কোটি এক দশমিক পাঁচ') + self.assertEqual(n.to_cardinal(600000000600.66), + u'ষাট হাজার কোটি ছয়শত দশমিক ছয় ছয়') + self.assertEqual(n.to_cardinal(7000000000000.77), + u'সাত লাখ কোটি দশমিক সাত সাত') + self.assertEqual(n.to_cardinal(80000000000888.88), + u'আশি লাখ কোটি আটশত আটাশি দশমিক আট আট') + self.assertEqual(n.to_cardinal(900000000000000.9), + u'নয় কোটি কোটি দশমিক নয়') + self.assertEqual(n.to_cardinal(999999999999999.9), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + self.assertEqual(n.to_cardinal(9999999999999999.99), + u'একশত কোটি কোটি') + self.assertEqual(n.to_cardinal(99999999999999999.99), + u'এক হাজার কোটি কোটি') + self.assertEqual(n.to_cardinal('999999999999999999.99'), + u'নয় হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয় নয়') # noqa: E501 + + def test_to_ordinal(self): + n = Num2Word_BN() + self.assertEqual(n.to_ordinal(0.56), u'শূন্য দশমিক পাঁচ ছয়') + self.assertEqual(n.to_ordinal(1.11), u'এক দশমিক এক এক') + self.assertEqual(n.to_ordinal(2.66), u'দুই দশমিক ছয় ছয়') + self.assertEqual(n.to_ordinal(7.68), u'সাত দশমিক ছয় আট') + self.assertEqual(n.to_ordinal('10.35'), u'দশ দশমিক তিন পাঁচ') + self.assertEqual(n.to_ordinal('11.47'), u'এগারো দশমিক চার সাত') + self.assertEqual(n.to_ordinal(13.69), u'তেরো দশমিক ছয় নয়') + self.assertEqual(n.to_ordinal(15.96), u'পনের দশমিক নয় ছয়') + self.assertEqual(n.to_ordinal(16.9999), u'ষোল দশমিক নয় নয় নয় নয়') + self.assertEqual(n.to_ordinal(19.56587), + u'উনিশ দশমিক পাঁচ ছয় পাঁচ আট সাত') + self.assertEqual(n.to_ordinal(31.31), u'একত্রিশ দশমিক তিন এক') + self.assertEqual(n.to_ordinal(40.85), u'চল্লিশ দশমিক আট পাঁচ') + self.assertEqual(n.to_ordinal(66.66), u'ছিষট্টি দশমিক ছয় ছয়') + self.assertEqual(n.to_ordinal(92.978), u'বিরানব্বই দশমিক নয় সাত আট') + self.assertEqual(n.to_ordinal(1000001.10), u'দশ লাখ এক দশমিক এক') + self.assertEqual(n.to_ordinal(20000000.22), u'দুই কোটি দশমিক দুই দুই') + self.assertEqual(n.to_ordinal(300030000.33), + u'ত্রিশ কোটি ত্রিশ হাজার দশমিক তিন তিন') + self.assertEqual(n.to_ordinal('4004000444.44'), + u'চারশত কোটি চল্লিশ লাখ চারশত চৌচল্লিশ দশমিক চার চার') + self.assertEqual(n.to_ordinal(50000000001.50), + u'পাঁচ হাজার কোটি এক দশমিক পাঁচ') + self.assertEqual(n.to_ordinal(600000000600.66), + u'ষাট হাজার কোটি ছয়শত দশমিক ছয় ছয়') + self.assertEqual(n.to_ordinal(7000000000000.77), + u'সাত লাখ কোটি দশমিক সাত সাত') + self.assertEqual(n.to_ordinal(80000000000888.88), + u'আশি লাখ কোটি আটশত আটাশি দশমিক আট আট') + self.assertEqual(n.to_ordinal(900000000000000.9), + u'নয় কোটি কোটি দশমিক নয়') + self.assertEqual(n.to_ordinal(999999999999999.9), + u'নয় কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয়') # noqa: E501 + self.assertEqual(n.to_ordinal(9999999999999999.99), + u'একশত কোটি কোটি') + self.assertEqual(n.to_ordinal(99999999999999999.99), + u'এক হাজার কোটি কোটি') + self.assertEqual(n.to_ordinal('999999999999999999.99'), + u'নয় হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই দশমিক নয় নয়') # noqa: E501 + + def test_to_year(self): + n = Num2Word_BN() + self.assertEqual(n.to_year(1), u'এক সাল') + self.assertEqual(n.to_year(1000), u'এক হাজার সাল') + self.assertEqual(n.to_year(1500), u'এক হাজার পাঁচশত সাল') + self.assertEqual(n.to_year(1820), u'এক হাজার আটশত বিশ সাল') + self.assertEqual(n.to_year(1920), u'এক হাজার নয়শত বিশ সাল') + self.assertEqual(n.to_year(2024), u'দুই হাজার চব্বিশ সাল') + self.assertEqual(n.to_year(2004), u'দুই হাজার চার সাল') + + def test_to_ordinal_num(self): + n = Num2Word_BN() + self.assertEqual(n.to_ordinal_num(1), u'প্রথম') + self.assertEqual(n.to_ordinal_num(1000), u'এক হাজারতম') + self.assertEqual(n.to_ordinal_num(1500), u'এক হাজার পাঁচশতম') + self.assertEqual(n.to_ordinal_num(1820), u'এক হাজার আটশত বিশতম') + self.assertEqual(n.to_ordinal_num(1920), u'এক হাজার নয়শত বিশতম') + self.assertEqual(n.to_ordinal_num(2024), u'দুই হাজার চব্বিশতম') + self.assertEqual(n.to_ordinal_num(2004), u'দুই হাজার চারতম') + + def test_max_number_error(self): + n = Num2Word_BN() + + with self.assertRaises(NumberTooLargeError): + n.to_ordinal( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_cardinal( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_year( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_ordinal_num( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + n.to_currency( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991) # noqa: E501 + + with self.assertRaises(NumberTooLargeError): + num2words( + 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999991, # noqa: E501 + lang="bn") + + def test_is_smaller_than_max_number(self): + n = Num2Word_BN() + self.assertEqual(n._is_smaller_than_max_number(55555), True) + + def test_is_smaller_than_max_number_error(self): + with self.assertRaises(NumberTooLargeError): + n = Num2Word_BN() + n._is_smaller_than_max_number(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999) # noqa: E501 + + def test_parse_number(self): + n = Num2Word_BN() + self.assertEqual(n.parse_number(Decimal(3.25)), (3, 25)) + self.assertEqual(n.parse_number(Decimal(300.2550)), + (300, 2549999999999954525264911353588104248046875)) + + def test_parse_paisa(self): + n = Num2Word_BN() + self.assertEqual(n.parse_paisa(Decimal(3.25)), (3, 25)) + self.assertEqual(n.parse_paisa(300.2550), (300, 25)) + self.assertEqual(n.parse_paisa(100.5), (100, 50)) + + def test_number_to_bengali_word(self): + n = Num2Word_BN() + self.assertEqual(n._number_to_bengali_word(3), "তিন") + self.assertEqual(n._number_to_bengali_word(2550), + "দুই হাজার পাঁচশত পঞ্চাশ") + self.assertEqual(n._number_to_bengali_word(9999999999999999), + "নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই কোটি নিরানব্বই লাখ নিরানব্বই হাজার নয়শত নিরানব্বই") # noqa: E501 diff --git a/tests/test_cz.py b/tests/test_cs.py similarity index 72% rename from tests/test_cz.py rename to tests/test_cs.py index 1801e8f7..2c2b0e5f 100644 --- a/tests/test_cz.py +++ b/tests/test_cs.py @@ -22,39 +22,39 @@ from num2words import num2words -class Num2WordsCZTest(TestCase): +class Num2WordsCSTest(TestCase): def test_cardinal(self): - self.assertEqual(num2words(100, lang='cz'), "sto") - self.assertEqual(num2words(101, lang='cz'), "sto jedna") - self.assertEqual(num2words(110, lang='cz'), "sto deset") - self.assertEqual(num2words(115, lang='cz'), "sto patnáct") - self.assertEqual(num2words(123, lang='cz'), "sto dvacet tři") - self.assertEqual(num2words(1000, lang='cz'), "tisíc") - self.assertEqual(num2words(1001, lang='cz'), "tisíc jedna") - self.assertEqual(num2words(2012, lang='cz'), "dva tisíce dvanáct") - self.assertEqual( - num2words(10.02, lang='cz'), + self.assertEqual(num2words(100, lang='cs'), "sto") + self.assertEqual(num2words(101, lang='cs'), "sto jedna") + self.assertEqual(num2words(110, lang='cs'), "sto deset") + self.assertEqual(num2words(115, lang='cs'), "sto patnáct") + self.assertEqual(num2words(123, lang='cs'), "sto dvacet tři") + self.assertEqual(num2words(1000, lang='cs'), "tisíc") + self.assertEqual(num2words(1001, lang='cs'), "tisíc jedna") + self.assertEqual(num2words(2012, lang='cs'), "dva tisíce dvanáct") + self.assertEqual( + num2words(10.02, lang='cs'), "deset celá nula dva" ) self.assertEqual( - num2words(15.007, lang='cz'), + num2words(15.007, lang='cs'), "patnáct celá nula nula sedm" ) self.assertEqual( - num2words(12519.85, lang='cz'), + num2words(12519.85, lang='cs'), "dvanáct tisíc pětset devatenáct celá osmdesát pět" ) self.assertEqual( - num2words(123.50, lang='cz'), + num2words(123.50, lang='cs'), "sto dvacet tři celá pět" ) self.assertEqual( - num2words(1234567890, lang='cz'), + num2words(1234567890, lang='cs'), "miliarda dvěstě třicet čtyři miliony pětset šedesát " "sedm tisíc osmset devadesát" ) self.assertEqual( - num2words(215461407892039002157189883901676, lang='cz'), + num2words(215461407892039002157189883901676, lang='cs'), "dvěstě patnáct quintillionů čtyřista šedesát jedna kvadriliard " "čtyřista sedm kvadrilionů osmset devadesát dva triliardy třicet " "devět trilionů dva biliardy sto padesát sedm bilionů sto " @@ -62,7 +62,7 @@ def test_cardinal(self): "devětset jedna tisíc šestset sedmdesát šest" ) self.assertEqual( - num2words(719094234693663034822824384220291, lang='cz'), + num2words(719094234693663034822824384220291, lang='cs'), "sedmset devatenáct quintillionů devadesát " "čtyři kvadriliardy dvěstě třicet čtyři " "kvadriliony šestset devadesát tři triliardy " @@ -75,40 +75,40 @@ def test_cardinal(self): def test_to_ordinal(self): # @TODO: implement to_ordinal with self.assertRaises(NotImplementedError): - num2words(1, lang='cz', to='ordinal') + num2words(1, lang='cs', to='ordinal') def test_currency(self): self.assertEqual( - num2words(10.0, lang='cz', to='currency', currency='EUR'), + num2words(10.0, lang='cs', to='currency', currency='EUR'), "deset euro, nula centů") self.assertEqual( - num2words(1.0, lang='cz', to='currency', currency='CZK'), + num2words(1.0, lang='cs', to='currency', currency='CZK'), "jedna koruna, nula haléřů") self.assertEqual( - num2words(1234.56, lang='cz', to='currency', currency='EUR'), + num2words(1234.56, lang='cs', to='currency', currency='EUR'), "tisíc dvěstě třicet čtyři euro, padesát šest centů") self.assertEqual( - num2words(1234.56, lang='cz', to='currency', currency='CZK'), + num2words(1234.56, lang='cs', to='currency', currency='CZK'), "tisíc dvěstě třicet čtyři koruny, padesát šest haléřů") self.assertEqual( - num2words(101.11, lang='cz', to='currency', currency='EUR', + num2words(101.11, lang='cs', to='currency', currency='EUR', separator=' a'), "sto jedna euro a jedenáct centů") self.assertEqual( - num2words(101.21, lang='cz', to='currency', currency='CZK', + num2words(101.21, lang='cs', to='currency', currency='CZK', separator=' a'), "sto jedna korun a dvacet jedna haléřů" ) self.assertEqual( - num2words(-12519.85, lang='cz', to='currency', cents=False), + num2words(-12519.85, lang='cs', to='currency', cents=False), "mínus dvanáct tisíc pětset devatenáct euro, 85 centů" ) self.assertEqual( - num2words(123.50, lang='cz', to='currency', currency='CZK', + num2words(123.50, lang='cs', to='currency', currency='CZK', separator=' a'), "sto dvacet tři koruny a padesát haléřů" ) self.assertEqual( - num2words(19.50, lang='cz', to='currency', cents=False), + num2words(19.50, lang='cs', to='currency', cents=False), "devatenáct euro, 50 centů" ) diff --git a/tests/test_dk.py b/tests/test_da.py similarity index 54% rename from tests/test_dk.py rename to tests/test_da.py index 889e9d8e..3e1b4eba 100644 --- a/tests/test_dk.py +++ b/tests/test_da.py @@ -20,18 +20,26 @@ from unittest import TestCase from num2words import num2words +from num2words.lang_DA import Num2Word_DA class Num2WordsDKTest(TestCase): def test_ordinal(self): - self.assertEqual(num2words(1, to="ordinal", lang="dk"), "første") - self.assertEqual(num2words(5, to="ordinal", lang="dk"), "femte") + self.assertEqual(num2words(1, to="ordinal", lang="da"), "første") + self.assertEqual(num2words(5, to="ordinal", lang="da"), "femte") def test_cardinal(self): - self.assertEqual(num2words(0, to="cardinal", lang="dk"), "nul") - self.assertEqual(num2words(1, to="cardinal", lang="dk"), "et") - self.assertEqual(num2words(2, to="cardinal", lang="dk"), "to") - self.assertEqual(num2words(5, to="cardinal", lang="dk"), "fem") - self.assertEqual(num2words(8, to="cardinal", lang="dk"), "otte") - self.assertEqual(num2words(18, to="cardinal", lang="dk"), "atten") - self.assertEqual(num2words(45, to="cardinal", lang="dk"), "femogfyrre") + self.assertEqual(num2words(0, to="cardinal", lang="da"), "nul") + self.assertEqual(num2words(1, to="cardinal", lang="da"), "et") + self.assertEqual(num2words(2, to="cardinal", lang="da"), "to") + self.assertEqual(num2words(5, to="cardinal", lang="da"), "fem") + self.assertEqual(num2words(8, to="cardinal", lang="da"), "otte") + self.assertEqual(num2words(18, to="cardinal", lang="da"), "atten") + self.assertEqual(num2words(45, to="cardinal", lang="da"), "femogfyrre") + + def test_to_ordinal_num(self): + num2words_dk = Num2Word_DA() + self.assertEqual(num2words_dk.to_ordinal_num(1), "1te") + self.assertEqual(num2words_dk.to_ordinal_num(2), "2en") + self.assertEqual(num2words_dk.to_ordinal_num(5), "5te") + self.assertEqual(num2words_dk.to_ordinal_num(10), "10ende") diff --git a/tests/test_en.py b/tests/test_en.py index e763841c..4ab267c6 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -137,6 +137,18 @@ def test_to_currency(self): "two thousand sums and zero tiyins" ) + self.assertEqual( + num2words('2000.00', lang='en', to='currency', separator=' and', + cents=True, currency='JPY'), + "two thousand yen and zero sen" + ) + + self.assertEqual( + num2words('2000.00', lang='en', to='currency', separator=' and', + cents=True, currency='KRW'), + "two thousand won and zero jeon" + ) + def test_to_year(self): # issue 141 # "e2 e2" diff --git a/tests/test_hi.py b/tests/test_hi.py new file mode 100644 index 00000000..9a23e586 --- /dev/null +++ b/tests/test_hi.py @@ -0,0 +1,301 @@ +# -*- 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 + +# number, hindi number, pronounced form +TEST_CASES_CARDINAL = ( + (0, u"०", u"शून्य"), + (1, u"१", u"एक"), + (2, u"२", u"दो"), + (3, u"३", u"तीन"), + (4, u"४", u"चार"), + (5, u"५", u"पाँच"), + (6, u"६", u"छः"), + (7, u"७", u"सात"), + (8, u"८", u"आठ"), + (9, u"९", u"नौ"), + (10, u"१०", u"दस"), + (11, u"११", u"ग्यारह"), + (12, u"१२", u"बारह"), + (13, u"१३", u"तेरह"), + (14, u"१४", u"चौदह"), + (15, u"१५", u"पंद्रह"), + (16, u"१६", u"सोलह"), + (17, u"१७", u"सत्रह"), + (18, u"१८", u"अट्ठारह"), + (19, u"१९", u"उन्नीस"), + (20, u"२०", u"बीस"), + (21, u"२१", u"इक्कीस"), + (22, u"२२", u"बाईस"), + (23, u"२३", u"तेईस"), + (24, u"२४", u"चौबीस"), + (25, u"२५", u"पच्चीस"), + (26, u"२६", u"छब्बीस"), + (27, u"२७", u"सत्ताईस"), + (28, u"२८", u"अट्ठाईस"), + (29, u"२९", u"उनतीस"), + (30, u"३०", u"तीस"), + (31, u"३१", u"इकत्तीस"), + (32, u"३२", u"बत्तीस"), + (33, u"३३", u"तैंतीस"), + (34, u"३४", u"चौंतीस"), + (35, u"३५", u"पैंतीस"), + (36, u"३६", u"छत्तीस"), + (37, u"३७", u"सैंतीस"), + (38, u"३८", u"अड़तीस"), + (39, u"३९", u"उनतालीस"), + (40, u"४०", u"चालीस"), + (41, u"४१", u"इकतालीस"), + (42, u"४२", u"बयालीस"), + (43, u"४३", u"तैंतालीस"), + (44, u"४४", u"चौवालीस"), + (45, u"४५", u"पैंतालीस"), + (46, u"४६", u"छियालीस"), + (47, u"४७", u"सैंतालीस"), + (48, u"४८", u"अड़तालीस"), + (49, u"४९", u"उनचास"), + (50, u"५०", u"पचास"), + (51, u"५१", u"इक्यावन"), + (52, u"५२", u"बावन"), + (53, u"५३", u"तिरेपन"), + (54, u"५४", u"चौवन"), + (55, u"५५", u"पचपन"), + (56, u"५६", u"छप्पन"), + (57, u"५७", u"सत्तावन"), + (58, u"५८", u"अट्ठावन"), + (59, u"५९", u"उनसठ"), + (60, u"६०", u"साठ"), + (61, u"६१", u"इकसठ"), + (62, u"६२", u"बासठ"), + (63, u"६३", u"तिरसठ"), + (64, u"६४", u"चौंसठ"), + (65, u"६५", u"पैंसठ"), + (66, u"६६", u"छियासठ"), + (67, u"६७", u"सड़सठ"), + (68, u"६८", u"अड़सठ"), + (69, u"६९", u"उनहत्तर"), + (70, u"७०", u"सत्तर"), + (71, u"७१", u"इकहत्तर"), + (72, u"७२", u"बहत्तर"), + (73, u"७३", u"तिहत्तर"), + (74, u"७४", u"चौहत्तर"), + (75, u"७५", u"पचहत्तर"), + (76, u"७६", u"छिहत्तर"), + (77, u"७७", u"सतहत्तर"), + (78, u"७८", u"अठहत्तर"), + (79, u"७९", u"उनासी"), + (80, u"८०", u"अस्सी"), + (81, u"८१", u"इक्यासी"), + (82, u"८२", u"बयासी"), + (83, u"८३", u"तिरासी"), + (84, u"८४", u"चौरासी"), + (85, u"८५", u"पचासी"), + (86, u"८६", u"छियासी"), + (87, u"८७", u"सतासी"), + (88, u"८८", u"अट्ठासी"), + (89, u"८९", u"नवासी"), + (90, u"९०", u"नब्बे"), + (91, u"९१", u"इक्यानवे"), + (92, u"९२", u"बानवे"), + (93, u"९३", u"तिरानवे"), + (94, u"९४", u"चौरानवे"), + (95, u"९५", u"पचानवे"), + (96, u"९६", u"छियानवे"), + (97, u"९७", u"सत्तानवे"), + (98, u"९८", u"अट्ठानवे"), + (99, u"९९", u"निन्यानवे"), + (100, u"१००", u"एक सौ"), + (1000, u"१०००", u"एक हज़ार"), + (10000, u"१००००", u"दस हज़ार"), + (100000, u"१०००००", u"एक लाख"), + (1000000, u"१००००००", u"दस लाख"), + (10000000, u"१०००००००", u"एक करोड़"), + (100000000, u"१००००००००", u"दस करोड़"), + (1000000000, u"१०००००००००", u"एक अरब"), + (10000000000, u"१००००००००००", u"दस अरब"), + (100000000000, u"१०००००००००००", u"एक ख़रब"), + (1000000000000, u"१००००००००००००", u"दस ख़रब"), + (1234, u"१२३४", u"एक हज़ार दो सौ चौंतीस"), + (8901234, u"८९०१२३४", u"नवासी लाख एक हज़ार दो सौ चौंतीस"), + (567890123, u"५६७८९०१२३", + u"छप्पन करोड़ अठहत्तर लाख नब्बे हज़ार एक सौ तेईस"), + (113345, u"११३३४५", u"एक लाख तेरह हज़ार तीन सौ पैंतालीस"), +) + +# number, hindi numeric notation, pronounced form +TEST_CASES_ORDINAL = ( + (0, u"०", u"शून्य"), # zero is used in cardinal form + (1, u"१ला", u"पहला"), + (2, u"२रा", u"दूसरा"), + (3, u"३रा", u"तीसरा"), + (4, u"४था", u"चौथा"), + (5, u"५वाँ", u"पाँचवाँ"), + (6, u"६ठा", u"छठा"), + (7, u"७वाँ", u"सातवाँ"), + (8, u"८वाँ", u"आठवाँ"), + (9, u"९वाँ", u"नौवाँ"), + (10, u"१०वाँ", u"दसवाँ"), + (11, u"११वाँ", u"ग्यारहवाँ"), + (12, u"१२वाँ", u"बारहवाँ"), + (13, u"१३वाँ", u"तेरहवाँ"), + (14, u"१४वाँ", u"चौदहवाँ"), + (15, u"१५वाँ", u"पंद्रहवाँ"), + (16, u"१६वाँ", u"सोलहवाँ"), + (17, u"१७वाँ", u"सत्रहवाँ"), + (18, u"१८वाँ", u"अट्ठारहवाँ"), + (19, u"१९वाँ", u"उन्नीसवाँ"), + (20, u"२०वाँ", u"बीसवाँ"), + (21, u"२१वाँ", u"इक्कीसवाँ"), + (22, u"२२वाँ", u"बाईसवाँ"), + (23, u"२३वाँ", u"तेईसवाँ"), + (24, u"२४वाँ", u"चौबीसवाँ"), + (25, u"२५वाँ", u"पच्चीसवाँ"), + (26, u"२६वाँ", u"छब्बीसवाँ"), + (27, u"२७वाँ", u"सत्ताईसवाँ"), + (28, u"२८वाँ", u"अट्ठाईसवाँ"), + (29, u"२९वाँ", u"उनतीसवाँ"), + (30, u"३०वाँ", u"तीसवाँ"), + (31, u"३१वाँ", u"इकत्तीसवाँ"), + (32, u"३२वाँ", u"बत्तीसवाँ"), + (33, u"३३वाँ", u"तैंतीसवाँ"), + (34, u"३४वाँ", u"चौंतीसवाँ"), + (35, u"३५वाँ", u"पैंतीसवाँ"), + (36, u"३६वाँ", u"छत्तीसवाँ"), + (37, u"३७वाँ", u"सैंतीसवाँ"), + (38, u"३८वाँ", u"अड़तीसवाँ"), + (39, u"३९वाँ", u"उनतालीसवाँ"), + (40, u"४०वाँ", u"चालीसवाँ"), + (41, u"४१वाँ", u"इकतालीसवाँ"), + (42, u"४२वाँ", u"बयालीसवाँ"), + (43, u"४३वाँ", u"तैंतालीसवाँ"), + (44, u"४४वाँ", u"चौवालीसवाँ"), + (45, u"४५वाँ", u"पैंतालीसवाँ"), + (46, u"४६वाँ", u"छियालीसवाँ"), + (47, u"४७वाँ", u"सैंतालीसवाँ"), + (48, u"४८वाँ", u"अड़तालीसवाँ"), + (49, u"४९वाँ", u"उनचासवाँ"), + (50, u"५०वाँ", u"पचासवाँ"), + (51, u"५१वाँ", u"इक्यावनवाँ"), + (52, u"५२वाँ", u"बावनवाँ"), + (53, u"५३वाँ", u"तिरेपनवाँ"), + (54, u"५४वाँ", u"चौवनवाँ"), + (55, u"५५वाँ", u"पचपनवाँ"), + (56, u"५६वाँ", u"छप्पनवाँ"), + (57, u"५७वाँ", u"सत्तावनवाँ"), + (58, u"५८वाँ", u"अट्ठावनवाँ"), + (59, u"५९वाँ", u"उनसठवाँ"), + (60, u"६०वाँ", u"साठवाँ"), + (61, u"६१वाँ", u"इकसठवाँ"), + (62, u"६२वाँ", u"बासठवाँ"), + (63, u"६३वाँ", u"तिरसठवाँ"), + (64, u"६४वाँ", u"चौंसठवाँ"), + (65, u"६५वाँ", u"पैंसठवाँ"), + (66, u"६६वाँ", u"छियासठवाँ"), + (67, u"६७वाँ", u"सड़सठवाँ"), + (68, u"६८वाँ", u"अड़सठवाँ"), + (69, u"६९वाँ", u"उनहत्तरवाँ"), + (70, u"७०वाँ", u"सत्तरवाँ"), + (71, u"७१वाँ", u"इकहत्तरवाँ"), + (72, u"७२वाँ", u"बहत्तरवाँ"), + (73, u"७३वाँ", u"तिहत्तरवाँ"), + (74, u"७४वाँ", u"चौहत्तरवाँ"), + (75, u"७५वाँ", u"पचहत्तरवाँ"), + (76, u"७६वाँ", u"छिहत्तरवाँ"), + (77, u"७७वाँ", u"सतहत्तरवाँ"), + (78, u"७८वाँ", u"अठहत्तरवाँ"), + (79, u"७९वाँ", u"उनासीवाँ"), + (80, u"८०वाँ", u"अस्सीवाँ"), + (81, u"८१वाँ", u"इक्यासीवाँ"), + (82, u"८२वाँ", u"बयासीवाँ"), + (83, u"८३वाँ", u"तिरासीवाँ"), + (84, u"८४वाँ", u"चौरासीवाँ"), + (85, u"८५वाँ", u"पचासीवाँ"), + (86, u"८६वाँ", u"छियासीवाँ"), + (87, u"८७वाँ", u"सतासीवाँ"), + (88, u"८८वाँ", u"अट्ठासीवाँ"), + (89, u"८९वाँ", u"नवासीवाँ"), + (90, u"९०वाँ", u"नब्बेवाँ"), + (91, u"९१वाँ", u"इक्यानवेवाँ"), + (92, u"९२वाँ", u"बानवेवाँ"), + (93, u"९३वाँ", u"तिरानवेवाँ"), + (94, u"९४वाँ", u"चौरानवेवाँ"), + (95, u"९५वाँ", u"पचानवेवाँ"), + (96, u"९६वाँ", u"छियानवेवाँ"), + (97, u"९७वाँ", u"सत्तानवेवाँ"), + (98, u"९८वाँ", u"अट्ठानवेवाँ"), + (99, u"९९वाँ", u"निन्यानवेवाँ"), + (100, u"१००वाँ", u"एक सौवाँ"), + (1000, u"१०००वाँ", u"एक हज़ारवाँ"), + (100000, u"१०००००वाँ", u"एक लाखवाँ"), + (1000000, u"१००००००वाँ", u"दस लाखवाँ"), + (10000000, u"१०००००००वाँ", u"एक करोड़वाँ"), + (100000000, u"१००००००००वाँ", u"दस करोड़वाँ"), + (1000000000, u"१०००००००००वाँ", u"एक अरबवाँ"), + (10000000000, u"१००००००००००वाँ", u"दस अरबवाँ"), + (100000000000, u"१०००००००००००वाँ", u"एक ख़रबवाँ"), + (1000000000000, u"१००००००००००००वाँ", u"दस ख़रबवाँ"), +) + + +class Num2WordsHITest(TestCase): + def test_cardinal(self): + for number, _, words in TEST_CASES_CARDINAL: + self.assertEqual( + num2words(number, lang="hi"), + words, + msg="failing number %s" % number, + ) + + def test_negative_cardinal(self): + self.assertEqual(num2words(-42, lang="hi"), u"माइनस बयालीस") + + def test_float_cardinal(self): + self.assertEqual(num2words(12.5, lang="hi"), u"बारह दशमलव पाँच") + self.assertEqual(num2words(12.51, lang="hi"), u"बारह दशमलव पाँच एक") + + def test_ordinal(self): + for number, _, words in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(number, lang="hi", ordinal=True), + words, + msg="failing number %s" % number, + ) + + def test_ordinal_num(self): + for number, numeric_notation, _ in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(number, lang="hi", to="ordinal_num"), + numeric_notation, + msg="failing number %s" % number, + ) + + # In python3, Hindi numbers are implicitly converted into number + # as `assert int('४२') == 42`. + # Thus it's possible to pass Hindi numbers string directly + # to the num2words as `num2words('४२', lang='hi')`. + # This will work for any language, + # but is relevant to test for Hindi particularly. + def test_hindi_numeric_input(self): + for number, hindi_number, words in TEST_CASES_CARDINAL: + self.assertEqual( + num2words(hindi_number, lang="hi"), + words, + msg="failing number %s" % number, + ) diff --git a/tox.ini b/tox.ini index 63e88f3a..b896391e 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,14 @@ [tox] -envlist = py37,py38,py39,py310,py311,py312,flake8,isort +envlist = py38,py39,py310,py311,py312,py313,flake8,isort [gh-actions] python = - 3.7: py37 3.8: py38 3.9: py39 3.10: isort, flake8, py310 3.11: py311 3.12: py312 + 3.13: py313 [testenv]