diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..68330d4c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.7, 3.8, 3.9, '3.10', '3.11', '3.12'] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install tox tox-gh-actions coveralls + pip install -r requirements-test.txt + - name: Test with tox + run: | + tox + - name: Upload coverage data to coveralls.io + run: coveralls --service=github + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERALLS_FLAG_NAME: ${{ matrix.python-version }} + COVERALLS_PARALLEL: true + + coveralls: + name: Indicate completion to coveralls.io + needs: build + runs-on: ubuntu-latest + container: python:3-slim + steps: + - name: Finished + run: | + pip3 install --upgrade coveralls + coveralls --service=github --finish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 5e0679e9..8f01013f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ dist .idea/ *.egg-info /.tox +.eggs/ +/venv/ +.venv/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index aa600d03..00000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -sudo: false -language: python -python: - - "2.7" - - "3.4" - - "3.5" - - "3.6" -matrix: - include: - - { python: 3.6, env: TOXENV=flake8 } - - { python: 3.6, env: TOXENV=isort } - # Py37 requires xenial distrubution and sudo - # See travis-ci/travis-ci#9069 - - { python: 3.7, dist: xenial, sudo: true } - -install: - - pip install tox-travis - - pip install coveralls -script: tox -after_success: if [ -e .coverage ]; then coveralls; fi diff --git a/CHANGES.rst b/CHANGES.rst index 0cbd2500..ea33f3e2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,89 @@ Changelog ========= +Version 0.5.13 -- 2023/10/18 +--------------------------- + +* Fix a problem in Brazilian Portuguese code referred to thousands when the hundreds are exact. (#421) +* Fix issue with the hundreds of millions, billions, ... when the hundreds of those are exact. (#436) +* Fix negative number problem (#477) +* Fix lang_DK issues (#366) +* Norwegian uplift (#484) +* BYN to EU and RU (#439) +* Change python3.6 to python3.11 because deprecation in ubuntu 22.04 (#494) +* Add support for Azerbaijani language (#495) +* Add Icelandic (#380) +* Hebrew long-form spelling, gender, ordinals, fractions, maxval=1e66, construct forms (#490) +* Fix 15, 16, 17, 18, 19 issue (#505) +* Added support for the Nigerian Naira (#507) +* Fix several issues with num2words in Arabic (#512) +* Guatemalan currency support (#510) +* Fix #508: Handle string inputs in Italian to_ordinal (#518) +* Add Slovak language support (#533) +* Add gender and morphological cases support for Ukrainian (#530) +* Adding genders for Russian language (#503) +* Lang By Added (#506) +* Add Saudi Riyal to english (#531) + +Version 0.5.12 -- 2022/08/19 +---------------------------- + +* Support Japanese Reiwa (令和/れいわ) era. (#412) +* Add basic farsi support (#354) +* Added Tajik language support (#406) +* Fix Amharic language support (#465) +* Fix Hebrew pluralize and implement to_currency (#330) +* Add support to translate some currencies in italian language (#434) +* Fix Polish twenties (#345) +* Add uzs for ru and en (#422) +* Added support for Esperanto numbers. (#387) +* [ADD] to ordinal number for Turkish (#468) +* Fix zeroth in Dutch to nulde fixing (#326) + +Version 0.5.11 -- 2022/08/03 +---------------------------- + +* Add KZT and UAH currencies to lang RU (#264) +* Add es_NI currency (#276) +* Update .gitignore to add .eggs/ directory (#280) +* Fix Hebrew support (#289) +* Update test_tr.py to increase coverage (#298) +* Add ordinal 12,345 to ES test suite to increase coverage (#287) +* Add simple tests for lang_DK.py (#286) +* Add testcase for lang_EN.py (#288) +* Add more tests to base.py (#283) +* Fixed misspelling of 21 (cardinal and ordinal number) in IT language (#270) +* Romanian issues 259 (#260) +* Adding Language Support for Telugu / Bug Fix in Kannada (#263) +* Add support of Kazakh language (KZ) (#306) +* Update README.rst (#307) +* Added support for Hungarian language (#310) +* [UPD] Readme file (#363) +* [ADD] num2words: add traslation to spanish of several currencies (#356) +* added swedish language including test cases (#352) +* Remove dupplicated line in lang_PT_BR (#355) +* Fix ordinal_num output for Dutch (NL) (#369) +* Polishordinals (#367) +* [tr] return Turkish 0 ordinal and cardinal (#347) +* Improve Ukrainian support and minor fixes in CZ, KZ, LT, LV, PL, RU, SR languages (#400) +* feat: ci: replace travis by github workflows (#448) +* [ES] Added missing accents ("dieciséis", "dólar", "dólares", "veintiún"), improved currency gender handling, fixed pound cent names (#443) + +Version 0.5.10 -- 2019/05/12 +---------------------------- + +* Add Kannada language localization (#243) +* Revert some copyrights changed by mistake (#254) +* Add indian rupee to the supported currencies (#248) +* Improve currency functions for German and French (#247) +* Improve Slovene localization (#246) +* Improve Spanish localization (#240) +* Fix typo 'seperator' on source code (#238) +* Convert string to decimal values (#223) +* Improve German localization and test coverage (#237) +* Improve Polish localization (#233) +* Fix ordinal number for French ending on 1 (#236) + Version 0.5.9 -- 2019/01/10 --------------------------- @@ -33,9 +116,9 @@ Version 0.5.7 -- 2018/06/27 * Add Finnish localization. (#170) * Add Japanese localization. (#171) * Add belgian-french localization. (#151) -* Add Czech localization. (#154) +* Add Czech localization. (#154) * Add Thai localization. (#139) -* Improve English localization. (#144) +* Improve English localization. (#144) * Improve Spanish localization. (#167) * Improve Italian localization. (#143) * Improve documentation. (#155, #145, #174) diff --git a/README.rst b/README.rst index 8e509c15..c207324d 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -num2words - Convert numbers to words in multiple languages -========================================================== +num2words library - Convert numbers to words in multiple languages +================================================================== .. image:: https://img.shields.io/pypi/v/num2words.svg :target: https://pypi.python.org/pypi/num2words @@ -51,7 +51,7 @@ Command line:: $ num2words 24,120.10 -l es veinticuatro mil ciento veinte punto uno $num2words 2.14 -l es --to currency - dos euros con catorce centimos + dos euros con catorce céntimos In code there's only one function to use:: @@ -63,7 +63,7 @@ In code there's only one function to use:: >>> num2words(42, lang='fr') quarante-deux -Besides the numerical argument, there are two main optional arguments. +Besides the numerical argument, there are two main optional arguments, ``to:`` and ``lang:`` **to:** The converter to use. Supported values are: @@ -76,26 +76,39 @@ 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) +* ``az`` (Azerbaijani) +* ``be`` (Belarusian) +* ``ce`` (Chechen) +* ``cy`` (Welsh) * ``cz`` (Czech) * ``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) * ``eu`` (EURO) +* ``fa`` (Farsi) * ``fi`` (Finnish) * ``fr`` (French) * ``fr_CH`` (French - Switzerland) * ``fr_BE`` (French - Belgium) * ``fr_DZ`` (French - Algeria) * ``he`` (Hebrew) +* ``hu`` (Hungarian) * ``id`` (Indonesian) +* ``is`` (Icelandic) * ``it`` (Italian) * ``ja`` (Japanese) +* ``kn`` (Kannada) * ``ko`` (Korean) +* ``kz`` (Kazakh) * ``lt`` (Lithuanian) * ``lv`` (Latvian) * ``no`` (Norwegian) @@ -104,9 +117,12 @@ Besides the numerical argument, there are two main optional arguments. * ``pt_BR`` (Portuguese - Brazilian) * ``sl`` (Slovene) * ``sr`` (Serbian) +* ``sv`` (Swedish) * ``ro`` (Romanian) * ``ru`` (Russian) -* ``sl`` (Slovene) +* ``te`` (Telugu) +* ``tet`` (Tetum) +* ``tg`` (Tajik) * ``tr`` (Turkish) * ``th`` (Thai) * ``vi`` (Vietnamese) @@ -144,4 +160,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/bin/num2words b/bin/num2words index 7c9d595f..359d1bdb 100755 --- a/bin/num2words +++ b/bin/num2words @@ -34,7 +34,7 @@ Options: -t --to= Output converter [default: cardinal]. -h --help Show this message. -v --version Show version. - + Examples: $ num2words 10001 ten thousand and one @@ -46,7 +46,7 @@ Examples: veinticuatro mil ciento veinte punto uno $num2words 2.14 -l es --to currency - dos euros con catorce centimos + dos euros con catorce céntimos """ from __future__ import print_function, unicode_literals @@ -55,7 +55,7 @@ import sys from docopt import docopt import num2words -__version__ = "0.5.9" +__version__ = "0.5.13" __license__ = "LGPL" @@ -76,13 +76,13 @@ def main(): sys.stdout.write(os.linesep) sys.exit(0) if args["--list-converters"]: - for lang in get_converters(): - sys.stdout.write(lang) + for cvt in get_converters(): + sys.stdout.write(cvt) sys.stdout.write(os.linesep) sys.exit(0) try: words = num2words.num2words(args[''], lang=args['--lang'], to=args['--to']) - sys.stdout.write(words+os.linesep) + sys.stdout.write(words + os.linesep) sys.exit(0) except Exception as err: sys.stderr.write(str(args[''])) diff --git a/num2words/README.md b/num2words/README.md new file mode 100644 index 00000000..b7e2e0fa --- /dev/null +++ b/num2words/README.md @@ -0,0 +1,70 @@ +# Add new language + +for each new language you must create a file `lang_NN.py` where `NN` is the +ISO 639-1 or ISO 639-3 [language code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). + +This class must be a subclass of `Num2Word_EU` and implement at least the following methods + +``` +to_cardinal(self, number) +to_ordinal(self, number) +`` + +To integrate your language into the `num2words` module, add the name of your file +to the import list in [num2words/__init__.py](num2words/__init__.py) (top of the file), +and `'nn': lang_NN.Num2Word_NN()` to the `CONVERTER_CLASSES` list in the same file. +Do not forget to remplace `NN` by the appropriate ISO 639 language code. + +The following is a template for a new language class + +``` +from .lang_EU import Num2Word_EU + +class Num2Word_CY(Num2Word_EU): + def setup(self): + Num2Word_EU.setup(self) + + def __init__(self): + pass + + def to_ordinal(self, number): + # implement here your code. number is the integer to be transformed into an ordinal + # as a word (str) + # which is returned + return "NOT IMPLEMENTED" + + def to_cardinal(self, number): + # implement here your code. number is the integer to be transformed into an cardinal + # as a word (str) + # which is returned + return "NOT IMPLEMENTED" +``` + +You can use as manu auxiliary methods as you need to make your code efficient and readable. +If you need further options like Gender, Formal/Informal, add those parameters to the methods, +e.g. + +``` + def to_ordinal(self, number, gender="fem", informal=True) + # your code + pass +``` + +More inspiration can be found in existing `num2words/lang_NN.py` files + +## Code validation + +In order to get your contribution merged into the main project, your code must test the validation tests. +For this install the packages needed to test + +``` +pip install -r requirements-test.txt +``` + +run `tox` and `coverage` to check that the code is well formated and all parts of the code are tested + +``` +tox +python3 -m coverage report -m +``` + diff --git a/num2words/__init__.py b/num2words/__init__.py index ac84888d..c513d853 100644 --- a/num2words/__init__.py +++ b/num2words/__init__.py @@ -17,65 +17,56 @@ from __future__ import unicode_literals -from . import lang_AR -from . import lang_CZ -from . import lang_EN -from . import lang_EN_IN -from . import lang_FR -from . import lang_FR_CH -from . import lang_FR_BE -from . import lang_FR_DZ -from . import lang_DE -from . import lang_ES -from . import lang_FI -from . import lang_LT -from . import lang_LV -from . import lang_PL -from . import lang_RO -from . import lang_RU -from . import lang_ID -from . import lang_JA -from . import lang_NO -from . import lang_DK -from . import lang_PT -from . import lang_PT_BR -from . import lang_HE -from . import lang_IT -from . import lang_ES_VE -from . import lang_ES_CO -from . import lang_VI -from . import lang_TR -from . import lang_NL -from . import lang_UK -from . import lang_SL -from . import lang_SR -from . import lang_TH -from . import lang_KO +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) CONVERTER_CLASSES = { + 'am': lang_AM.Num2Word_AM(), 'ar': lang_AR.Num2Word_AR(), + 'az': lang_AZ.Num2Word_AZ(), + 'be': lang_BE.Num2Word_BE(), + 'ca': lang_CA.Num2Word_CA(), + 'ce': lang_CE.Num2Word_CE(), + '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(), + 'fa': lang_FA.Num2Word_FA(), 'fr': lang_FR.Num2Word_FR(), 'fr_CH': lang_FR_CH.Num2Word_FR_CH(), 'fr_BE': lang_FR_BE.Num2Word_FR_BE(), 'fr_DZ': lang_FR_DZ.Num2Word_FR_DZ(), 'de': lang_DE.Num2Word_DE(), 'fi': lang_FI.Num2Word_FI(), + 'eo': lang_EO.Num2Word_EO(), 'es': lang_ES.Num2Word_ES(), 'es_CO': lang_ES_CO.Num2Word_ES_CO(), + 'es_CR': lang_ES_CR.Num2Word_ES_CR(), + 'es_GT': lang_ES_GT.Num2Word_ES_GT(), + 'es_NI': lang_ES_NI.Num2Word_ES_NI(), 'es_VE': lang_ES_VE.Num2Word_ES_VE(), 'id': lang_ID.Num2Word_ID(), 'ja': lang_JA.Num2Word_JA(), + 'kn': lang_KN.Num2Word_KN(), 'ko': lang_KO.Num2Word_KO(), + 'kz': lang_KZ.Num2Word_KZ(), 'lt': lang_LT.Num2Word_LT(), 'lv': lang_LV.Num2Word_LV(), 'pl': lang_PL.Num2Word_PL(), 'ro': lang_RO.Num2Word_RO(), 'ru': lang_RU.Num2Word_RU(), + 'sk': lang_SK.Num2Word_SK(), 'sl': lang_SL.Num2Word_SL(), 'sr': lang_SR.Num2Word_SR(), + 'sv': lang_SV.Num2Word_SV(), 'no': lang_NO.Num2Word_NO(), 'dk': lang_DK.Num2Word_DK(), 'pt': lang_PT.Num2Word_PT(), @@ -83,13 +74,17 @@ 'he': lang_HE.Num2Word_HE(), 'it': lang_IT.Num2Word_IT(), 'vi': lang_VI.Num2Word_VI(), + 'tg': lang_TG.Num2Word_TG(), 'th': lang_TH.Num2Word_TH(), 'tr': lang_TR.Num2Word_TR(), 'nl': lang_NL.Num2Word_NL(), - 'uk': lang_UK.Num2Word_UK() + 'uk': lang_UK.Num2Word_UK(), + 'te': lang_TE.Num2Word_TE(), + 'tet': lang_TET.Num2Word_TET(), + 'hu': lang_HU.Num2Word_HU(), + 'is': lang_IS.Num2Word_IS(), } - CONVERTES_TYPES = ['cardinal', 'ordinal', 'ordinal_num', 'year', 'currency'] @@ -101,9 +96,13 @@ def num2words(number, ordinal=False, lang='en', to='cardinal', **kwargs): if lang not in CONVERTER_CLASSES: raise NotImplementedError() converter = CONVERTER_CLASSES[lang] + + if isinstance(number, str): + number = converter.str_to_number(number) + # backwards compatible if ordinal: - return converter.to_ordinal(number) + to = 'ordinal' if to not in CONVERTES_TYPES: raise NotImplementedError() diff --git a/num2words/base.py b/num2words/base.py index 43973818..243045ff 100644 --- a/num2words/base.py +++ b/num2words/base.py @@ -94,9 +94,12 @@ def parse_minus(self, num_str): """Detach minus and return it as symbol with new num_str.""" if num_str.startswith('-'): # Extra spacing to compensate if there is no minus. - return '%s ' % self.negword, num_str[1:] + return '%s ' % self.negword.strip(), num_str[1:] return '', num_str + def str_to_number(self, value): + return Decimal(value) + def to_cardinal(self, value): try: assert int(value) == value @@ -106,7 +109,7 @@ def to_cardinal(self, value): out = "" if value < 0: value = abs(value) - out = self.negword + out = "%s " % self.negword.strip() if value >= self.MAXVAL: raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) @@ -136,7 +139,7 @@ def float2tuple(self, value): def to_cardinal_float(self, value): try: float(value) == value - except (ValueError, TypeError, AssertionError): + except (ValueError, TypeError, AssertionError, AttributeError): raise TypeError(self.errmsg_nonnum % value) pre, post = self.float2tuple(float(value)) @@ -254,20 +257,23 @@ def pluralize(self, n, forms): """ raise NotImplementedError + def _money_verbose(self, number, currency): + return self.to_cardinal(number) + def _cents_verbose(self, number, currency): return self.to_cardinal(number) def _cents_terse(self, number, currency): return "%02d" % number - def to_currency(self, val, currency='EUR', cents=True, seperator=',', + def to_currency(self, val, currency='EUR', cents=True, separator=',', adjective=False): """ Args: val: Numeric value currency (str): Currency code cents (bool): Verbose cents - seperator (str): Cent seperator + separator (str): Cent separator adjective (bool): Prefix currency name with adjective Returns: str: Formatted string @@ -286,15 +292,16 @@ def to_currency(self, val, currency='EUR', cents=True, seperator=',', if adjective and currency in self.CURRENCY_ADJECTIVES: cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1) - minus_str = "%s " % self.negword if is_negative else "" + minus_str = "%s " % self.negword.strip() if is_negative else "" + money_str = self._money_verbose(left, currency) cents_str = self._cents_verbose(right, currency) \ if cents else self._cents_terse(right, currency) return u'%s%s %s%s %s %s' % ( minus_str, - self.to_cardinal(left), + money_str, self.pluralize(left, cr1), - seperator, + separator, cents_str, self.pluralize(right, cr2) ) diff --git a/num2words/lang_AM.py b/num2words/lang_AM.py new file mode 100644 index 00000000..77922db3 --- /dev/null +++ b/num2words/lang_AM.py @@ -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) diff --git a/num2words/lang_AR.py b/num2words/lang_AR.py index 843d7972..7195dd47 100644 --- a/num2words/lang_AR.py +++ b/num2words/lang_AR.py @@ -17,10 +17,14 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA +import decimal +import math import re from decimal import Decimal from math import floor +from .base import Num2Word_Base + CURRENCY_SR = [("ريال", "ريالان", "ريالات", "ريالاً"), ("هللة", "هللتان", "هللات", "هللة")] CURRENCY_EGP = [("جنيه", "جنيهان", "جنيهات", "جنيهاً"), @@ -37,11 +41,13 @@ ] -class Num2Word_AR(object): - errmsg_too_big = "Too large" - max_num = 10 ** 36 +class Num2Word_AR(Num2Word_Base): + errmsg_toobig = "abs(%s) must be less than %s." + MAXVAL = 10**51 def __init__(self): + super().__init__() + self.number = 0 self.arabicPrefixText = "" self.arabicSuffixText = "" @@ -75,26 +81,40 @@ def __init__(self): "", "مائة", "مئتان", "ثلاثمائة", "أربعمائة", "خمسمائة", "ستمائة", "سبعمائة", "ثمانمائة", "تسعمائة" ] + self.arabicAppendedTwos = [ "مئتا", "ألفا", "مليونا", "مليارا", "تريليونا", "كوادريليونا", - "كوينتليونا", "سكستيليونا" + "كوينتليونا", "سكستيليونا", "سبتيليونا", "أوكتيليونا ", + "نونيليونا", "ديسيليونا", "أندسيليونا", "دوديسيليونا", + "تريديسيليونا", "كوادريسيليونا", "كوينتينيليونا" ] self.arabicTwos = [ "مئتان", "ألفان", "مليونان", "ملياران", "تريليونان", - "كوادريليونان", "كوينتليونان", "سكستيليونان" + "كوادريليونان", "كوينتليونان", "سكستيليونان", "سبتيليونان", + "أوكتيليونان ", "نونيليونان ", "ديسيليونان", "أندسيليونان", + "دوديسيليونان", "تريديسيليونان", "كوادريسيليونان", "كوينتينيليونان" ] self.arabicGroup = [ "مائة", "ألف", "مليون", "مليار", "تريليون", "كوادريليون", - "كوينتليون", "سكستيليون" + "كوينتليون", "سكستيليون", "سبتيليون", "أوكتيليون", "نونيليون", + "ديسيليون", "أندسيليون", "دوديسيليون", "تريديسيليون", + "كوادريسيليون", "كوينتينيليون" ] self.arabicAppendedGroup = [ "", "ألفاً", "مليوناً", "ملياراً", "تريليوناً", "كوادريليوناً", - "كوينتليوناً", "سكستيليوناً" + "كوينتليوناً", "سكستيليوناً", "سبتيليوناً", "أوكتيليوناً", + "نونيليوناً", "ديسيليوناً", "أندسيليوناً", "دوديسيليوناً", + "تريديسيليوناً", "كوادريسيليوناً", "كوينتينيليوناً" ] self.arabicPluralGroups = [ "", "آلاف", "ملايين", "مليارات", "تريليونات", "كوادريليونات", - "كوينتليونات", "سكستيليونات" + "كوينتليونات", "سكستيليونات", "سبتيليونات", "أوكتيليونات", + "نونيليونات", "ديسيليونات", "أندسيليونات", "دوديسيليونات", + "تريديسيليونات", "كوادريسيليونات", "كوينتينيليونات" ] + assert len(self.arabicAppendedGroup) == len(self.arabicGroup) + assert len(self.arabicPluralGroups) == len(self.arabicGroup) + assert len(self.arabicAppendedTwos) == len(self.arabicTwos) def number_to_arabic(self, arabic_prefix_text, arabic_suffix_text): self.arabicPrefixText = arabic_prefix_text @@ -102,7 +122,6 @@ def number_to_arabic(self, arabic_prefix_text, arabic_suffix_text): self.extract_integer_and_decimal_parts() def extract_integer_and_decimal_parts(self): - re.split('\\.', str(self.number)) splits = re.split('\\.', str(self.number)) self.integer_value = int(splits[0]) @@ -129,8 +148,9 @@ def decimal_value(self, decimal_part): else: result = decimal_part - for i in range(len(result), self.partPrecision): - result += '0' + # The following is useless (never happens) + # for i in range(len(result), self.partPrecision): + # result += '0' return result def digit_feminine_status(self, digit, group_level): @@ -138,13 +158,13 @@ def digit_feminine_status(self, digit, group_level): if self.isCurrencyPartNameFeminine: return self.arabicFeminineOnes[int(digit)] else: + # Note: this never happens return self.arabicOnes[int(digit)] elif group_level == 0: if self.isCurrencyNameFeminine: return self.arabicFeminineOnes[int(digit)] else: return self.arabicOnes[int(digit)] - else: return self.arabicOnes[int(digit)] @@ -159,28 +179,37 @@ def process_arabic_group(self, group_number, group_level, ret_val = "{}".format(self.arabicAppendedTwos[0]) else: ret_val = "{}".format(self.arabicHundreds[int(hundreds)]) + if ret_val != "" and tens != 0: + ret_val += " و " if tens > 0: if tens < 20: + # if int(group_level) >= len(self.arabicTwos): + # raise OverflowError(self.errmsg_toobig % + # (self.number, self.MAXVAL)) + assert int(group_level) < len(self.arabicTwos) if tens == 2 and int(hundreds) == 0 and group_level > 0: - if self.integer_value in [2000, 2000000, 2000000000, - 2000000000000, 2000000000000000, - 2000000000000000000]: + pow = int(math.log10(self.integer_value)) + if self.integer_value > 10 and pow % 3 == 0 and \ + self.integer_value == 2 * (10 ** pow): ret_val = "{}".format( self.arabicAppendedTwos[int(group_level)]) else: ret_val = "{}".format( self.arabicTwos[int(group_level)]) else: - if ret_val != "": - ret_val += " و " if tens == 1 and group_level > 0 and hundreds == 0: + # Note: this never happens + # (hundreds == 0 only if group_number is 0) ret_val += "" elif (tens == 1 or tens == 2) and ( group_level == 0 or group_level == -1) and \ hundreds == 0 and remaining_number == 0: + # Note: this never happens (idem) ret_val += "" + elif tens == 1 and group_level > 0: + ret_val += self.arabicGroup[int(group_level)] else: ret_val += self.digit_feminine_status(int(tens), group_level) @@ -188,19 +217,31 @@ def process_arabic_group(self, group_number, group_level, ones = tens % 10 tens = (tens / 10) - 2 if ones > 0: - if ret_val is not "" and tens < 4: - ret_val += " و " - ret_val += self.digit_feminine_status(ones, group_level) - if ret_val is not "" and ones != 0: + if ret_val != "" and ones != 0: ret_val += " و " ret_val += self.arabicTens[int(tens)] return ret_val + # We use this instead of built-in `abs` function, + # because `abs` suffers from loss of precision for big numbers + def abs(self, number): + return number if number >= 0 else -number + + # We use this instead of `"{:09d}".format(number)`, + # because the string conversion suffers from loss of + # precision for big numbers + def to_str(self, number): + integer = int(number) + if integer == number: + return str(integer) + decimal = round((number - integer) * 10**9) + return str(integer) + "." + "{:09d}".format(decimal).rstrip("0") + def convert(self, value): - self.number = "{:.9f}".format(value) + self.number = self.to_str(value) self.number_to_arabic(self.arabicPrefixText, self.arabicSuffixText) return self.convert_to_arabic() @@ -218,25 +259,37 @@ def convert_to_arabic(self): while temp_number > Decimal(0): - number_to_process = int( - Decimal(str(temp_number)) % Decimal(str(1000))) - temp_number = int(Decimal(temp_number) / Decimal(1000)) + temp_number_dec = Decimal(str(temp_number)) + try: + number_to_process = int(temp_number_dec % Decimal(str(1000))) + except decimal.InvalidOperation: + decimal.getcontext().prec = len( + temp_number_dec.as_tuple().digits + ) + number_to_process = int(temp_number_dec % Decimal(str(1000))) + + temp_number = int(temp_number_dec / Decimal(1000)) group_description = \ self.process_arabic_group(number_to_process, group, Decimal(floor(temp_number))) - if group_description is not '': + if group_description != '': if group > 0: - if ret_val is not "": - ret_val = "{} و {}".format("", ret_val) - if number_to_process != 2: + if ret_val != "": + ret_val = "{}و {}".format("", ret_val) + if number_to_process != 2 and number_to_process != 1: + # if group >= len(self.arabicGroup): + # raise OverflowError(self.errmsg_toobig % + # (self.number, self.MAXVAL) + # ) + assert group < len(self.arabicGroup) if number_to_process % 100 != 1: if 3 <= number_to_process <= 10: ret_val = "{} {}".format( self.arabicPluralGroups[group], ret_val) else: - if ret_val is not "": + if ret_val != "": ret_val = "{} {}".format( self.arabicAppendedGroup[group], ret_val) @@ -250,7 +303,7 @@ def convert_to_arabic(self): ret_val = "{} {}".format(group_description, ret_val) group += 1 formatted_number = "" - if self.arabicPrefixText is not "": + if self.arabicPrefixText != "": formatted_number += "{} ".format(self.arabicPrefixText) formatted_number += ret_val if self.integer_value != 0: @@ -288,21 +341,21 @@ def convert_to_arabic(self): elif 11 <= remaining100 <= 99: formatted_number += self.currency_subunit[3] - if self.arabicSuffixText is not "": + if self.arabicSuffixText != "": formatted_number += " {}".format(self.arabicSuffixText) return formatted_number def validate_number(self, number): - if number >= self.max_num: - raise OverflowError(self.errmsg_too_big) + if number >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (number, self.MAXVAL)) return number def set_currency_prefer(self, currency): - if currency is 'EGP': + if currency == 'EGP': self.currency_unit = CURRENCY_EGP[0] self.currency_subunit = CURRENCY_EGP[1] - elif currency is 'KWD': + elif currency == 'KWD': self.currency_unit = CURRENCY_KWD[0] self.currency_subunit = CURRENCY_KWD[1] else: @@ -329,7 +382,7 @@ def to_ordinal(self, number, prefix=''): self.currency_unit = ('', '', '', '') self.arabicPrefixText = prefix self.arabicSuffixText = "" - return "{}".format(self.convert(abs(number)).strip()) + return "{}".format(self.convert(self.abs(number)).strip()) def to_year(self, value): value = self.validate_number(value) @@ -339,6 +392,7 @@ def to_ordinal_num(self, value): return self.to_ordinal(value).strip() def to_cardinal(self, number): + self.isCurrencyNameFeminine = False number = self.validate_number(number) minus = '' if number < 0: @@ -349,4 +403,4 @@ def to_cardinal(self, number): self.arabicPrefixText = "" self.arabicSuffixText = "" self.arabicOnes = ARABIC_ONES - return minus + self.convert(value=abs(number)).strip() + return minus + self.convert(value=self.abs(number)).strip() diff --git a/num2words/lang_AZ.py b/num2words/lang_AZ.py new file mode 100644 index 00000000..e225bfb7 --- /dev/null +++ b/num2words/lang_AZ.py @@ -0,0 +1,204 @@ +# -*- 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 unicode_literals + +from .base import Num2Word_Base + + +class Num2Word_AZ(Num2Word_Base): + DIGITS = { + 0: u"sıfır", + 1: u"bir", + 2: u"iki", + 3: u"üç", + 4: u"dörd", + 5: u"beş", + 6: u"altı", + 7: u"yeddi", + 8: u"səkkiz", + 9: u"doqquz", + } + + DECIMALS = { + 1: u"on", + 2: u"iyirmi", + 3: u"otuz", + 4: u"qırx", + 5: u"əlli", + 6: u"altmış", + 7: u"yetmiş", + 8: u"səksən", + 9: u"doxsan", + } + + POWERS_OF_TEN = { + 2: u"yüz", + 3: u"min", + 6: u"milyon", + 9: u"milyard", + 12: u"trilyon", + 15: u"katrilyon", + 18: u"kentilyon", + 21: u"sekstilyon", + 24: u"septilyon", + 27: u"oktilyon", + 30: u"nonilyon", + 33: u"desilyon", + 36: u"undesilyon", + 39: u"dodesilyon", + 42: u"tredesilyon", + 45: u"katordesilyon", + 48: u"kendesilyon", + 51: u"seksdesilyon", + 54: u"septendesilyon", + 57: u"oktodesilyon", + 60: u"novemdesilyon", + 63: u"vigintilyon", + } + + VOWELS = u"aıoueəiöü" + VOWEL_TO_CARDINAL_SUFFIX_MAP = { + **dict.fromkeys(["a", "ı"], "ıncı"), + **dict.fromkeys(["e", "ə", "i"], "inci"), + **dict.fromkeys(["o", "u"], "uncu"), + **dict.fromkeys(["ö", "ü"], "üncü"), + } + + VOWEL_TO_CARDINAL_NUM_SUFFIX_MAP = { + **dict.fromkeys(["a", "ı"], "cı"), + **dict.fromkeys(["e", "ə", "i"], "ci"), + **dict.fromkeys(["o", "u"], "cu"), + **dict.fromkeys(["ö", "ü"], "cü"), + } + + CURRENCY_INTEGRAL = ('manat', 'manat') + CURRENCY_FRACTION = ('qəpik', 'qəpik') + CURRENCY_FORMS = {'AZN': (CURRENCY_INTEGRAL, CURRENCY_FRACTION)} + + def setup(self): + super().setup() + + self.negword = u"mənfi" + self.pointword = u"nöqtə" + + def to_cardinal(self, value): + value_str = str(value) + parts = value_str.split(".") + integral_part = parts[0] + fraction_part = parts[1] if len(parts) > 1 else "" + + if integral_part.startswith("-"): + integral_part = integral_part[1:] # ignore minus sign here + + integral_part_in_words = self.int_to_word(integral_part) + fraction_part_in_words = "" if not fraction_part else self.int_to_word( + fraction_part, leading_zeros=True) + + value_in_words = integral_part_in_words + if fraction_part: + value_in_words = " ".join( + [ + integral_part_in_words, + self.pointword, + fraction_part_in_words + ] + ) + + if value < 0: + value_in_words = " ".join([self.negword, value_in_words]) + + return value_in_words + + def to_ordinal(self, value): + assert int(value) == value + + cardinal = self.to_cardinal(value) + last_vowel = self._last_vowel(cardinal) + assert last_vowel is not None + suffix = self.VOWEL_TO_CARDINAL_SUFFIX_MAP[last_vowel] + + if cardinal.endswith(tuple(self.VOWELS)): + cardinal = cardinal[:-1] + + ordinal = "".join([cardinal, suffix]) + + return ordinal + + def to_ordinal_num(self, value): + assert int(value) == value + + cardinal = self.to_cardinal(value) + last_vowel = self._last_vowel(cardinal) + assert last_vowel is not None + suffix = self.VOWEL_TO_CARDINAL_NUM_SUFFIX_MAP[last_vowel] + ordinal_num = "-".join([str(value), suffix]) + + return ordinal_num + + def to_year(self, value): + assert int(value) == value + + year = self.to_cardinal(abs(value)) + if value < 0: + year = " ".join(["e.ə.", year]) + + return year + + def pluralize(self, n, forms): + form = 0 if n == 1 else 1 + return forms[form] + + def int_to_word(self, num_str, leading_zeros=False): + words = [] + reversed_str = list(reversed(num_str)) + + for index, digit in enumerate(reversed_str): + digit_int = int(digit) + # calculate remainder after dividing index by 3 + # because number is parsed by three digit chunks + remainder_to_3 = index % 3 + if remainder_to_3 == 0: + if index > 0: + if set(reversed_str[index:index+3]) != {'0'}: + words.insert(0, self.POWERS_OF_TEN[index]) + if digit_int > 0: + # we say "min" not "bir min" + if not (digit_int == 1 and index == 3): + words.insert(0, self.DIGITS[digit_int]) + elif remainder_to_3 == 1: + if digit_int != 0: + words.insert(0, self.DECIMALS[digit_int]) + else: # remainder is 2 + if digit_int > 0: + words.insert(0, self.POWERS_OF_TEN[2]) # "yüz" + if digit_int > 1: + words.insert(0, self.DIGITS[digit_int]) + + if num_str == '0': + words.append(self.DIGITS[0]) + + if leading_zeros: + zeros_count = len(num_str) - len(str(int(num_str))) + words[:0] = zeros_count * [self.DIGITS[0]] + + return " ".join(words) + + def _last_vowel(self, value): + for char in value[::-1]: + if char in self.VOWELS: + return char diff --git a/num2words/lang_BE.py b/num2words/lang_BE.py new file mode 100644 index 00000000..c41d6e4e --- /dev/null +++ b/num2words/lang_BE.py @@ -0,0 +1,351 @@ +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2022, Sergei Ruzki. 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 + +from .base import Num2Word_Base +from .utils import get_digits, splitbyx + +ZERO = "нуль" + +ONES_FEMININE = { + 1: "адна", + 2: "дзве", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", +} + +ONES = { + "f": { + 1: "адна", + 2: "дзве", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", + }, + "m": { + 1: "адзін", + 2: "два", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", + }, + "n": { + 1: "адно", + 2: "два", + 3: "тры", + 4: "чатыры", + 5: "пяць", + 6: "шэсць", + 7: "сем", + 8: "восем", + 9: "дзевяць", + }, +} + +TENS = { + 0: "дзесяць", + 1: "адзінаццаць", + 2: "дванаццаць", + 3: "трынаццаць", + 4: "чатырнаццаць", + 5: "пятнаццаць", + 6: "шаснаццаць", + 7: "сямнаццаць", + 8: "васямнаццаць", + 9: "дзевятнаццаць", +} + +TWENTIES = { + 2: "дваццаць", + 3: "трыццаць", + 4: "сорак", + 5: "пяцьдзясят", + 6: "шэсцьдзясят", + 7: "семдзесят", + 8: "восемдзесят", + 9: "дзевяноста", +} + +TWENTIES_ORD = ( + ("дваццаць", "дваццаці"), + ("трыццаць", "трыццаці"), + ("сорак", "сарака"), + ("пяцьдзясят", "пяцідзясяці"), + ("шэсцьдзясят", "шaсцідзясяці"), + ("семдзесят", "сямідзесяці"), + ("восемдзесят", "васьмідзесяці"), + ("дзевяноста", "дзевяноста"), +) + +HUNDREDS = { + 1: "сто", + 2: "дзвесце", + 3: "трыста", + 4: "чатырыста", + 5: "пяцьсот", + 6: "шэсцьсот", + 7: "семсот", + 8: "восемсот", + 9: "дзевяцьсот", +} + +THOUSANDS = { + 1: ("тысяча", "тысячы", "тысяч"), # 10^3 + 2: ("мільён", "мільёны", "мільёнаў"), # 10^6 + 3: ("мільярд", "мільярды", "мільярдаў"), # 10^9 + 4: ("трыльён", "трыльёны", "трыльёнаў"), # 10^12 + 5: ("квадрыльён", "квадрыльёны", "квадрыльёнаў"), # 10^15 + 6: ("квінтыльён", "квінтыльёны", "квінтыльёнаў"), # 10^18 + 7: ("секстыльён", "секстыльёны", "секстыльёнаў"), # 10^21 + 8: ("сэптыльён", "сэптыльёны", "сэптыльёнаў"), # 10^24 + 9: ("актыльён", "актыльёны", "актыльёнаў"), # 10^27 + 10: ("нанільён", "нанільёны", "нанільёнаў"), # 10^30 +} + + +class Num2Word_BE(Num2Word_Base): + CURRENCY_FORMS = { + "RUB": ( + ("расійскі рубель", "расійскія рублі", "расійскіх рублёў"), + ("капейка", "капейкі", "капеек"), + ), + "EUR": (("еўра", "еўра", "еўра"), ("цэнт", "цэнты", "цэнтаў")), + "USD": (("долар", "долары", "долараў"), ("цэнт", "цэнты", "цэнтаў")), + "UAH": ( + ("грыўна", "грыўны", "грыўнаў"), + ("капейка", "капейкі", "капеек"), + ), + "KZT": (("тэнге", "тэнге", "тэнге"), ("тыйін", "тыйіны", "тыйінаў")), + "BYN": ( + ("беларускі рубель", "беларускія рублі", "беларускіх рублёў"), + ("капейка", "капейкі", "капеек"), + ), + "UZS": (("сум", "сумы", "сумаў"), ("тыйін", "тыйіны", "тыйінаў")), + "PLN": (("злоты", "злотых", "злотых"), ("грош", "грошы", "грошаў")), + } + + def setup(self): + self.negword = "мінус" + self.pointword = "коска" + self.ords = { + "нуль": "нулявы", + "адзін": "першы", + "два": "другі", + "тры": "трэці", + "чатыры": "чацвёрты", + "пяць": "пяты", + "шэсць": "шосты", + "сем": "сёмы", + "восем": "восьмы", + "дзевяць": "дзявяты", + "сто": "соты", + "тысяча": "тысячны", + } + + self.ords_adjective = { + "адзін": "адна", + "адна": "адна", + "дзве": "двух", + "тры": "трох", + "чатыры": "чатырох", + "пяць": "пяці", + "шэсць": "шасці", + "сем": "сямі", + "восем": "васьмі", + "дзевяць": "дзевяцi", + "сто": "ста", + } + + def to_cardinal(self, number, gender="m"): + n = str(number).replace(",", ".") + if "." in n: + left, right = n.split(".") + if set(right) == {"0"}: + leading_zero_count = 0 + else: + leading_zero_count = len(right) - len(right.lstrip("0")) + + decimal_part = (ZERO + " ") * leading_zero_count + self._int2word( + int(right), gender + ) + return "{} {} {}".format( + self._int2word(int(left), gender), self.pointword, decimal_part + ) + else: + return self._int2word(int(n), gender) + + def pluralize(self, n, forms): + if n % 100 < 10 or n % 100 > 20: + if n % 10 == 1: + form = 0 + elif 5 > n % 10 > 1: + form = 1 + else: + form = 2 + else: + form = 2 + return forms[form] + + def to_ordinal(self, number, gender="m"): + self.verify_ordinal(number) + if isinstance(gender, bool) and gender: + gender = "f" + outwords = self.to_cardinal(number, gender).split(" ") + lastword = outwords[-1].lower() + try: + if len(outwords) > 1: + if outwords[-2] in self.ords_adjective: + outwords[-2] = self.ords_adjective.get( + outwords[-2], outwords[-2] + ) + elif outwords[-2] == "дзесяць": + outwords[-2] = outwords[-2][:-1] + "і" + if len(outwords) == 3: + if outwords[-3] in ["адзін", "адна"]: + outwords[-3] = "" + lastword = self.ords[lastword] + except KeyError: + if lastword[:-3] in self.ords_adjective: + lastword = ( + self.ords_adjective.get(lastword[:-3], lastword) + "соты" + ) + elif lastword[-7:] == "дзесяць": + lastword = "дзясяты" + elif lastword[-9:] == "семдзесят": + lastword = "сямідзясяты" + elif lastword[-1] == "ь" or lastword[-2] == "ц": + lastword = lastword[:-2] + "ты" + elif lastword[-1] == "к": + lastword = lastword.replace("о", "а") + "авы" + + elif lastword[-2] == "ч" or lastword[-1] == "ч": + if lastword[-2] == "ч": + lastword = lastword[:-1] + "ны" + if lastword[-1] == "ч": + lastword = lastword + "ны" + + elif lastword[-1] == "н" or lastword[-2] == "н": + lastword = lastword[: lastword.rfind("н") + 1] + "ны" + elif lastword[-3:] == "наў": + lastword = lastword[: lastword.rfind("н") + 1] + "ны" + elif lastword[-1] == "д" or lastword[-2] == "д": + lastword = lastword[: lastword.rfind("д") + 1] + "ны" + + if gender == "f": + if lastword[-2:] in [ + "ці", + ]: + lastword = lastword[:-2] + "цяя" + else: + lastword = lastword[:-1] + "ая" + + if gender == "n": + if lastword[-2:] in ["ці", "ца"]: + lastword = lastword[:-2] + "цяе" + else: + lastword = lastword[:-1] + "ае" + + outwords[-1] = self.title(lastword) + if len(outwords) == 2 and "адна" in outwords[-2]: + outwords[-2] = outwords[-1] + del outwords[-1] + + if len(outwords) > 1 and ( + (any(x[0] in outwords[-1] for x in THOUSANDS.values())) + or "тысяч" in outwords[-1] + ): + new_outwords = [] + for _w in outwords: + replacement = next( + (x for x in TWENTIES_ORD if x[0] in _w), None + ) + if replacement: + _w = _w.replace(replacement[0], replacement[1]) + new_outwords.append(_w) + outwords = ["".join(new_outwords)] + + return " ".join(outwords).strip() + + def _money_verbose(self, number, currency): + gender = "m" + if currency == "UAH": + gender = "f" + + return self._int2word(number, gender) + + def _cents_verbose(self, number, currency): + if currency in ("UAH", "RUB", "BYN"): + gender = "f" + else: + gender = "m" + + return self._int2word(number, gender) + + def _int2word(self, n, gender="m"): + if n < 0: + return " ".join([self.negword, self._int2word(abs(n), gender)]) + + if n == 0: + return ZERO + + words = [] + chunks = list(splitbyx(str(n), 3)) + i = len(chunks) + for x in chunks: + i -= 1 + + if x == 0: + continue + + n1, n2, n3 = get_digits(x) + + if n3 > 0: + words.append(HUNDREDS[n3]) + + if n2 > 1: + words.append(TWENTIES[n2]) + + if n2 == 1: + words.append(TENS[n1]) + elif n1 > 0: + if i == 0: + ones = ONES[gender] + elif i == 1: + ones = ONES["f"] # Thousands are feminine + else: + ones = ONES["m"] + + words.append(ones[n1]) + + if i > 0: + words.append(self.pluralize(x, THOUSANDS[i])) + + return " ".join(words) diff --git a/num2words/lang_CA.py b/num2words/lang_CA.py new file mode 100644 index 00000000..97d0f29e --- /dev/null +++ b/num2words/lang_CA.py @@ -0,0 +1,476 @@ +from __future__ import division, print_function, unicode_literals + +import math + +from .lang_EU import Num2Word_EU + +GENERIC_DOLLARS = ('dòlar', 'dòlars') +GENERIC_CENTS = ('centau', 'centaus') +CURRENCIES_UNA = ( + 'SLL', + 'SEK', + 'NOK', + 'CZK', + 'DKK', + 'ISK', + 'SKK', + 'GBP', + 'CYP', + 'EGP', + 'FKP', + 'GIP', + 'LBP', + 'SDG', + 'SHP', + 'SSP', + 'SYP', + 'INR', + 'IDR', + 'LKR', + 'MUR', + 'NPR', + 'PKR', + 'SCR', + 'ESP', + 'TRY', + 'ITL', +) +CENTS_UNA = ('EGP', 'JOD', 'LBP', 'SDG', 'SSP', 'SYP') + + +class Num2Word_CA(Num2Word_EU): + CURRENCY_FORMS = { + 'EUR': (('euro', 'euros'), ('cèntim', 'cèntims')), + 'ESP': (('pesseta', 'pessetes'), ('cèntim', 'cèntims')), + 'USD': (GENERIC_DOLLARS, ('centau', 'centaus')), + 'PEN': (('sol', 'sols'), ('cèntim', 'cèntims')), + 'CRC': (('colón', 'colons'), GENERIC_CENTS), + 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'GBP': (('lliura', 'lliures'), ('penic', 'penics')), + 'RUB': (('ruble', 'rubles'), ('copec', 'copecs')), + 'SEK': (('corona', 'corones'), ('öre', 'öre')), + 'NOK': (('corona', 'corones'), ('øre', 'øre')), + 'PLN': (('zloty', 'zlotys'), ('grosz', 'groszy')), + 'MXN': (('peso', 'pesos'), GENERIC_CENTS), + 'RON': (('leu', 'lei'), ('ban', 'bani')), + 'INR': (('rupia', 'rupies'), ('paisa', 'paise')), + 'HUF': (('fòrint', 'fòrints'), ('fillér', 'fillérs')), + 'FRF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'CNY': (('iuan', 'iuans'), ('fen', 'jiao')), + 'CZK': (('corona', 'corones'), ('haléř', 'haléřů')), + 'NIO': (('córdoba', 'córdobas'), GENERIC_CENTS), + 'VES': (('bolívar', 'bolívars'), ('cèntim', 'cèntims')), + 'BRL': (('real', 'reals'), GENERIC_CENTS), + 'CHF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'JPY': (('ien', 'iens'), ('sen', 'sen')), + 'KRW': (('won', 'wons'), ('jeon', 'jeon')), + 'KPW': (('won', 'wons'), ('chŏn', 'chŏn')), + 'TRY': (('lira', 'lires'), ('kuruş', 'kuruş')), + 'ZAR': (('rand', 'rands'), ('cèntim', 'cèntims')), + 'KZT': (('tenge', 'tenge'), ('tin', 'tin')), + 'UAH': (('hrívnia', 'hrívnies'), ('kopiika', 'kopíok')), + 'THB': (('baht', 'bahts'), ('satang', 'satang')), + 'AED': (('dirham', 'dirhams'), ('fils', 'fulūs')), + 'AFN': (('afgani', 'afganis'), ('puli', 'puls')), + 'ALL': (('lek', 'lekë'), ('qqindarka', 'qindarkë')), + 'AMD': (('dram', 'drams'), ('luma', 'lumas')), + 'ANG': (('florí', 'florins'), ('cèntim', 'cèntims')), + 'AOA': (('kwanza', 'kwanzes'), ('cèntim', 'cèntims')), + 'ARS': (('peso', 'pesos'), GENERIC_CENTS), + 'AWG': (('florí', 'florins'), GENERIC_CENTS), + 'AZN': (('manat', 'manats'), ('qəpik', 'qəpik')), + 'BBD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BDT': (('taka', 'taka'), ('poisha', 'poisha')), + 'BGN': (('lev', 'leva'), ('stotinka', 'stotinki')), + 'BHD': (('dinar', 'dinars'), ('fils', 'fulūs')), + 'BIF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'BMD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BND': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BOB': (('boliviano', 'bolivianos'), GENERIC_CENTS), + 'BSD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BTN': (('ngultrum', 'ngultrums'), ('chetrum', 'chetrums')), + 'BWP': (('pula', 'pula'), ('thebe', 'thebe')), + 'BYN': (('ruble', 'rubles'), ('copec', 'copecs')), + 'BYR': (('ruble', 'rubles'), ('copec', 'copecs')), + 'BZD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'CDF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'CLP': (('peso', 'pesos'), GENERIC_CENTS), + 'COP': (('peso', 'pesos'), GENERIC_CENTS), + 'CUP': (('peso', 'pesos'), GENERIC_CENTS), + 'CVE': (('escut', 'escuts'), GENERIC_CENTS), + 'CYP': (('lliura', 'lliures'), ('cèntim', 'cèntims')), + 'DJF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'DKK': (('corona', 'corones'), ('øre', 'øre')), + 'DOP': (('peso', 'pesos'), GENERIC_CENTS), + 'DZD': (('dinar', 'dinars'), ('cèntim', 'cèntims')), + 'ECS': (('sucre', 'sucres'), GENERIC_CENTS), + 'EGP': (('lliura', 'lliures'), ('piastre', 'piastres')), + 'ERN': (('nakfa', 'nakfes'), ('cèntim', 'cèntims')), + 'ETB': (('birr', 'birr'), ('cèntim', 'cèntims')), + 'FJD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'FKP': (('lliura', 'lliures'), ('penic', 'penics')), + 'GEL': (('lari', 'laris'), ('tetri', 'tetri')), + 'GHS': (('cedi', 'cedis'), ('pesewa', 'pesewas')), + 'GIP': (('lliura', 'lliures'), ('penic', 'penics')), + 'GMD': (('dalasi', 'dalasis'), ('butut', 'bututs')), + 'GNF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'GTQ': (('quetzal', 'quetzals'), GENERIC_CENTS), + 'GYD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'HKD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'HNL': (('lempira', 'lempires'), GENERIC_CENTS), + 'HRK': (('kuna', 'kuna'), ('lipa', 'lipa')), + 'HTG': (('gourde', 'gourdes'), ('cèntim', 'cèntims')), + 'IDR': (('rúpia', 'rúpies'), ('cèntim', 'cèntims')), + 'ILS': (('xéquel', 'xéquels'), ('agorà', 'agorot')), + 'IQD': (('dinar', 'dinars'), ('fils', 'fils')), + 'IRR': (('rial', 'rials'), ('dinar', 'dinars')), + 'ISK': (('corona', 'corones'), ('eyrir', 'aurar')), + 'ITL': (('lira', 'lires'), ('cèntim', 'cèntims')), + 'JMD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'JOD': (('dinar', 'dinars'), ('piastra', 'piastres')), + 'KES': (('xiling', 'xílings'), ('cèntim', 'cèntims')), + 'KGS': (('som', 'som'), ('tyiyn', 'tyiyn')), + 'KHR': (('riel', 'riels'), ('cèntim', 'cèntims')), + 'KMF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'KWD': (('dinar', 'dinars'), ('fils', 'fils')), + 'KYD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'LAK': (('kip', 'kips'), ('at', 'at')), + 'LBP': (('lliura', 'lliures'), ('piastra', 'piastres')), + 'LKR': (('rúpia', 'rúpies'), ('cèntim', 'cèntims')), + 'LRD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'LSL': (('loti', 'maloti'), ('sente', 'lisente')), + 'LTL': (('lita', 'litai'), ('cèntim', 'cèntims')), + 'LYD': (('dinar', 'dinars'), ('dírham', 'dírhams')), + 'MAD': (('dírham', 'dirhams'), ('cèntim', 'cèntims')), + 'MDL': (('leu', 'lei'), ('ban', 'bani')), + 'MGA': (('ariary', 'ariary'), ('iraimbilanja', 'iraimbilanja')), + 'MKD': (('denar', 'denari'), ('deni', 'deni')), + 'MMK': (('kyat', 'kyats'), ('pya', 'pyas')), + 'MNT': (('tögrög', 'tögrög'), ('möngö', 'möngö')), + 'MOP': (('pataca', 'pataques'), ('avo', 'avos')), + 'MRO': (('ouguiya', 'ouguiya'), ('khoums', 'khoums')), + 'MRU': (('ouguiya', 'ouguiya'), ('khoums', 'khoums')), + 'MUR': (('rupia', 'rúpies'), ('cèntim', 'cèntims')), + 'MVR': (('rufiyaa', 'rufiyaa'), ('laari', 'laari')), + 'MWK': (('kwacha', 'kwacha'), ('tambala', 'tambala')), + 'MYR': (('ringgit', 'ringgits'), ('sen', 'sens')), + 'MZN': (('metical', 'meticals'), GENERIC_CENTS), + 'NAD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'NGN': (('naira', 'naires'), ('kobo', 'kobos')), + 'NPR': (('rupia', 'rupies'), ('paisa', 'paises')), + 'NZD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'OMR': (('rial', 'rials'), ('baisa', 'baisa')), + 'PAB': (GENERIC_DOLLARS, ('centésimo', 'centésimos')), + 'PGK': (('kina', 'kina'), ('toea', 'toea')), + 'PHP': (('peso', 'pesos'), GENERIC_CENTS), + 'PKR': (('rupia', 'rupies'), ('paisa', 'paise')), + 'PLZ': (('zloty', 'zlotys'), ('grosz', 'groszy')), + 'PYG': (('guaraní', 'guaranís'), ('cèntim', 'cèntims')), + 'QAR': (('rial', 'rials'), ('dírham', 'dírhams')), + 'QTQ': (('quetzal', 'quetzals'), GENERIC_CENTS), + 'RSD': (('dinar', 'dinars'), ('para', 'para')), + 'RUR': (('ruble', 'rubles'), ('copec', 'copecs')), + 'RWF': (('franc', 'francs'), ('cèntim', 'cèntims')), + 'SAR': (('riyal', 'riyals'), ('hàl·lala', 'hàl·lalat')), + 'SBD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'SCR': (('rupia', 'rupies'), ('cèntim', 'cèntims')), + 'SDG': (('lliura', 'lliures'), ('piastre', 'piastres')), + 'SGD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'SHP': (('lliura', 'lliures'), ('penic', 'penics')), + 'SLL': (('leonE', 'leones'), ('cèntim', 'cèntims')), + 'SRD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'SSP': (('lliura', 'lliures'), ('piastre', 'piastres')), + 'STD': (('dobra', 'dobrAs'), ('cèntim', 'cèntims')), + 'SVC': (('colón', 'colons'), GENERIC_CENTS), + 'SYP': (('lliura', 'lliures'), ('piastre', 'piastres')), + 'SZL': (('lilangeni', 'emalangeni'), ('cèntim', 'cèntims')), + 'TJS': (('somoni', 'somoni'), ('diram', 'diram')), + 'TMT': (('manat', 'manats'), ('teňňesi', 'teňňesi')), + 'TND': (('dinar', 'dinars'), ('mil·lim', 'mil·limat')), + 'TOP': (('paanga', 'paangas'), ('seniti', 'seniti')), + 'TTD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'TWD': (('nou dòlar', 'nous dòlars'), ('fen', 'fen')), + 'TZS': (('xíling', 'xílings'), ('cèntim', 'cèntims')), + 'UGX': (('xíling', 'xílings'), ('cèntim', 'cèntims')), + 'UYU': (('peso', 'pesos'), ('centèsim', 'centèsims')), + 'UZS': (('som', 'som'), ('tiyin', 'tiyin')), + 'VND': (('dong', 'dongs'), ('xu', 'xu')), + 'VUV': (('vatu', 'vatus'), ('cèntim', 'cèntims')), + 'WST': (('tala', 'tala'), ('sene', 'sene')), + 'XAF': (('franc CFA', 'francs CFA'), ('cèntim', 'cèntims')), + 'XCD': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'XOF': (('franc CFA', 'francs CFA'), ('cèntim', 'cèntims')), + 'XPF': (('franc CFP', 'francs CFP'), ('cèntim', 'cèntims')), + 'YER': (('rial', 'rials'), ('fils', 'fils')), + 'YUM': (('dinar', 'dinars'), ('para', 'para')), + 'ZMW': (('kwacha', 'kwacha'), ('ngwee', 'ngwee')), + 'ZWL': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + 'ZWL': (GENERIC_DOLLARS, ('cèntim', 'cèntims')), + } + + GIGA_SUFFIX = None + MEGA_SUFFIX = "ilió" + + def setup(self): + lows = ["quadr", "tr", "b", "m"] + self.high_numwords = self.gen_high_numwords([], [], lows) + self.negword = "menys " + self.pointword = "punt" + self.errmsg_nonnum = "type(%s) no és [long, int, float]" + self.errmsg_floatord = "El float %s no pot ser tractat com un" \ + " ordinal." + self.errmsg_negord = "El número negatiu %s no pot ser tractat" \ + " com un ordinal." + self.errmsg_toobig = "abs(%s) ha de ser inferior a %s." + self.gender_stem = "è" + self.exclude_title = ["i", "menys", "punt"] + + self.mid_numwords = [ + (1000, "mil"), + (100, "cent"), + (90, "noranta"), + (80, "vuitanta"), + (70, "setanta"), + (60, "seixanta"), + (50, "cinquanta"), + (40, "quaranta"), + (30, "trenta"), + ] + self.low_numwords = [ + "vint-i-nou", + "vint-i-vuit", + "vint-i-set", + "vint-i-sis", + "vint-i-cinc", + "vint-i-quatre", + "vint-i-tres", + "vint-i-dos", + "vint-i-un", + "vint", + "dinou", + "divuit", + "disset", + "setze", + "quinze", + "catorze", + "tretze", + "dotze", + "onze", + "deu", + "nou", + "vuit", + "set", + "sis", + "cinc", + "quatre", + "tres", + "dos", + "un", + "zero", + ] + self.mid_num = { + 1000: "mil", + 100: "cent", + 90: "noranta", + 80: "vuitanta", + 70: "setanta", + 60: "seixanta", + 50: "cinquanta", + 40: "quaranta", + 30: "trenta", + 20: "vint", + 10: "deu", + } + self.low_num = { + 0: "zero", + 1: "un", + 2: "dos", + 3: "tres", + 4: "quatre", + 5: "cinc", + 6: "sis", + 7: "set", + 8: "vuit", + 9: "nou", + 10: "deu", + 11: "onze", + 12: "dotze", + 13: "tretze", + 14: "catorze", + 15: "quinze", + 16: "setze", + 17: "disset", + 18: "divuit", + 19: "dinou", + 20: "vint", + 21: "vint-i-un", + 22: "vint-i-dos", + 23: "vint-i-tres", + 24: "vint-i-quatre", + 25: "vint-i-cinc", + 26: "vint-i-sis", + 27: "vint-i-set", + 28: "vint-i-vuit", + 29: "vint-i-nou", + } + self.ords = { + 1: "primer", + 2: "segon", + 3: "tercer", + 4: "quart", + 5: "cinqu", + 6: "sis", + 7: "set", + 8: "vuit", + 9: "nov", + 10: "des", + 11: "onz", + 12: "dotz", + 13: "tretz", + 14: "catorz", + 15: "quinz", + 16: "setz", + 17: "disset", + 18: "divuit", + 19: "dinov", + 20: "vint", + 30: "trent", + 40: "quarant", + 50: "cinquant", + 60: "seixant", + 70: "setant", + 80: "vuitant", + 90: "norant", + 100: "cent", + 200: "dos-cent", + 300: "tres-cent", + 400: "quatre-cent", + 500: "cinc-cent", + 600: "sis-cent", + 700: "set-cent", + 800: "vuit-cent", + 900: "nou-cent", + 1e3: "mil", + 1e6: "milion", + 1e9: "mil milion", + 1e12: "bilion", + 1e15: "mil bilion", + } + + self.ords_2 = {1: "1r", 2: "2n", 3: "3r", 4: "4t"} + self.ords_3 = { + 1: "unè", + 2: "dosè", + 3: "tresè", + 4: "quatrè", + 5: "cinquè", + 6: "sisè", + 7: "setè", + 8: "vuitè", + 9: "novè", + } + + def merge(self, curr, next): + ctext, cnum, ntext, nnum = curr + next + if cnum == 1: + if nnum < 1000000: + return next + ctext = "un" + + if nnum < cnum: + if cnum < 100: + return "%s-%s" % (ctext, ntext), cnum + nnum + elif nnum == 1: + return "%s %s" % (ctext, ntext), cnum + nnum + elif cnum == 100: + return "%s %s" % (ctext, ntext), cnum + nnum + else: + return "%s %s" % (ctext, ntext), cnum + nnum + elif (not nnum % 1000000) and cnum > 1: + ntext = ntext[:-3] + "lions" + if nnum == 100: + ntext += "s" + ctext += "-" + else: + ntext = " " + ntext + return (ctext + ntext, cnum * nnum) + + def to_ordinal(self, value): + self.verify_ordinal(value) + if value == 0: + text = "" + elif value < 5: + text = self.ords[value] + elif value <= 20: + text = "%s%s" % (self.ords[value], self.gender_stem) + elif value <= 30: + frac = value % 10 + text = "%s%s%s" % (self.ords[20], "-i-", self.ords_3[frac]) + elif value < 100: + dec = (value // 10) * 10 + text = "%s%s%s%s" % (self.ords[dec], "a", + "-", self.ords_3[value - dec]) + elif value == 1e2: + text = "%s%s" % (self.ords[value], self.gender_stem) + elif value < 2e2: + cen = (value // 100) * 100 + text = "%s %s" % (self.ords[cen], self.to_ordinal(value - cen)) + elif value < 1e3: + cen = (value // 100) * 100 + text = "%s%s %s" % (self.ords[cen], "s", + self.to_ordinal(value - cen)) + elif value == 1e3: + text = "%s%s" % (self.ords[value], self.gender_stem) + elif value < 1e6: + dec = 1000 ** int(math.log(int(value), 1000)) + high_part, low_part = divmod(value, dec) + cardinal = self.to_cardinal(high_part) if high_part != 1 else "" + text = "%s %s %s" % (cardinal, self.ords[dec], + self.to_ordinal(low_part)) + elif value < 1e18: + dec = 1000 ** int(math.log(int(value), 1000)) + high_part, low_part = divmod(value, dec) + cardinal = self.to_cardinal(high_part) if high_part != 1 else "" + text = "%s%s%s %s" % (cardinal, self.ords[dec], + self.gender_stem, self.to_ordinal(low_part)) + else: + part1 = self.to_cardinal(value) + text = "%s%s" % (part1[:-1], "onè") + return text.strip() + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + if value not in self.ords_2: + return "%s%s" % (value, "è" if self.gender_stem == "è" else "a") + else: + return self.ords_2[value] + + def to_currency(self, val, currency="EUR", cents=True, + separator=" amb", adjective=False): + result = super(Num2Word_CA, self).to_currency( + val, currency=currency, cents=cents, + separator=separator, adjective=adjective + ) + list_result = result.split(separator + " ") + + if currency in CURRENCIES_UNA: + list_result[0] = list_result[0].replace("un", "una") + list_result[0] = list_result[0].replace("dos", "dues") + list_result[0] = list_result[0].replace("cents", "centes") + + list_result[0] = list_result[0].replace("vint-i-un", "vint-i-un") + list_result[0] = list_result[0].replace(" i un", "-un") + list_result[0] = list_result[0].replace("un", "un") + + if currency in CENTS_UNA: + list_result[1] = list_result[1].replace("un", "una") + list_result[1] = list_result[1].replace("dos", "dues") + + list_result[1] = list_result[1].replace("vint-i-un", "vint-i-una") + + list_result[1] = list_result[1].replace("un", "un") + + result = (separator + " ").join(list_result) + + return result diff --git a/num2words/lang_CE.py b/num2words/lang_CE.py new file mode 100644 index 00000000..abf8e5f0 --- /dev/null +++ b/num2words/lang_CE.py @@ -0,0 +1,522 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2023, Johannes Heinecke. 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 + +from .currency import parse_currency_parts +from .lang_EU import Num2Word_EU + +# Chechen numbers inflect in case if without noun or +# use a special oblique ending when followed by a counted noun +# 4, 14, 40 and composites thereof agree in class (gender) with the +# noun. Chechen has 6 classes which are indicated by the initial +# letter of 4, 14 and 40. By default it is "д" but +# it can also be "б", "й" or "в". +# Indicate the needed class prefix as follows +# num2words(4, lang='ce', case="abs", clazz="б") + + +CARDINALS = { + "casenames": { + "abs": "Им.", + "gen": "Род.", + "dat": "Дат.", + "erg": "Эрг;", + "instr": "Твор.", + "mat": "Вещ.", + "comp": "Сравнит.", + "all": "Местн.", + }, + "casesuffix_cons": { # to be added to numerals with final consonant + "gen": "аннан", + "dat": "анна", + "erg": "амма", + "instr": "анца", + "mat": "аннах", + "comp": "аннал", + "all": "анга", + "obl": "ан", + "ORD": "алгӀа", + }, + "casesuffix_voc": { # to be added to numerals with final vowel + "gen": "ннан", + "dat": "нна", + "erg": "мма", + "instr": "нца", + "mat": "ннах", + "comp": "ннал", + "all": "нга", + "obl": "н", + "ORD": "лгӀа", + }, + 0: { + "attr": "ноль", + "abs": "ноль", + "gen": "нолан", + "dat": "нолана", + "erg": "ноло", + "instr": "ноланца", + "mat": "ноланах", + "comp": "ноланал", + "all": "ноланга", + }, + 1: { + "attr": "цхьа", # in front of nouns in ABS + "obl": "цхьана", # with nouns in other cases than ABS + "abs": "цхьаъ", + "gen": "цхьаннан", + "dat": "цхьанна", + "erg": "цхьамма", + "instr": "цхьаьнца", + "mat": "цхьаннах", + "comp": "цхьаннал", + "all": "цхаьнга", + "ORD": "цхьалгӀа", + }, + 2: { + "attr": "ши", # in front of 100, 1000 + "obl": "шина", + "abs": "шиъ", + "gen": "шиннан", + "dat": "шинна", + "erg": "шимма", + "instr": "шинца", + "mat": "шиннах", + "comp": "шиннал", + "all": "шинга", + "ORD": "шолгӀа", + }, + 3: { + "attr": "кхо", + "obl": "кхона", + "abs": "кхоъ", + "gen": "кхааннан", + "dat": "кхаанна", + "erg": "кхаамма", + "instr": "кхаанца", + "mat": "кхааннах", + "comp": "кхааннал", + "all": "кхаанга", + "ORD": "кхоалгӀа", + }, + 4: { + "attr": "д*и", + "obl": "д*еа", + "abs": "д*иъ", + "gen": "д*еаннан", + "dat": "д*еанна", + "erg": "д*еамма", + "instr": "д*еанца", + "mat": "д*еаннах", + "comp": "д*еаннал", + "all": "д*еанга", + "ORD": "д*оьалгӀа", + }, + 5: { + "attr": "пхи", + "obl": "пхеа", + "abs": "пхиъ", + "gen": "пхеаннан", + "dat": "пхеанна", + "erg": "пхеамма", + "instr": "нхеанца", + "mat": "пхеаннах", + "comp": "пхеаннал", + "all": "пхеанга", + "ORD": "пхоьалгӀа", + }, + 6: { + "abs": "ялх", + "attr": "ялх", + "ORD": "йолхалгӀа", + }, + 7: { + "abs": "ворхӀ", + "attr": "ворхӀ", + "ORD": "ворхӀалгӀа", + }, + 8: { + "abs": "бархӀ", + "attr": "бархӀ", + "ORD": "борхӀалӀа", + }, + 9: { + "abs": "исс", + "attr": "исс", + "ORD": "уьссалгӀа", + }, + 10: { + "attr": "итт", + "abs": "итт", + "gen": "иттаннан", + "dat": "иттанна", + "erg": "иттамма", + "instr": "иттанца", + "mat": "иттаннах", + "comp": "иттаннал", + "all": "иттанга", + "ORD": "уьтталгӀа", + }, + 11: { + "abs": "цхьайтта", + "attr": "цхьайтта", + "ORD": "цхьайтталгӀа", + }, + 12: { + "abs": "шийтта", + "attr": "шийтта", + "ORD": "шийтталга", + }, + 13: { + "abs": "кхойтта", + "attr": "кхойтта", + "ORD": "кхойтталгӀа", + }, + 14: { + "abs": "д*ейтта", + "attr": "д*ейтта", + "ORD": "д*ейтталгӀа", + }, + 15: { + "abs": "пхийтта", + "attr": "пхийтта", + "ORD": "пхийтталгӀа", + }, + 16: { + "abs": "ялхитта", + "attr": "ялхитта", + "ORD": "ялхитталгӀа", + }, + 17: { + "abs": "вуьрхӀитта", + "attr": "вуьрхӀитта", + "ORD": "вуьрхӀитталгӀа", + }, + 18: { + "abs": "берхӀитта", + "attr": "берхӀитта", + "ORD": "берхитталӀа", + }, + 19: { + "abs": "ткъайесна", + "attr": "ткъайесна", + "ORD": "ткъаесналгӀа", + }, + 20: { + "abs": "ткъа", + "gen": "ткъаннан", + "dat": "ткъанна", + "erg": "ткъамма", + "instr": "ткъанца", + "mat": "ткъаннах", + "comp": "ткъаннал", + "all": "ткъанга", + "attr": "ткъе", + "ORD": "ткъолгӀа", + }, + 40: { + "abs": "шовзткъа", + "attr": "шовзткъе", + "ORD": "шовзткъалгІа", + }, + 60: { + "abs": "кхузткъа", + "attr": "кхузткъе", + "ORD": "кхузткъалгІа", + }, + 80: { + "abs": "дезткъа", + "attr": "дезткъе", + "ORD": "дезткъалгІа", + }, + 100: { + "attr": "бӀе", + "abs": "бӀе", + "obl": "бӀен", + "gen": "бӀеннан", + "dat": "бӀенна", + "erg": "бӀемма", + "instr": "бӀенца", + "mat": "бӀеннах", + "comp": "бӀеннал", + "all": "бӀенга", + "ORD": "бІолгІа", + }, + 1000: { + "attr": "эзар", + "abs": "эзар", + "obl": "эзаран", + "gen": "эзарнан", + "dat": "эзарна", + "erg": "эзарно", + "instr": "эзарнаца", + "mat": "эзарнах", + "comp": "эзарнал", + "all": "эзаранга", + "ORD": "эзарлагІа", + }, + 1000000: { + "attr": "миллион", + "abs": "миллион", + "ORD": "миллионалгІа", + }, +} + +ILLIONS = { + 6: { + "attr": "миллион", + "abs": "миллион", + "ORD": "миллионалгІа", + }, + 9: { + "attr": "миллиард", + "abs": "миллиард", + "ORD": "миллиардалгІа", + }, + 12: { + "attr": "биллион", + "abs": "биллион", + "ORD": "биллионалгІа", + }, + 15: { + "attr": "биллиард", + "abs": "биллиард", + "ORD": "биллиардалгІа", + }, + 18: { + "attr": "триллион", + "abs": "триллион", + "ORD": "триллионалгІа", + }, + 21: { + "attr": "триллиард", + "abs": "триллиард", + "ORD": "триллиардалгІа", + }, + 24: { + "attr": "квадриллион", + "abs": "квадриллион", + "ORD": "квадриллионалгІа", + }, + 27: { + "attr": "квадриллиард", + "abs": "квадриллиард", + "ORD": "квадриллиардалгІа", + }, + 30: { + "attr": "квинтиллион", + "abs": "квинтиллион", + "ORD": "квинтиллионалгІа", + }, + 33: { + "attr": "квинтиллиард", + "abs": "квинтиллиард", + "ORD": "квинтиллиардалгІа", + }, +} + + +MINUS = "минус" +# DECIMALPOINT = "запятая" # check ! +DECIMALPOINT = "а" + + +class Num2Word_CE(Num2Word_EU): + CURRENCY_FORMS = { + # currency code: (sg, pl), (sg, pl) + "EUR": (("Евро", "Евро"), ("Сент", "Сенташ")), + "RUB": (("Сом", "Сомаш"), ("Кепек", "Кепекаш")), + "USD": (("Доллар", "Доллараш"), ("Сент", "Сенташ")), + "GBP": (("Фунт", "Фунташ"), ("Пенни", "Пенни")), + } + + def setup(self): + Num2Word_EU.setup(self) + self.negword = "минус" + self.pointword = "запятая" # check ! + # self.errmsg_nonnum = ( + # u"Seulement des nombres peuvent être convertis en mots." + # ) + # self.errmsg_toobig = ( + # u"Nombre trop grand pour être converti en mots (abs(%s) > %s)." + # ) + # self.exclude_title = ["et", "virgule", "moins"] + self.mid_numwords = [] + self.low_numwords = [] + self.ords = {} + + def to_ordinal(self, number, clazz="д"): + # implement here your code. number is the integer to + # be transformed into an ordinal as a word (str) + # which is returned + return self.to_cardinal(number, clazz=clazz, case="ORD") + + def to_cardinal(self, number, clazz="д", case="abs"): + if isinstance(number, float): + entires = self.to_cardinal(int(number)) + float_part = str(number).split(".")[1] + postfix = " ".join( + # Drops the trailing zero and comma + [self.to_cardinal(int(c)) for c in float_part] + ) + return entires + " " + DECIMALPOINT + " " + postfix + + elif number < 20: + return self.makecase(number, case, clazz) + elif number < 100: + twens = number // 20 + units = number % 20 + base = twens * 20 + if units == 0: + return self.makecase(number, case, clazz) + else: + twenties = self.makecase(base, "attr", clazz) + rest = self.to_cardinal(units, clazz=clazz, case=case) + return twenties + " " + rest.replace("д*", clazz) + elif number < 1000: + hundreds = number // 100 + tens = number % 100 + if hundreds > 1: + hundert = ( + CARDINALS[hundreds]["attr"].replace("д*", clazz) + " " + ) + else: + hundert = "" + if tens != 0: + rest = self.to_cardinal(tens, clazz=clazz, case=case) + return hundert + CARDINALS[100]["abs"] + " " + rest + else: + return hundert + self.makecase(100, case, clazz) + elif number < 1000000: + thousands = number // 1000 + hundert = number % 1000 + if hundert > 0: + tcase = "attr" + else: + tcase = case + if thousands > 1: + tausend = ( + self.to_cardinal(thousands, clazz=clazz, case="attr") + + " " + + CARDINALS[1000][tcase] + ) + else: + tausend = self.makecase(1000, tcase, clazz) + + if hundert != 0: + rest = " " + self.to_cardinal(hundert, clazz=clazz, case=case) + else: + rest = "" + return tausend + rest + + elif number < 10**34: + out = [] + for pot in reversed([6, 9, 12, 15, 18, 21, 24, 27, 30, 33]): + # 3 digits of billion, trillion etc + step = number // 10**pot % 1000 + if step > 0: + words = self.to_cardinal(step, clazz=clazz, case="attr") + out.append(words + " " + ILLIONS[pot]["attr"]) + rest = number % 10**6 + if rest: + out.append(self.to_cardinal(rest, clazz=clazz, case=case)) + return " ".join(out) + + return "NOT IMPLEMENTED" + + def _money_verbose(self, number, currency, case): + mcase = "attr" + if case != "abs": + mcase = "obl" + return self.to_cardinal(number, case=mcase) + + def _cents_verbose(self, number, currency, case): + mcase = "attr" + if case != "abs": + mcase = "obl" + return self.to_cardinal(number, case=mcase) + + def to_currency( + self, + val, + currency="RUB", + cents=True, + separator=",", + adjective=False, + case="abs", + ): + """ + Args: + val: Numeric value + currency (str): Currency code + cents (bool): Verbose cents + separator (str): Cent separator + adjective (bool): Prefix currency name with adjective + Returns: + str: Formatted string + + """ + left, right, is_negative = parse_currency_parts(val) + + try: + cr1, cr2 = self.CURRENCY_FORMS[currency] + devise = cr1[0] + centime = cr2[0] + except KeyError: + raise NotImplementedError( + 'Currency code "%s" not implemented for "%s"' + % (currency, self.__class__.__name__) + ) + + minus_str = "%s " % self.negword.strip() if is_negative else "" + money_str = self._money_verbose(left, currency, case) + cents_str = ( + self._cents_verbose(right, currency, case) + if cents + else self._cents_terse(right, currency) + ) + + return "%s%s %s%s %s %s" % ( + minus_str, + money_str, + devise, # always singular + separator, + cents_str, + centime, + ) + + def to_ordinal_num(self, number): + self.verify_ordinal(number) + return str(number) + "-й" + + def to_year(self, year, case="abs"): + return self.to_cardinal(year, case=case) + + def makecase(self, number, case, clazz): + # print("ZZZZ", number, CARDINALS[number]) + if case in CARDINALS[number]: + return CARDINALS[number][case].replace("д*", clazz) + else: + if CARDINALS[number]["abs"][-1] in "а": + return ( + CARDINALS[number]["abs"].replace("д*", clazz) + + CARDINALS["casesuffix_voc"][case] + ) + else: + return ( + CARDINALS[number]["abs"].replace("д*", clazz) + + CARDINALS["casesuffix_cons"][case] + ) diff --git a/num2words/lang_CY.py b/num2words/lang_CY.py new file mode 100644 index 00000000..e5045129 --- /dev/null +++ b/num2words/lang_CY.py @@ -0,0 +1,607 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2023, Johannes Heinecke. 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 + +from .currency import parse_currency_parts +from .lang_EU import Num2Word_EU + +# Welsh numerals differs to many other languages since the counted +# object does not follow the numeral but is inserted between +# e.g. "23 hours" is +# tri awr ar hugain +# 3 hour on twenty +# in addition to that some numeral trigger a mutation on the following word +# either another numeral or the counted object +# (https://en.wikipedia.org/wiki/Consonant_mutation#Welsh) +# e.g. "23 dogs" (aspirated mutation, c -> ch) +# tri chi ar hugain +# 3 dog on twenty +# but "22 dogs" (soft mutation, c -> g) +# dau gi ar hugain +# 2 dog on twenty +# and "24 dogs" (no mutation) +# pedwar ci ar hugain +# 4 dog on twenty +# (BTW, the counted word is always in singular when following a numeral) +# numerals are mutated as well +# e.g. "300" +# tri chant +# 3 hundred +# "200" +# dau gant +# 2 hundred +# "500" +# pump cant +# 5 hundreds +# the numerals for 2, 3 and 4 are different in function of gender (MASC, FEM) +# 2 cats +# dwy gath + +# 2 dogs +# dau gi + +# 2000 +# dwy fil + +# 3000 +# tair mil + +# to add the counted object in the correct position use +# num2words(17, lang="cy", counted="ci", gender="masc") +# num2words(17, lang="cy", counted="cath", gender="fem") +# if the number is > 99, use plural form of counted object +# num2words(117, lang="cy", counted="cathod", gender="fem") + + +# Globals +# ------- + +OBJ = "__OBJECT__" + +CARDINAL_WORDS = { + # masc, fem, triggers mutation + 0: [("dim", None), (OBJ, None)], + 1: [("un", None), (OBJ, None)], + 2: [("dau", "SM"), (OBJ, None)], + 3: [("tri", "AM"), (OBJ, None)], + 4: [("pedwar", None), (OBJ, None)], + 5: [("pump", None), (OBJ, None)], + 6: [("chwech", "AM"), (OBJ, None)], + 7: [("saith", None), (OBJ, None)], + 8: [("wyth", None), (OBJ, None)], + 9: [("naw", None), (OBJ, None)], + 10: [("deg", None), (OBJ, None)], + 11: [("un", None), (OBJ, None), ("ar ddeg", None)], + 12: [("deuddeg", None), (OBJ, None)], + 13: [("tri", "AM"), (OBJ, None), ("ar ddeg", None)], + 14: [("pedwar", None), (OBJ, None), ("ar ddeg", None)], + 15: [("pymtheg", None), (OBJ, None)], + 16: [("un", None), (OBJ, None), ("ar bymtheg", None)], + 17: [("dau", "SM"), (OBJ, None), ("ar bymtheg", None)], + 18: [("deunaw", None), (OBJ, None)], + 19: [("pedwar", None), ("ar bymtheg", None)], +} + +CARDINAL_WORDS_FEM = { + # masc, fem, triggers mutation + 0: [("dim", None), (OBJ, None)], + 1: [("un", None), (OBJ, None)], + 2: [("dwy", "SM"), (OBJ, None)], + 3: [("tair", None), (OBJ, None)], + 4: [("pedair", None), (OBJ, None)], + 5: [("pump", None), (OBJ, None)], + 6: [("chwech", "AM"), (OBJ, None)], + 7: [("saith", None), (OBJ, None)], + 8: [("wyth", None), (OBJ, None)], + 9: [("naw", None), (OBJ, None)], + 10: [("deg", None), (OBJ, None)], + 11: [("un", None), (OBJ, None), ("ar ddeg", None)], + 12: [("deuddeg", None), (OBJ, None)], + 13: [("tair", None), (OBJ, None), ("ar ddeg", None)], + 14: [("pedair", None), (OBJ, None), ("ar ddeg", None)], + 15: [("pymtheg", None), (OBJ, None)], + 16: [("un", None), (OBJ, None), ("ar bymtheg", None)], + 17: [("dwy", "SM"), (OBJ, None), ("ar bymtheg", None)], + 18: [("deunaw", None), (OBJ, None)], + 19: [("pedair", None), ("ar bymtheg", None)], +} + +MILLION_WORDS = { + 3: ("mil", None), + 6: ("miliwn", None), + 9: ("biliwn", None), + 12: ("triliwn", None), + 15: ("cwadriliwn", None), + 18: ("cwintiliwn", None), + 21: ("secsttiliwn", None), + 24: ("septiliwn", None), + 27: ("octiliwn", None), + 30: ("noniliwn", None), + 33: ("dengiliwn", None), +} + +ORDINAL_WORDS = { + 0: [("dimfed", None), (OBJ, None)], + 1: [(OBJ, None), ("cyntaf", None)], + 2: [("ail", "SM"), (OBJ, None)], + 3: [("trydydd", None), (OBJ, None)], + 4: [("pedwerydd", None), (OBJ, None)], + 5: [("pumed", None), (OBJ, None)], + 6: [("chweched", None), (OBJ, None)], + 7: [("saithfed", None), (OBJ, None)], + 8: [("wythfed", None), (OBJ, None)], + 9: [("nawfed", None), (OBJ, None)], + 10: [("degfed", None), (OBJ, None)], + 11: [("unfed", "SM"), (OBJ, None), ("ar ddeg", None)], + 12: [("deuddegfed", None), (OBJ, None)], + 13: [("trydydd", None), (OBJ, None), ("ar ddeg", None)], + 14: [("pedwerydd", None), (OBJ, None), ("ar ddeg", None)], + 15: [("pymthegfed", None), (OBJ, None)], + 16: [("unfed", None), (OBJ, None), ("ar bymtheg", None)], + 17: [("ail", "SM"), (OBJ, None), ("ar bymtheg", None)], + 18: [("deunawfed", None), (OBJ, None)], + 19: [("pedwerydd", None), (OBJ, None), ("ar bymtheg", None)], +} +ORDINAL_WORDS_FEM = { + 0: [("dimfed", None), (OBJ, None)], + 1: [(OBJ, None), ("gyntaf", None)], + 2: [("ail", "SM"), (OBJ, None)], + 3: [("trydedd", "SM"), (OBJ, None)], + 4: [("pedwaredd", "SM"), (OBJ, None)], + 5: [("pumed", None), (OBJ, None)], + 6: [("chweched", None), (OBJ, None)], + 7: [("saithfed", None), (OBJ, None)], + 8: [("wythfed", None), (OBJ, None)], + 9: [("nawfed", None), (OBJ, None)], + 10: [("degfed", None), (OBJ, None)], + 11: [("unfed", "SM"), (OBJ, None), ("ar ddeg", None)], + 12: [("deuddegfed", None), (OBJ, None)], + 13: [("trydedd", "SM"), (OBJ, None), ("ar ddeg", None)], + 14: [("pedwaredd", "SM"), (OBJ, None), ("ar ddeg", None)], + 15: [("pymthegfed", None), (OBJ, None)], + 16: [("unfed", None), (OBJ, None), ("ar bymtheg", None)], + 17: [("ail", "SM"), (OBJ, None), ("ar bymtheg", None)], + 18: [("deunawfed", None), (OBJ, None)], + 19: [("pedwaredd", None), (OBJ, None), ("ar bymtheg", None)], +} + +# The script can extrapolate the missing numbers from the base forms. +STR_TENS = { + 1: [("ugain", None), (OBJ, None)], + 2: [("deugain", None), (OBJ, None)], + 3: [("trigain", None), (OBJ, None)], + 4: [("pedwar ugain", None), (OBJ, None)], +} + +ORD_STR_TENS = { + 1: [("ugainfed", None), (OBJ, None)], + 2: [("deugainfed", None), (OBJ, None)], + 3: [("trigainfed", None), (OBJ, None)], + 4: [("pedwar ugainfed", None), (OBJ, None)], +} + +STR_TENS_INFORMAL = { + 1: ("undeg", None), + 2: ("dauddeg", None), + 3: ("trideg", None), + 4: ("pedwardeg", None), + 5: ("pumdeg", None), + 6: ("chwedeg", None), + 7: ("saithdeg", None), + 8: ("wythdeg", None), + 9: ("nawdeg", None), +} + + +GENERIC_DOLLARS = ("dolar", "dolarau") +GENERIC_CENTS = ("ceiniog", "ceiniogau") + +CURRENCIES_FEM = ["GBP"] + + +class Num2Word_CY(Num2Word_EU): + CURRENCY_FORMS = { + # currency code: (sg, pl), (sg, pl) + # in Welsh a noun after a numeral is ALWAYS in the singular + "EUR": (("euro", "euros"), GENERIC_CENTS), + "USD": (GENERIC_DOLLARS, GENERIC_CENTS), + "GBP": (("punt", "punnoedd"), ("ceiniog", "ceiniogau")), + "CNY": (("yuan", "yuans"), ("ffen", "ffens")), + } + + MINUS_PREFIX_WORD = "meinws " + FLOAT_INFIX_WORD = " pwynt " + +# def setup(self): +# Num2Word_EU.setup(self) + + def __init__(self): + pass + + def float_to_words(self, float_number): + # if ordinal: + # prefix = self.to_ordinal(int(float_number)) + # else: + prefix = self.to_cardinal(int(float_number)) + float_part = str(float_number).split(".")[1] + postfix = " ".join( + # Drops the trailing zero and comma + [self.to_cardinal(int(c)) for c in float_part] + ) + return prefix + Num2Word_CY.FLOAT_INFIX_WORD + postfix + + def hundred_group( + self, number, informal=False, gender="masc", ordinal=False + ): + hundreds = number // 100 + until100 = number % 100 # 0 - 99 + # list group of number words and mutation info (for the following word) + result = ( + [] + ) + if gender == "fem": + CW = CARDINAL_WORDS_FEM + else: + if ordinal: + CW = ORDINAL_WORDS + else: + CW = CARDINAL_WORDS + + if hundreds > 0: + if hundreds > 1: + result.extend((CARDINAL_WORDS[hundreds])) + result.extend([("cant", None), (OBJ, None)]) + if until100: + if until100 in [ + 1, + 8, + 11, + 16, + 20, + 21, + 31, + 36, + 41, + 48, + 61, + 68, + 71, + 81, + 88, + 91, + ]: + result.append(("ac", None)) + else: + result.append(("a", "AM")) + if until100: + # if informal: + # pass + if not ordinal and until100 >= 50 and until100 <= 59: + units = number % 10 + if hundreds > 0: + if units == 0: + result.append(("hanner", None)) + elif units == 1: + result.extend([("hanner ac un", None), (OBJ, None)]) + else: + result.append(("hanner a", "AM")) + result.extend(CW[units]) + else: + if units == 0: + result.extend([("hanner cant", None), (OBJ, None)]) + elif units == 1: + result.extend( + [("hanner cant ac un", None), (OBJ, None)] + ) + else: + result.append(("hanner cant a", "AM")) + result.extend(CW[units]) + else: + if (number < 20 and number > 0) or ( + number == 0 and hundreds == 0 + ): + if gender == "fem": + result.extend(CARDINAL_WORDS_FEM[int(number)]) + else: + result.extend(CARDINAL_WORDS[int(number)]) + + else: + tens = until100 // 20 + units = number % 20 + if ordinal and units == 0: + degau = ORD_STR_TENS.get(tens) + else: + degau = STR_TENS.get(tens) + + if units != 0: + if tens > 1: + result.extend(CW[units]) + if degau: + result.append(("a", "AM")) + result.extend(degau) + else: + result.extend(CW[units]) + if degau: + result.append(("ar", "SM")) + result.extend(degau) + elif degau: + result.extend(degau) + return result + + def to_ordinal(self, number, informal=False, gender="masc"): + if number < 20: + return makestring(ORDINAL_WORDS[number]) + if number == 100: + return "canfed" + elif number > 100: + raise NotImplementedError("The given number is too large.") + + return self.to_cardinal( + number, informal=False, gender=gender, ordinal=True + ) + + def to_cardinal( + self, + number, + informal=False, + gender="masc", + ordinal=False, + counted=None, + raw=False, + ): + negative = False + if number < 0: + negative = True + number = -1 * number + if number == 0: + if raw: + return CARDINAL_WORDS[0] + else: + return makestring(CARDINAL_WORDS[0]) + elif not number < 999 * 10**33: + raise NotImplementedError("The given number is too large.") + + elif isinstance(number, float): + return self.float_to_words(number) + + # split in groups of 10**3 + # groups of three digits starting from right (units (1 - 999), + # thousands, millions, ...) + groups = ( + [] + ) + lowestgroup = ( + None # find the lowest group of 3 digits > 0 for the ordinals + ) + for pot in [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36]: + gr = (number % 10**pot) // 10 ** (pot - 3) + groups.append((gr, pot)) + if gr and not lowestgroup: + lowestgroup = gr + # print("groups", groups) + + result = [] + if negative: + result.append(("meinws", None)) + + for gr, pot in reversed(groups): + if gr: + # print("AAAA", gr, pot, gender) + if pot == 6: + g = "fem" # mil (1000) is feminine + elif pot == 3: + g = gender # units depend on the following noun + else: + g = "masc" # millions etc are masculine + # "mil" is feminine + if gr > 1 or pot == 3: + words = self.hundred_group( + gr, + informal=informal, + gender=g, + ordinal=ordinal and (lowestgroup == gr), + ) + result += words + # print(">>>> ", words) + if pot > 3: + result.append(MILLION_WORDS[pot - 3]) + if raw: + # need to be able trigger correct mutation on currencies + return result + else: + if number < 100: + return makestring(result, counted=counted) + else: + if counted: + result.extend([("o", "SM"), (counted, None)]) + return makestring(result) + + def to_currency( + self, val, currency="EUR", cents=True, separator=",", adjective=False + ): + """ + Args: + val: Numeric value + currency (str): Currency code + cents (bool): Verbose cents + separator (str): Cent separator + adjective (bool): Prefix currency name with adjective + Returns: + str: Formatted string + + """ + left, right, is_negative = parse_currency_parts(val) + try: + cr1, cr2 = self.CURRENCY_FORMS[currency] + + except KeyError: + raise NotImplementedError( + 'Currency code "%s" not implemented for "%s"' + % (currency, self.__class__.__name__) + ) + + # if adjective and currency in self.CURRENCY_ADJECTIVES: + # cr1 = prefix_currency(self.CURRENCY_ADJECTIVES[currency], cr1) + + minus_str = "%s " % self.negword.strip() if is_negative else "" + money_str = self._money_verbose(left, currency) + cents_str = ( + self._cents_verbose(right, currency) + if cents + else self._cents_terse(right, currency) + ) + + if right == 0: + # no pence + return "%s%s" % ( + minus_str, + money_str, + # self.pluralize(right, cr2) + ) + elif left == 0: + # no pounds + return "%s%s" % ( + minus_str, + cents_str, + # self.pluralize(right, cr2) + ) + + return "%s%s%s %s" % ( + minus_str, + money_str, + # self.pluralize(left, cr1), + separator, + cents_str, + # self.pluralize(right, cr2) + ) + + def _money_verbose(self, number, currency): + # used in super().to_currency(), we need to add gender + # here for feminine currencies + # if currency in CURRENCIES_FEM: # always true in this context + if number > 100: + m = self.to_cardinal(number, gender="fem", raw=True) + # if currency in self.CURRENCY_FORMS: + c = self.CURRENCY_FORMS[currency][0][1] + m.append(("o", "SM")) + m.append((c, None)) + # else: + # c = currency + # m.append((c, None)) + return makestring(m) + else: + # if number > 1: + m = self.to_cardinal(number, gender="fem", raw=True) + # elif number == 0: + # m = self.to_cardinal(number, gender="fem", raw=True) + # else: + # m = [(OBJ, None)] + # if currency in self.CURRENCY_FORMS: + c = self.CURRENCY_FORMS[currency][0][0] + # else: + # c = currency + # print("eeeeeeeee", m) + # m.append((c, None)) + # print("fffffffff", m) + return makestring(m, counted=c) + # else: + # return self.to_cardinal(number, raw=True) + + def _cents_verbose(self, number, currency): + if number == 0: + return "" + # elif number > 100: + # m = self.to_cardinal(number, raw=True) + # # if currency in self.CURRENCY_FORMS: + # c = self.CURRENCY_FORMS[currency][0][1] + # m.append(("o", "SM")) + # m.append((c, None)) + # # else: + # # c = currency + # # m.append((c, None)) + # return makestring(m) + else: + if number > 1: + m = self.to_cardinal(number, raw=True) + else: + m = [(OBJ, None)] + # if currency in self.CURRENCY_FORMS: + c = self.CURRENCY_FORMS[currency][1][0] + # else: + # c = currency + return makestring(m, counted=c) + + +def makestring(result, counted=None): + # concatenate numberwords with correct mutation + out = [] + lastmut = None + for w, mut in result: + if w == OBJ: + if not counted: + continue + else: + w = counted + counted = None # only first position + if lastmut: + out.append(mutate(w, lastmut)) + else: + out.append(w) + lastmut = mut + return " ".join(out) + + +def mutate(word, mutation): + # print("uuu", word, mutation) + if mutation == "SM": + return softmutation(word) + elif mutation == "AM": + return aspiratedmutation(word) + # return word # does not occur + + +def softmutation(word): + # print("SM<<<<%s>" % word) + if word[0] == "p" and word[1] != "h": + return "b" + word[1:] + elif word[0] == "t" and word[1] != "h": + return "d" + word[1:] + elif word[0] == "c" and word[1] != "h": + return "g" + word[1:] + elif word[0] == "b" or word[0] == "m": + return "f" + word[1:] + elif word[0] == "d" and word[1] != "d": + return "d" + word + elif word.startswith("ll"): + return word[1:] + elif word.startswith("rh"): + return "r" + word[2:] + elif word == "ugain": + return "hugain" + else: + return word + + +def aspiratedmutation(word): + if word[0] == "p" and word[1] != "h": + return "ph" + word[1:] + elif word[0] == "t" and word[1] != "h": + return "th" + word[1:] + elif word[0] == "c" and word[1] != "h": + return "ch" + word[1:] + else: + return word diff --git a/num2words/lang_CZ.py b/num2words/lang_CZ.py index 548c48bb..04c44a07 100644 --- a/num2words/lang_CZ.py +++ b/num2words/lang_CZ.py @@ -102,10 +102,13 @@ def to_cardinal(self, number): n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + self._int2word(int(right))) return u'%s %s %s' % ( self._int2word(int(left)), self.pointword, - self._int2word(int(right)) + decimal_part ) else: return self._int2word(int(n)) diff --git a/num2words/lang_DE.py b/num2words/lang_DE.py index f6816979..ad61b18e 100644 --- a/num2words/lang_DE.py +++ b/num2words/lang_DE.py @@ -17,10 +17,20 @@ from __future__ import print_function, unicode_literals +import re + from .lang_EU import Num2Word_EU class Num2Word_DE(Num2Word_EU): + CURRENCY_FORMS = { + 'EUR': (('Euro', 'Euro'), ('Cent', 'Cent')), + 'GBP': (('Pfund', 'Pfund'), ('Penny', 'Pence')), + 'USD': (('Dollar', 'Dollar'), ('Cent', 'Cent')), + 'CNY': (('Yuan', 'Yuan'), ('Jiao', 'Fen')), + 'DEM': (('Mark', 'Mark'), ('Pfennig', 'Pfennig')), + } + GIGA_SUFFIX = "illiarde" MEGA_SUFFIX = "illion" @@ -45,7 +55,7 @@ def setup(self): self.errmsg_toobig = "Die Zahl %s muss kleiner als %s sein." self.exclude_title = [] - lows = ["non", "okt", "sept", "sext", "quint", "quadr", "tr", "b", "m"] + lows = ["Non", "Okt", "Sept", "Sext", "Quint", "Quadr", "Tr", "B", "M"] units = ["", "un", "duo", "tre", "quattuor", "quin", "sex", "sept", "okto", "novem"] tens = ["dez", "vigint", "trigint", "quadragint", "quinquagint", @@ -107,7 +117,7 @@ def merge(self, curr, next): def to_ordinal(self, value): self.verify_ordinal(value) - outword = self.to_cardinal(value) + outword = self.to_cardinal(value).lower() for key in self.ords: if outword.endswith(key): outword = outword[:len(outword) - len(key)] + self.ords[key] @@ -118,6 +128,13 @@ def to_ordinal(self, value): # Exception: "hundertste" is usually preferred over "einhundertste" if res == "eintausendste" or res == "einhundertste": res = res.replace("ein", "", 1) + # ... similarly for "millionste" etc. + res = re.sub(r'eine ([a-z]+(illion|illiard)ste)$', + lambda m: m.group(1), res) + # Ordinals involving "Million" etc. are written without a space. + # see https://de.wikipedia.org/wiki/Million#Sprachliches + res = re.sub(r' ([a-z]+(illion|illiard)ste)$', + lambda m: m.group(1), res) return res @@ -125,22 +142,13 @@ def to_ordinal_num(self, value): self.verify_ordinal(value) return str(value) + "." - def to_currency(self, val, longval=True, old=False): - hightxt = "Euro" - lowtxt = "Cent" - if old: - hightxt = "Mark" - lowtxt = "Pfennig/e" - - cents = int(round(val*100)) - res = self.to_splitnum(cents, hightxt=hightxt, lowtxt=lowtxt, - jointxt="und", longval=longval) - + def to_currency(self, val, currency='EUR', cents=True, separator=' und', + adjective=False): + result = super(Num2Word_DE, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) # Handle exception, in german is "ein Euro" and not "eins Euro" - if res.startswith("eins "): - res = res.replace("eins ", "ein ", 1) - - return res + return result.replace("eins ", "ein ") def to_year(self, val, longval=True): if not (val // 100) % 10: diff --git a/num2words/lang_DK.py b/num2words/lang_DK.py index 1a09094b..50ab110c 100644 --- a/num2words/lang_DK.py +++ b/num2words/lang_DK.py @@ -21,7 +21,7 @@ class Num2Word_DK(lang_EU.Num2Word_EU): - GIGA_SUFFIX = "illarder" + GIGA_SUFFIX = "illiarder" MEGA_SUFFIX = "illioner" def setup(self): @@ -61,6 +61,7 @@ def setup(self): "atten": "att", "nitten": "nitt", "tyve": "tyv"} + self.ordflag = False def merge(self, curr, next): ctext, cnum, ntext, nnum = curr + next diff --git a/num2words/lang_EN_NG.py b/num2words/lang_EN_NG.py new file mode 100644 index 00000000..7de81c84 --- /dev/null +++ b/num2words/lang_EN_NG.py @@ -0,0 +1,37 @@ +# -*- 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 unicode_literals + +from . import lang_EN + + +class Num2Word_EN_NG(lang_EN.Num2Word_EN): + + CURRENCY_FORMS = {'NGN': (('naira', 'naira'), ('kobo', 'kobo'))} + + CURRENCY_ADJECTIVES = {'NGN': 'Nigerian'} + + def to_currency( + self, val, currency='NGN', + kobo=True, separator=',', + adjective=False + ): + result = super(Num2Word_EN_NG, self).to_currency( + val, currency=currency, cents=kobo, separator=separator, + adjective=adjective) + return result diff --git a/num2words/lang_EO.py b/num2words/lang_EO.py new file mode 100644 index 00000000..ff47e69d --- /dev/null +++ b/num2words/lang_EO.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, 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 print_function, unicode_literals + +from .base import Num2Word_Base + + +class Num2Word_EO(Num2Word_Base): + CURRENCY_FORMS = { + "EUR": (("eŭro", "eŭroj"), ("centimo", "centimoj")), + "USD": (("dolaro", "dolaroj"), ("cendo", "cendoj")), + "FRF": (("franko", "frankoj"), ("centimo", "centimoj")), + "GBP": (("pundo", "pundoj"), ("penco", "pencoj")), + "CNY": (("juano", "juanoj"), ("feno", "fenoj")), + } + + GIGA_SUFFIX = "iliardo" + MEGA_SUFFIX = "iliono" + + def set_high_numwords(self, high): + cap = 3 + 6 * len(high) + + for word, n in zip(high, range(cap, 3, -6)): + if self.GIGA_SUFFIX: + self.cards[10 ** n] = word + self.GIGA_SUFFIX + + if self.MEGA_SUFFIX: + self.cards[10 ** (n - 3)] = word + self.MEGA_SUFFIX + + def gen_high_numwords(self, units, tens, lows): + out = [u + t for t in tens for u in units] + out.reverse() + return out + lows + + def setup(self): + lows = ["naŭ", "ok", "sep", "ses", "kvin", "kvar", "tr", "b", "m"] + units = ["", "un", "duo", "tre", "kvatuor", + "kvin", "seks", "septen", "okto", "novem"] + tens = ["dek", "vigint", "trigint", "kvadragint", "kvinkvagint", + "seksagint", "septuagint", "oktogint", "nonagint"] + + self.high_numwords = ["cent"] + self.gen_high_numwords(units, tens, + lows) + + self.negword = "minus " + self.pointword = "komo" + self.errmsg_nonnum = u"Sole nombroj povas esti konvertita en vortojn." + self.errmsg_toobig = ( + u"Tro granda nombro por esti konvertita en vortojn (abs(%s) > %s)." + ) + self.exclude_title = ["kaj", "komo", "minus"] + self.mid_numwords = [(1000, "mil"), (100, "cent"), (90, "naŭdek"), + (80, "okdek"), (70, "sepdek"), (60, "sesdek"), + (50, "kvindek"), (40, "kvardek"), (30, "tridek")] + self.low_numwords = ["dudek", "dek naŭ", "dek ok", "dek sep", + "dek ses", "dek kvin", "dek kvar", "dek tri", + "dek du", "dek unu", "dek", "naŭ", "ok", "sep", + "ses", "kvin", "kvar", "tri", "du", "unu", "nul"] + self.ords = { + "unu": "unua", + "du": "dua", + "tri": "tria", + "kvar": "kvara", + "kvin": "kvina", + "ses": "sesa", + "sep": "sepa", + "ok": "oka", + "naŭ": "naŭa", + "dek": "deka" + } + + def merge(self, curr, next): + ctext, cnum, ntext, nnum = curr + next + if cnum == 1 and nnum < 1000000: + return next + + if nnum >= 10**6 and cnum > 1: + return ("%s %sj" % (ctext, ntext), cnum + nnum) + + if nnum == 100: + return ("%s%s" % (ctext, ntext), cnum + nnum) + + return ("%s %s" % (ctext, ntext), cnum + nnum) + + def to_ordinal(self, value): + self.verify_ordinal(value) + word = self.to_cardinal(value) + for src, repl in self.ords.items(): + if word.endswith(src): + word = word[:-len(src)] + repl + return word + + if word.endswith("o"): + word = word[:-1] + "a" + elif word.endswith("oj"): + word = word[:-2] + "a" + else: + word = word + "a" + return word + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + out = str(value) + out += "a" + return out + + def to_currency(self, val, currency="EUR", cents=True, separator=" kaj", + adjective=False): + result = super(Num2Word_EO, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result + + def pluralize(self, n, forms): + form = 0 if n <= 1 else 1 + return forms[form] diff --git a/num2words/lang_ES.py b/num2words/lang_ES.py index 482a4141..de2d1e13 100644 --- a/num2words/lang_ES.py +++ b/num2words/lang_ES.py @@ -15,17 +15,197 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301 USA -from __future__ import print_function, unicode_literals +from __future__ import division, print_function, unicode_literals + +import math from .lang_EU import Num2Word_EU +GENERIC_DOLLARS = ('dólar', 'dólares') +GENERIC_CENTS = ('centavo', 'centavos') +CURRENCIES_UNA = ('SLL', 'SEK', 'NOK', 'CZK', 'DKK', 'ISK', + 'SKK', 'GBP', 'CYP', 'EGP', 'FKP', 'GIP', + 'LBP', 'SDG', 'SHP', 'SSP', 'SYP', 'INR', + 'IDR', 'LKR', 'MUR', 'NPR', 'PKR', 'SCR', + 'ESP', 'TRY', 'ITL') +CENTS_UNA = ('EGP', 'JOD', 'LBP', 'SDG', 'SSP', 'SYP') + class Num2Word_ES(Num2Word_EU): CURRENCY_FORMS = { - 'EUR': (('euro', 'euros'), ('centimo', 'centimos')), - 'ESP': (('peseta', 'pesetas'), ('centimo', 'centimos')), - 'USD': (('dolar', 'dolares'), ('centavo', 'centavos')), - 'PEN': (('sol', 'soles'), ('centimo', 'centimos')), + 'EUR': (('euro', 'euros'), ('céntimo', 'céntimos')), + 'ESP': (('peseta', 'pesetas'), ('céntimo', 'céntimos')), + 'USD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'PEN': (('sol', 'soles'), ('céntimo', 'céntimos')), + 'CRC': (('colón', 'colones'), GENERIC_CENTS), + 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'GBP': (('libra', 'libras'), ('penique', 'peniques')), + 'RUB': (('rublo', 'rublos'), ('kopeyka', 'kopeykas')), + 'SEK': (('corona', 'coronas'), ('öre', 'öre')), + 'NOK': (('corona', 'coronas'), ('øre', 'øre')), + 'PLN': (('zloty', 'zlotys'), ('grosz', 'groszy')), + 'MXN': (('peso', 'pesos'), GENERIC_CENTS), + 'RON': (('leu', 'leus'), ('ban', 'bani')), + 'INR': (('rupia', 'rupias'), ('paisa', 'paisas')), + 'HUF': (('florín', 'florines'), ('fillér', 'fillér')), + 'FRF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'CNY': (('yuan', 'yuanes'), ('fen', 'jiaos')), + 'CZK': (('corona', 'coronas'), ('haléř', 'haléř')), + 'NIO': (('córdoba', 'córdobas'), GENERIC_CENTS), + 'VES': (('bolívar', 'bolívares'), ('céntimo', 'céntimos')), + 'BRL': (('real', 'reales'), GENERIC_CENTS), + 'CHF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'JPY': (('yen', 'yenes'), ('sen', 'sen')), + 'KRW': (('won', 'wones'), ('jeon', 'jeon')), + 'KPW': (('won', 'wones'), ('chon', 'chon')), + 'TRY': (('lira', 'liras'), ('kuruş', 'kuruş')), + 'ZAR': (('rand', 'rands'), ('céntimo', 'céntimos')), + 'KZT': (('tenge', 'tenges'), ('tïın', 'tïın')), + 'UAH': (('hryvnia', 'hryvnias'), ('kopiyka', 'kopiykas')), + 'THB': (('baht', 'bahts'), ('satang', 'satang')), + 'AED': (('dirham', 'dirhams'), ('fils', 'fils')), + 'AFN': (('afghani', 'afghanis'), ('pul', 'puls')), + 'ALL': (('lek ', 'leke'), ('qindarkë', 'qindarka')), + 'AMD': (('dram', 'drams'), ('luma', 'lumas')), + 'ANG': (('florín', 'florines'), GENERIC_CENTS), + 'AOA': (('kwanza', 'kwanzas'), ('céntimo', 'céntimos')), + 'ARS': (('peso', 'pesos'), GENERIC_CENTS), + 'AWG': (('florín', 'florines'), GENERIC_CENTS), + 'AZN': (('manat', 'manat'), ('qəpik', 'qəpik')), + 'BBD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BDT': (('taka', 'takas'), ('paisa', 'paisas')), + 'BGN': (('lev', 'leva'), ('stotinka', 'stotinki')), + 'BHD': (('dinar', 'dinares'), ('fils', 'fils')), + 'BIF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'BMD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BND': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BOB': (('boliviano', 'bolivianos'), GENERIC_CENTS), + 'BSD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BTN': (('ngultrum', 'ngultrum'), ('chetrum', 'chetrum')), + 'BWP': (('pula', 'pulas'), ('thebe', 'thebes')), + 'BYN': (('rublo', 'rublos'), ('kópek', 'kópeks')), + 'BYR': (('rublo', 'rublos'), ('kópek', 'kópeks')), + 'BZD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'CDF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'CLP': (('peso', 'pesos'), GENERIC_CENTS), + 'COP': (('peso', 'pesos'), GENERIC_CENTS), + 'CUP': (('peso', 'pesos'), GENERIC_CENTS), + 'CVE': (('escudo', 'escudos'), GENERIC_CENTS), + 'CYP': (('libra', 'libras'), ('céntimo', 'céntimos')), + 'DJF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'DKK': (('corona', 'coronas'), ('øre', 'øre')), + 'DOP': (('peso', 'pesos'), GENERIC_CENTS), + 'DZD': (('dinar', 'dinares'), ('céntimo', 'céntimos')), + 'ECS': (('sucre', 'sucres'), GENERIC_CENTS), + 'EGP': (('libra', 'libras'), ('piastra', 'piastras')), + 'ERN': (('nakfa', 'nakfas'), ('céntimo', 'céntimos')), + 'ETB': (('birr', 'birrs'), ('céntimo', 'céntimos')), + 'FJD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'FKP': (('libra', 'libras'), ('penique', 'peniques')), + 'GEL': (('lari', 'laris'), ('tetri', 'tetris')), + 'GHS': (('cedi', 'cedis'), ('pesewa', 'pesewas')), + 'GIP': (('libra', 'libras'), ('penique', 'peniques')), + 'GMD': (('dalasi', 'dalasis'), ('butut', 'bututs')), + 'GNF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'GTQ': (('quetzal', 'quetzales'), GENERIC_CENTS), + 'GYD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'HKD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'HNL': (('lempira', 'lempiras'), GENERIC_CENTS), + 'HRK': (('kuna', 'kunas'), ('lipa', 'lipas')), + 'HTG': (('gourde', 'gourdes'), ('céntimo', 'céntimos')), + 'IDR': (('rupia', 'rupias'), ('céntimo', 'céntimos')), + 'ILS': (('séquel', 'séqueles'), ('agora', 'agoras')), + 'IQD': (('dinar', 'dinares'), ('fils', 'fils')), + 'IRR': (('rial', 'riales'), ('dinar', 'dinares')), + 'ISK': (('corona', 'coronas'), ('eyrir', 'aurar')), + 'ITL': (('lira', 'liras'), ('céntimo', 'céntimos')), + 'JMD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'JOD': (('dinar', 'dinares'), ('piastra', 'piastras')), + 'KES': (('chelín', 'chelines'), ('céntimo', 'céntimos')), + 'KGS': (('som', 'som'), ('tyiyn', 'tyiyn')), + 'KHR': (('riel', 'rieles'), ('céntimo', 'céntimos')), + 'KMF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'KWD': (('dinar', 'dinares'), ('fils', 'fils')), + 'KYD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'LAK': (('kip', 'kips'), ('att', 'att')), + 'LBP': (('libra', 'libras'), ('piastra', 'piastras')), + 'LKR': (('rupia', 'rupias'), ('céntimo', 'céntimos')), + 'LRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'LSL': (('loti', 'lotis'), ('céntimo', 'céntimos')), + 'LTL': (('lita', 'litas'), ('céntimo', 'céntimos')), + 'LVL': (('lat', 'lats'), ('céntimo', 'céntimos')), + 'LYD': (('dinar', 'dinares'), ('dírham', 'dírhams')), + 'MAD': (('dírham', 'dirhams'), ('céntimo', 'céntimos')), + 'MDL': (('leu', 'lei'), ('ban', 'bani')), + 'MGA': (('ariary', 'ariaris'), ('iraimbilanja', 'iraimbilanja')), + 'MKD': (('denar', 'denares'), ('deni', 'denis')), + 'MMK': (('kiat', 'kiats'), ('pya', 'pyas')), + 'MNT': (('tugrik', 'tugriks'), ('möngö', 'möngö')), + 'MOP': (('pataca', 'patacas'), ('avo', 'avos')), + 'MRO': (('ouguiya', 'ouguiyas'), ('khoums', 'khoums')), + 'MRU': (('ouguiya', 'ouguiyas'), ('khoums', 'khoums')), + 'MUR': (('rupia', 'rupias'), ('céntimo', 'céntimos')), + 'MVR': (('rufiyaa', 'rufiyaas'), ('laari', 'laari')), + 'MWK': (('kuacha', 'kuachas'), ('tambala', 'tambalas')), + 'MYR': (('ringgit', 'ringgit'), ('céntimo', 'céntimos')), + 'MZN': (('metical', 'metical'), GENERIC_CENTS), + 'NAD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'NGN': (('naira', 'nairas'), ('kobo', 'kobo')), + 'NPR': (('rupia', 'rupias'), ('paisa', 'paisas')), + 'NZD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'OMR': (('rial', 'riales'), ('baisa', 'baisa')), + 'PAB': (('balboa', 'balboas'), ('centésimo', 'centésimos')), + 'PGK': (('kina', 'kinas'), ('toea', 'toea')), + 'PHP': (('peso', 'pesos'), GENERIC_CENTS), + 'PKR': (('rupia', 'rupias'), ('paisa', 'paisas')), + 'PLZ': (('zloty', 'zlotys'), ('grosz', 'groszy')), + 'PYG': (('guaraní', 'guaranís'), ('céntimo', 'céntimos')), + 'QAR': (('rial', 'riales'), ('dírham', 'dírhams')), + 'QTQ': (('quetzal', 'quetzales'), GENERIC_CENTS), + 'RSD': (('dinar', 'dinares'), ('para', 'para')), + 'RUR': (('rublo', 'rublos'), ('kopek', 'kopeks')), + 'RWF': (('franco', 'francos'), ('céntimo', 'céntimos')), + 'SAR': (('riyal', 'riales'), ('halala', 'halalas')), + 'SBD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'SCR': (('rupia', 'rupias'), ('céntimo', 'céntimos')), + 'SDG': (('libra', 'libras'), ('piastra', 'piastras')), + 'SGD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'SHP': (('libra', 'libras'), ('penique', 'peniques')), + 'SKK': (('corona', 'coronas'), ('halier', 'haliers')), + 'SLL': (('leona', 'leonas'), ('céntimo', 'céntimos')), + 'SRD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'SSP': (('libra', 'libras'), ('piastra', 'piastras')), + 'STD': (('dobra', 'dobras'), ('céntimo', 'céntimos')), + 'SVC': (('colón', 'colones'), GENERIC_CENTS), + 'SYP': (('libra', 'libras'), ('piastra', 'piastras')), + 'SZL': (('lilangeni', 'emalangeni'), ('céntimo', 'céntimos')), + 'TJS': (('somoni', 'somonis'), ('dirame', 'dirames')), + 'TMT': (('manat', 'manat'), ('tenge', 'tenge')), + 'TND': (('dinar', 'dinares'), ('milésimo', 'milésimos')), + 'TOP': (('paanga', 'paangas'), ('céntimo', 'céntimos')), + 'TTD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'TWD': (('nuevo dólar', 'nuevos dólares'), ('céntimo', 'céntimos')), + 'TZS': (('chelín', 'chelines'), ('céntimo', 'céntimos')), + 'UAG': (('hryvnia', 'hryvnias'), ('kopiyka', 'kopiykas')), + 'UGX': (('chelín', 'chelines'), ('céntimo', 'céntimos')), + 'UYU': (('peso', 'pesos'), ('centésimo', 'centésimos')), + 'UZS': (('sum', 'sum'), ('tiyin', 'tiyin')), + 'VEF': (('bolívar fuerte', 'bolívares fuertes'), + ('céntimo', 'céntimos')), + 'VND': (('dong', 'dongs'), ('xu', 'xu')), + 'VUV': (('vatu', 'vatu'), ('nenhum', 'nenhum')), + 'WST': (('tala', 'tala'), GENERIC_CENTS), + 'XAF': (('franco CFA', 'francos CFA'), ('céntimo', 'céntimos')), + 'XCD': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'XOF': (('franco CFA', 'francos CFA'), ('céntimo', 'céntimos')), + 'XPF': (('franco CFP', 'francos CFP'), ('céntimo', 'céntimos')), + 'YER': (('rial', 'riales'), ('fils', 'fils')), + 'YUM': (('dinar', 'dinares'), ('para', 'para')), + 'ZMW': (('kwacha', 'kwachas'), ('ngwee', 'ngwee')), + 'ZRZ': (('zaire', 'zaires'), ('likuta', 'makuta')), + 'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), + 'ZWL': (GENERIC_DOLLARS, ('céntimo', 'céntimos')), } # //CHECK: Is this sufficient?? @@ -37,9 +217,13 @@ def setup(self): self.high_numwords = self.gen_high_numwords([], [], lows) self.negword = "menos " self.pointword = "punto" - self.errmsg_nonnum = "Solo números pueden ser convertidos a palabras." + self.errmsg_nonnum = "type(%s) no es [long, int, float]" + self.errmsg_floatord = "El float %s no puede ser tratado como un" \ + " ordinal." + self.errmsg_negord = "El número negativo %s no puede ser tratado" \ + " como un ordinal." self.errmsg_toobig = ( - "Numero muy grande para ser convertido a palabras." + "abs(%s) deber ser inferior a %s." ) self.gender_stem = "o" self.exclude_title = ["y", "menos", "punto"] @@ -51,7 +235,7 @@ def setup(self): "veintiséis", "veinticinco", "veinticuatro", "veintitrés", "veintidós", "veintiuno", "veinte", "diecinueve", "dieciocho", "diecisiete", - "dieciseis", "quince", "catorce", "trece", "doce", + "dieciséis", "quince", "catorce", "trece", "doce", "once", "diez", "nueve", "ocho", "siete", "seis", "cinco", "cuatro", "tres", "dos", "uno", "cero"] self.ords = {1: "primer", @@ -120,47 +304,47 @@ def merge(self, curr, next): def to_ordinal(self, value): self.verify_ordinal(value) - try: - if value == 0: - text = "" - elif value <= 10: - text = "%s%s" % (self.ords[value], self.gender_stem) - elif value <= 12: - text = ( - "%s%s%s" % (self.ords[10], self.gender_stem, - self.to_ordinal(value - 10)) - ) - elif value <= 100: - dec = (value // 10) * 10 - text = ( - "%s%s %s" % (self.ords[dec], self.gender_stem, - self.to_ordinal(value - dec)) - ) - elif value <= 1e3: - cen = (value // 100) * 100 - text = ( - "%s%s %s" % (self.ords[cen], self.gender_stem, - self.to_ordinal(value - cen)) - ) - elif value < 1e18: - # dec contains the following: - # [ 1e3, 1e6): 1e3 - # [ 1e6, 1e9): 1e6 - # [ 1e9, 1e12): 1e9 - # [1e12, 1e15): 1e12 - # [1e15, 1e18): 1e15 - dec = 10 ** ((((len(str(int(value))) - 1) / 3 - 1) + 1) * 3) - part = int(float(value / dec) * dec) - cardinal = ( - self.to_cardinal(part / dec) if part / dec != 1 else "" + if value == 0: + text = "" + elif value <= 10: + text = "%s%s" % (self.ords[value], self.gender_stem) + elif value <= 12: + text = ( + "%s%s%s" % (self.ords[10], self.gender_stem, + self.to_ordinal(value - 10)) + ) + elif value <= 100: + dec = (value // 10) * 10 + text = ( + "%s%s %s" % (self.ords[dec], self.gender_stem, + self.to_ordinal(value - dec)) ) - text = ( - "%s%s%s %s" % (cardinal, self.ords[dec], self.gender_stem, - self.to_ordinal(value - part)) - ) - else: - text = self.to_cardinal(value) - except KeyError: + elif value <= 1e3: + cen = (value // 100) * 100 + text = ( + "%s%s %s" % (self.ords[cen], self.gender_stem, + self.to_ordinal(value - cen)) + ) + elif value < 1e18: + # Round down to the nearest 1e(3n) + # dec contains the following: + # [ 1e3, 1e6): 1e3 + # [ 1e6, 1e9): 1e6 + # [ 1e9, 1e12): 1e9 + # [1e12, 1e15): 1e12 + # [1e15, 1e18): 1e15 + dec = 1000 ** int(math.log(int(value), 1000)) + + # Split the parts before and after the word for 'dec' + # eg (12, 345) = divmod(12_345, 1_000) + high_part, low_part = divmod(value, dec) + + cardinal = self.to_cardinal(high_part) if high_part != 1 else "" + text = ( + "%s%s%s %s" % (cardinal, self.ords[dec], self.gender_stem, + self.to_ordinal(low_part)) + ) + else: text = self.to_cardinal(value) return text.strip() @@ -168,10 +352,57 @@ def to_ordinal_num(self, value): self.verify_ordinal(value) return "%s%s" % (value, "º" if self.gender_stem == 'o' else "ª") - def to_currency(self, val, currency='EUR', cents=True, seperator=' con', + def to_currency(self, val, currency='EUR', cents=True, separator=' con', adjective=False): result = super(Num2Word_ES, self).to_currency( - val, currency=currency, cents=cents, seperator=seperator, + val, currency=currency, cents=cents, separator=separator, adjective=adjective) - # Handle exception, in spanish is "un euro" and not "uno euro" - return result.replace("uno", "un") + # Handle exception: In Spanish it's "un euro" and not "uno euro", + # except in these currencies, where it's "una": leona, corona, + # libra, lira, rupia, lempira, peseta. + # The same goes for "veintiuna", "treinta y una"... + # Also, this needs to be handled separately for "dollars" and + # "cents". + # All "cents" are masculine except for: piastra. + # Source: https://www.rae.es/dpd/una (section 2.2) + + # split "dollars" part from "cents" part + list_result = result.split(separator + " ") + + # "DOLLARS" PART (list_result[0]) + + # Feminine currencies ("una libra", "trescientas libras"...) + if currency in CURRENCIES_UNA: + + # "una libra", "veintiuna libras", "treinta y una libras"... + list_result[0] = list_result[0].replace("uno", "una") + + # "doscientas libras", "trescientas libras"... + list_result[0] = list_result[0].replace("cientos", "cientas") + + # Masc.: Correct orthography for the specific case of "veintiún": + list_result[0] = list_result[0].replace("veintiuno", "veintiún") + + # Masculine currencies: general case ("un euro", "treinta y un + # euros"...): + list_result[0] = list_result[0].replace("uno", "un") + + # "CENTS" PART (list_result[1]) + + # Feminine "cents" ("una piastra", "veintiuna piastras"...) + if currency in CENTS_UNA: + + # "una piastra", "veintiuna piastras", "treinta y una piastras"... + list_result[1] = list_result[1].replace("uno", "una") + + # Masc.: Correct orthography for the specific case of "veintiún": + list_result[1] = list_result[1].replace("veintiuno", "veintiún") + + # Masculine "cents": general case ("un centavo", "treinta y un + # centavos"...): + list_result[1] = list_result[1].replace("uno", "un") + + # join back "dollars" part with "cents" part + result = (separator + " ").join(list_result) + + return result diff --git a/num2words/lang_ES_CR.py b/num2words/lang_ES_CR.py new file mode 100644 index 00000000..ee1d4440 --- /dev/null +++ b/num2words/lang_ES_CR.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2024, Randall Castro. 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 print_function, unicode_literals + +from .lang_ES import Num2Word_ES + + +class Num2Word_ES_CR(Num2Word_ES): + + def to_currency(self, val, longval=True, old=False): + result = self.to_splitnum(val, hightxt="colón/es", lowtxt="céntimo/s", + divisor=1, jointxt="y", longval=longval) + # Handle exception, in spanish is "un euro" and not "uno euro" + return result.replace("uno", "un") diff --git a/num2words/lang_ES_GT.py b/num2words/lang_ES_GT.py new file mode 100644 index 00000000..9bc4c750 --- /dev/null +++ b/num2words/lang_ES_GT.py @@ -0,0 +1,32 @@ +# -*- 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 print_function, unicode_literals + +from .lang_ES import Num2Word_ES + + +class Num2Word_ES_GT(Num2Word_ES): + + def to_currency(self, val, longval=True, old=False): + result = self.to_splitnum(val, hightxt="quetzal/es", + lowtxt="centavo/s", + divisor=1, jointxt="y", + longval=longval) + # Handle exception, in spanish is "un euro" + # and not "uno euro" + return result.replace("uno", "un") diff --git a/num2words/lang_ES_NI.py b/num2words/lang_ES_NI.py new file mode 100644 index 00000000..9e5f9e89 --- /dev/null +++ b/num2words/lang_ES_NI.py @@ -0,0 +1,33 @@ +# -*- 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 print_function, unicode_literals + +from .lang_ES import Num2Word_ES + + +class Num2Word_ES_NI(Num2Word_ES): + CURRENCY_FORMS = { + 'NIO': (('córdoba', 'córdobas'), ('centavo', 'centavos')), + } + + def to_currency(self, val, currency='NIO', cents=True, separator=' con', + adjective=False): + result = super(Num2Word_ES, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result.replace("uno", "un") diff --git a/num2words/lang_EU.py b/num2words/lang_EU.py index 4a301af7..0ff74ab2 100644 --- a/num2words/lang_EU.py +++ b/num2words/lang_EU.py @@ -26,6 +26,7 @@ class Num2Word_EU(Num2Word_Base): CURRENCY_FORMS = { 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BYN': (('rouble', 'roubles'), ('kopek', 'kopeks')), 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), # repalced by EUR 'EEK': (('kroon', 'kroons'), ('sent', 'senti')), @@ -41,11 +42,18 @@ class Num2Word_EU(Num2Word_Base): 'NOK': (('krone', 'kroner'), ('øre', 'øre')), 'PLN': (('zloty', 'zlotys', 'zlotu'), ('grosz', 'groszy')), 'MXN': (('peso', 'pesos'), GENERIC_CENTS), - 'RON': (('leu', 'lei'), ('ban', 'bani')), + 'RON': (('leu', 'lei', 'de lei'), ('ban', 'bani', 'de bani')), + 'INR': (('rupee', 'rupees'), ('paisa', 'paise')), + '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')) + } CURRENCY_ADJECTIVES = { 'AUD': 'Australian', + 'BYN': 'Belarusian', 'CAD': 'Canadian', 'EEK': 'Estonian', 'USD': 'US', @@ -53,6 +61,11 @@ class Num2Word_EU(Num2Word_Base): 'NOK': 'Norwegian', 'MXN': 'Mexican', 'RON': 'Romanian', + 'INR': 'Indian', + 'HUF': 'Hungarian', + 'ISK': 'íslenskar', + 'UZS': 'Uzbekistan', + 'SAR': 'Saudi' } GIGA_SUFFIX = "illiard" diff --git a/num2words/lang_FA.py b/num2words/lang_FA.py new file mode 100644 index 00000000..3597b08c --- /dev/null +++ b/num2words/lang_FA.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2018, Abdullah Alhazmy, Alhazmy13. All Rights Reserved. +# Copyright (c) 2020, Hamidreza Kalbasi. All Rights Reserved. +# Copyright (c) 2023, Nika Soltani Tehrani. 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 decimal import Decimal +from math import floor + +farsiOnes = [ + "", "یک", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", + "نه", + "ده", + "یازده", + "دوازده", + "سیزده", + "چهارده", + "پانزده", + "شانزده", + "هفده", + "هجده", + "نوزده", +] + +farsiTens = [ + "", + "ده", + "بیست", + "سی", + "چهل", + "پنجاه", + "شصت", + "هفتاد", + "هشتاد", + "نود", +] + +farsiHundreds = [ + "", + "صد", + "دویست", + "سیصد", + "چهارصد", + "پانصد", + "ششصد", + "هفتصد", + "هشتصد", + "نهصد", +] + +farsiBig = [ + '', + ' هزار', + ' میلیون', + " میلیارد", + ' تریلیون', + " تریلیارد", +] + +farsiFrac = ["", "دهم", "صدم"] +farsiFracBig = ["", "هزارم", "میلیونیم", "میلیاردیم"] + +farsiSeperator = ' و ' + + +class Num2Word_FA(object): + # Those are unused + errmsg_toobig = "Too large" + MAXNUM = 10 ** 36 + + def __init__(self): + self.number = 0 + + def float2tuple(self, value): + pre = int(value) + + # Simple way of finding decimal places to update the precision + self.precision = abs(Decimal(str(value)).as_tuple().exponent) + + post = abs(value - pre) * 10**self.precision + if abs(round(post) - post) < 0.01: + # We generally floor all values beyond our precision (rather than + # rounding), but in cases where we have something like 1.239999999, + # which is probably due to python's handling of floats, we actually + # want to consider it as 1.24 instead of 1.23 + post = int(round(post)) + else: + post = int(floor(post)) + return pre, post, self.precision + + def cardinal3(self, number): + if number <= 19: + return farsiOnes[number] + if number < 100: + x, y = divmod(number, 10) + if y == 0: + return farsiTens[x] + return farsiTens[x] + farsiSeperator + farsiOnes[y] + x, y = divmod(number, 100) + if y == 0: + return farsiHundreds[x] + return farsiHundreds[x] + farsiSeperator + self.cardinal3(y) + + def cardinalPos(self, number): + x = number + res = '' + for b in farsiBig: + x, y = divmod(x, 1000) + if y == 0: + continue + yx = self.cardinal3(y) + b + if b == ' هزار' and y == 1: + yx = 'هزار' + if res == '': + res = yx + else: + res = yx + farsiSeperator + res + return res + + def fractional(self, number, level): + if number == 5: + return "نیم" + x = self.cardinalPos(number) + ld3, lm3 = divmod(level, 3) + ltext = (farsiFrac[lm3] + " " + farsiFracBig[ld3]).strip() + return x + " " + ltext + + def to_currency(self, value): + return self.to_cardinal(value) + " تومان" + + def to_ordinal(self, number): + r = self.to_cardinal(number) + if r[-1] == 'ه' and r[-2] == 'س': + return r[:-1] + 'وم' + return r + 'م' + + def to_year(self, value): + return self.to_cardinal(value) + + @staticmethod + def to_ordinal_num(value): + return str(value)+"م" + + def to_cardinal(self, number): + if number < 0: + return "منفی " + self.to_cardinal(-number) + if number == 0: + return "صفر" + x, y, level = self.float2tuple(number) + if y == 0: + return self.cardinalPos(x) + if x == 0: + return self.fractional(y, level) + return self.cardinalPos(x) + farsiSeperator + self.fractional(y, level) diff --git a/num2words/lang_FI.py b/num2words/lang_FI.py index 3b6bae6e..7a3621b8 100644 --- a/num2words/lang_FI.py +++ b/num2words/lang_FI.py @@ -682,10 +682,10 @@ def to_year(self, val, suffix=None, longval=True): suffix = suffix or " ennen ajanlaskun alkua" return self.to_cardinal(val).replace(" ", "") + suffix - def to_currency(self, val, currency="EUR", cents=True, seperator=" ja", + def to_currency(self, val, currency="EUR", cents=True, separator=" ja", adjective=False): return super(Num2Word_FI, self).to_currency( - val, currency=currency, cents=cents, seperator=seperator, + val, currency=currency, cents=cents, separator=separator, adjective=adjective) def splitnum(self, value, options): diff --git a/num2words/lang_FR.py b/num2words/lang_FR.py index 4524cb56..f843205c 100644 --- a/num2words/lang_FR.py +++ b/num2words/lang_FR.py @@ -21,6 +21,14 @@ class Num2Word_FR(Num2Word_EU): + CURRENCY_FORMS = { + 'EUR': (('euro', 'euros'), ('centime', 'centimes')), + 'USD': (('dollar', 'dollars'), ('cent', 'cents')), + 'FRF': (('franc', 'francs'), ('centime', 'centimes')), + 'GBP': (('livre', 'livres'), ('penny', 'pence')), + 'CNY': (('yuan', 'yuans'), ('fen', 'jiaos')), + } + def setup(self): Num2Word_EU.setup(self) @@ -29,7 +37,9 @@ def setup(self): self.errmsg_nonnum = ( u"Seulement des nombres peuvent être convertis en mots." ) - self.errmsg_toobig = u"Nombre trop grand pour être converti en mots." + self.errmsg_toobig = ( + u"Nombre trop grand pour être converti en mots (abs(%s) > %s)." + ) self.exclude_title = ["et", "virgule", "moins"] self.mid_numwords = [(1000, "mille"), (100, "cent"), (80, "quatre-vingts"), (60, "soixante"), @@ -89,13 +99,12 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) out = str(value) - out += {"1": "er"}.get(out[-1], "me") + out += "er" if value == 1 else "me" return out - def to_currency(self, val, longval=True, old=False): - hightxt = "euro/s" - if old: - hightxt = "franc/s" - cents = int(round(val*100)) - return self.to_splitnum(cents, hightxt=hightxt, lowtxt="centime/s", - divisor=100, jointxt="et", longval=longval) + def to_currency(self, val, currency='EUR', cents=True, separator=' et', + adjective=False): + result = super(Num2Word_FR, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result diff --git a/num2words/lang_FR_DZ.py b/num2words/lang_FR_DZ.py index 928520e6..176d700a 100644 --- a/num2words/lang_FR_DZ.py +++ b/num2words/lang_FR_DZ.py @@ -21,8 +21,13 @@ class Num2Word_FR_DZ(Num2Word_FR): - def to_currency(self, val, longval=True, cents=True, jointxt="virgule"): - return self.to_splitnum( - val, hightxt="dinard/s", lowtxt="centime/s", divisor=1, - jointxt=jointxt, longval=longval, cents=cents - ) + CURRENCY_FORMS = { + 'DIN': (('dinard', 'dinards'), ('centime', 'centimes')), + } + + def to_currency(self, val, currency='DIN', cents=True, separator=' et', + adjective=False): + result = super(Num2Word_FR, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + return result diff --git a/num2words/lang_HE.py b/num2words/lang_HE.py index d98a84a7..8898d667 100644 --- a/num2words/lang_HE.py +++ b/num2words/lang_HE.py @@ -18,48 +18,54 @@ from __future__ import print_function, unicode_literals +from .base import Num2Word_Base +from .compat import to_s +from .currency import parse_currency_parts from .utils import get_digits, splitbyx ZERO = (u'אפס',) ONES = { - 1: (u'אחד',), - 2: (u'שנים',), - 3: (u'שלש',), - 4: (u'ארבע',), - 5: (u'חמש',), - 6: (u'שש',), - 7: (u'שבע',), - 8: (u'שמנה',), - 9: (u'תשע',), + 1: (u'אחת', u'אחד', u'אחת', u'אחד', + u'ראשונה', u'ראשון', u'ראשונות', u'ראשונים'), + 2: (u'שתיים', u'שניים', u'שתי', u'שני', + u'שנייה', u'שני', u'שניות', u'שניים'), + 3: (u'שלוש', u'שלושה', u'שלוש', u'שלושת', + u'שלישית', u'שלישי', u'שלישיות', u'שלישיים'), + 4: (u'ארבע', u'ארבעה', u'ארבע', u'ארבעת', + u'רביעית', u'רביעי', u'רביעיות', u'רביעיים'), + 5: (u'חמש', u'חמישה', u'חמש', u'חמשת', + u'חמישית', u'חמישי', u'חמישיות', u'חמישיים'), + 6: (u'שש', u'שישה', u'שש', u'ששת', + u'שישית', u'שישי', u'שישיות', u'שישיים'), + 7: (u'שבע', u'שבעה', u'שבע', u'שבעת', + u'שביעית', u'שביעי', u'שביעיות', u'שביעיים'), + 8: (u'שמונה', u'שמונה', u'שמונה', u'שמונת', + u'שמינית', u'שמיני', u'שמיניות', u'שמיניים'), + 9: (u'תשע', u'תשעה', u'תשע', u'תשעת', + u'תשיעית', u'תשיעי', u'תשיעיות', u'תשיעיים'), } TENS = { - 0: (u'עשר',), - 1: (u'אחד עשרה',), - 2: (u'שנים עשרה',), - 3: (u'שלש עשרה',), - 4: (u'ארבע עשרה',), - 5: (u'חמש עשרה',), - 6: (u'שש עשרה',), - 7: (u'שבע עשרה',), - 8: (u'שמנה עשרה',), - 9: (u'תשע עשרה',), + 0: (u'עשר', u'עשרה', u'עשר', u'עשרת', + u'עשירית', u'עשירי', u'עשיריות', u'עשיריים'), + 1: (u'עשרה', u'עשר'), + 2: (u'שתים עשרה', u'שנים עשר'), } TWENTIES = { 2: (u'עשרים',), - 3: (u'שלשים',), + 3: (u'שלושים',), 4: (u'ארבעים',), 5: (u'חמישים',), - 6: (u'ששים',), + 6: (u'שישים',), 7: (u'שבעים',), - 8: (u'שמנים',), + 8: (u'שמונים',), 9: (u'תשעים',), } -HUNDRED = { - 1: (u'מאה',), +HUNDREDS = { + 1: (u'מאה', u'מאת'), 2: (u'מאתיים',), 3: (u'מאות',) } @@ -67,25 +73,106 @@ THOUSANDS = { 1: (u'אלף',), 2: (u'אלפיים',), + 3: (u'אלפים', 'אלפי'), } -AND = u'ו' - +LARGE = { + 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'ויגינטיליוני') +} -def pluralize(n, forms): - # gettext implementation: - # (n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2) +AND = u'ו' - form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 if n != 0 else 2 +DEF = u'ה' - return forms[form] +MAXVAL = int('1' + '0'*66) -def int2word(n): - if n > 9999: # doesn't yet work for numbers this big - raise NotImplementedError() +def chunk2word(n, i, x, gender='f', construct=False, + ordinal=False, plural=False): + words = [] + n1, n2, n3 = get_digits(x) + + if n3 > 0: + if construct and n == 100: + words.append(HUNDREDS[n3][1]) + elif n3 <= 2: + words.append(HUNDREDS[n3][0]) + else: + words.append(ONES[n3][0] + ' ' + HUNDREDS[3][0]) + + if n2 > 1: + words.append(TWENTIES[n2][0]) + + if i == 0 or x >= 11: + male = gender == 'm' or i > 0 + cop = (2*(construct and i == 0)+4*ordinal+2*plural) * (n < 11) + if n2 == 1: + if n1 == 0: + words.append(TENS[n1][male + cop]) + elif n1 == 2: + words.append(TENS[n1][male]) + else: + words.append(ONES[n1][male] + ' ' + TENS[1][male]) + elif n1 > 0: + words.append(ONES[n1][male + cop]) + + construct_last = construct and (n % 1000 ** i == 0) + + if i == 1: + if x >= 11: + words[-1] = words[-1] + ' ' + THOUSANDS[1][0] + elif n1 == 0: + words.append(TENS[0][3] + ' ' + THOUSANDS[3][construct_last]) + elif n1 <= 2: + words.append(THOUSANDS[n1][0]) + else: + words.append(ONES[n1][3] + ' ' + THOUSANDS[3][construct_last]) + + elif i > 1: + if x >= 11: + words[-1] = words[-1] + ' ' + LARGE[i - 1][construct_last] + elif n1 == 0: + words.append(TENS[0][1 + 2*construct_last] + ' ' + + LARGE[i - 1][construct_last]) + elif n1 == 1: + words.append(LARGE[i - 1][0]) + else: + words.append(ONES[n1][1 + 2*(construct_last or x == 2)] + ' ' + + LARGE[i - 1][construct_last]) + + return words + + +def int2word(n, gender='f', construct=False, + ordinal=False, definite=False, plural=False): + assert n == int(n) + assert not construct or not ordinal + assert ordinal or (not definite and not plural) + if n >= MAXVAL: + raise OverflowError('abs(%s) must be less than %s.' % (n, MAXVAL)) if n == 0: + if ordinal: + return DEF + ZERO[0] return ZERO[0] words = [] @@ -98,53 +185,143 @@ def int2word(n): if x == 0: continue - n1, n2, n3 = get_digits(x) + words += chunk2word(n, i, x, gender=gender, construct=construct, + ordinal=ordinal, plural=plural) - if n3 > 0: - if n3 <= 2: - words.append(HUNDRED[n3][0]) - else: - words.append(ONES[n3][0]) - words.append(HUNDRED[3][0]) + # https://hebrew-academy.org.il/2017/01/30/%D7%95-%D7%94%D7%97%D7%99%D7%91%D7%95%D7%A8-%D7%91%D7%9E%D7%A1%D7%A4%D7%A8%D7%99%D7%9D # noqa + if len(words) > 1: + words[-1] = AND + words[-1] - if n2 > 1: - words.append(TWENTIES[n2][0]) - - if n2 == 1: - words.append(TENS[n1][0]) - elif n1 > 0 and not (i > 0 and x == 1): - words.append(ONES[n1][0]) + if ordinal and (n >= 11 or definite): + words[0] = DEF + words[0] - if i > 0: - if i <= 2: - words.append(THOUSANDS[i][0]) - else: - words.append(ONES[i][0]) - words.append(THOUSANDS[1][0]) - - if len(words) > 1: - words[-1] = AND + words[-1] return ' '.join(words) -def n2w(n): - return int2word(int(n)) - - -def to_currency(n, currency='EUR', cents=True, seperator=','): - raise NotImplementedError() - - -class Num2Word_HE(object): - def to_cardinal(self, number): - return n2w(number) - - def to_ordinal(self, number): - raise NotImplementedError() - - -if __name__ == '__main__': - yo = Num2Word_HE() - nums = [1, 11, 21, 24, 99, 100, 101, 200, 211, 345, 1000, 1011] - for num in nums: - print(num, yo.to_cardinal(num)) +class Num2Word_HE(Num2Word_Base): + CURRENCY_FORMS = { + 'ILS': ((u'שקל', u'שקלים'), (u'אגורה', u'אגורות')), + 'EUR': ((u'אירו', u'אירו'), (u'סנט', u'סנטים')), + 'USD': ((u'דולר', u'דולרים'), (u'סנט', u'סנטים')), + } + + CURRENCY_GENDERS = { + 'ILS': ('m', 'f'), + 'EUR': ('m', 'm'), + 'USD': ('m', 'm'), + } + + def __init__(self, makaf='-'): + super(Num2Word_HE, self).__init__() + self.makaf = makaf + + def setup(self): + super(Num2Word_HE, self).setup() + self.negword = u'מינוס' + self.pointword = u'נקודה' + self.MAXVAL = MAXVAL + + def to_cardinal_float(self, value, gender='f'): + try: + float(value) == value + except (ValueError, TypeError, AssertionError, AttributeError): + raise TypeError(self.errmsg_nonnum % value) + + pre, post = self.float2tuple(float(value)) + + post = str(post) + post = '0'*(self.precision - len(post)) + post + + out = [self.to_cardinal(pre, gender=gender)] + if self.precision: + out.append(self.title(self.pointword)) + + for i in range(self.precision): + curr = int(post[i]) + out.append(to_s(self.to_cardinal(curr))) + + return ' '.join(out) + + def to_cardinal(self, value, gender='f', construct=False): + try: + assert int(value) == value + except (ValueError, TypeError, AssertionError): + # https://hebrew-academy.org.il/2019/12/03/%D7%A2%D7%9C-%D7%94%D7%91%D7%A2%D7%AA-%D7%94%D7%9E%D7%A1%D7%A4%D7%A8-%D7%94%D7%9E%D7%A2%D7%95%D7%A8%D7%91 # noqa + return self.to_cardinal_float(value, gender=gender) + + out = "" + if value < 0: + value = abs(value) + out = "%s " % self.negword.strip() + + if value >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) + + return out + int2word(int(value), gender=gender, construct=construct) + + def to_ordinal(self, value, gender='m', definite=False, plural=False): + self.verify_ordinal(value) + + if value >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (value, self.MAXVAL)) + + return int2word(int(value), gender=gender, ordinal=True, + definite=definite, plural=plural) + + def pluralize(self, n, forms, currency=None, prefer_singular=False): + assert n == int(n) + form = 1 + if n == 1 or prefer_singular and ( + abs(n) >= 11 or n == 0 or currency != 'ILS'): + form = 0 + return forms[form] + + def to_currency(self, val, currency='ILS', cents=True, + separator=AND, adjective=False, + prefer_singular=False, prefer_singular_cents=False): + left, right, is_negative = parse_currency_parts(val) + + if not separator.startswith(' '): + separator = ' ' + separator + + try: + cr1, cr2 = self.CURRENCY_FORMS[currency] + + except KeyError: + raise NotImplementedError( + 'Currency code "%s" not implemented for "%s"' % + (currency, self.__class__.__name__)) + + minus_str = "%s " % self.negword.strip() if is_negative else "" + try: + gender1, gender2 = self.CURRENCY_GENDERS[currency] + except KeyError: + gender1 = gender2 = '' + + money_str = self.to_cardinal(left, gender=gender1, + construct=left == 2) + if cents: + cents_str = self.to_cardinal(right, gender=gender2, + construct=right == 2) + else: + cents_str = self._cents_terse(right, currency) + sep_parts = separator.split() + if sep_parts and sep_parts[-1] == AND: + separator += self.makaf + + strings = [ + minus_str, + money_str, + self.pluralize(left, cr1, currency=currency, + prefer_singular=prefer_singular), + separator, + cents_str, + self.pluralize(right, cr2, currency=currency, + prefer_singular=prefer_singular_cents) + ] + if left == 1: + strings[1], strings[2] = strings[2], strings[1] + if right == 1: + strings[4], strings[5] = strings[5], strings[4] + # In Hebrew the separator is along with the following word + return u'%s%s %s%s%s %s' % tuple(strings) diff --git a/num2words/lang_HU.py b/num2words/lang_HU.py new file mode 100644 index 00000000..1bf54cf8 --- /dev/null +++ b/num2words/lang_HU.py @@ -0,0 +1,165 @@ +# -*- 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 + +ZERO = 'nulla' + + +class Num2Word_HU(lang_EU.Num2Word_EU): + GIGA_SUFFIX = "illiárd" + MEGA_SUFFIX = "illió" + + def setup(self): + super(Num2Word_HU, self).setup() + + self.negword = "mínusz " + self.pointword = "egész" + + self.mid_numwords = [(1000, "ezer"), (100, "száz"), (90, "kilencven"), + (80, "nyolcvan"), (70, "hetven"), (60, "hatvan"), + (50, "ötven"), (40, "negyven"), (30, "harminc")] + + low_numwords = ["kilenc", "nyolc", "hét", "hat", "öt", "négy", "három", + "kettő", "egy"] + self.low_numwords = (['tizen' + w for w in low_numwords] + + ['tíz'] + + low_numwords) + self.low_numwords = (['huszon' + w for w in low_numwords] + + ['húsz'] + + self.low_numwords + + [ZERO]) + + self.partial_ords = { + 'nulla': 'nullad', + 'egy': 'egyed', + 'kettő': 'ketted', + 'három': 'harmad', + 'négy': 'negyed', + 'öt': 'ötöd', + 'hat': 'hatod', + 'hét': 'heted', + 'nyolc': 'nyolcad', + 'kilenc': 'kilenced', + 'tíz': 'tized', + 'húsz': 'huszad', + 'harminc': 'harmincad', + 'negyven': 'negyvened', + 'ötven': 'ötvened', + 'hatvan': 'hatvanad', + 'hetven': 'hetvened', + 'nyolcvan': 'nyolcvanad', + 'kilencven': 'kilencvened', + 'száz': 'század', + 'ezer': 'ezred', + 'illió': 'milliomod', + 'illiárd': 'milliárdod' + } + + def to_cardinal(self, value, zero=ZERO): + if int(value) != value: + return self.to_cardinal_float(value) + elif value < 0: + out = self.negword + self.to_cardinal(-value) + elif value == 0: + out = zero + elif zero == '' and value == 2: + out = 'két' + elif value < 30: + out = self.cards[value] + elif value < 100: + out = self.tens_to_cardinal(value) + elif value < 1000: + out = self.hundreds_to_cardinal(value) + elif value < 10**6: + out = self.thousands_to_cardinal(value) + else: + out = self.big_number_to_cardinal(value) + return out + + def tens_to_cardinal(self, value): + try: + return self.cards[value] + except KeyError: + return self.cards[value // 10 * 10] + self.to_cardinal(value % 10) + + def hundreds_to_cardinal(self, value): + hundreds = value // 100 + prefix = "száz" + if hundreds != 1: + prefix = self.to_cardinal(hundreds, zero="") + prefix + postfix = self.to_cardinal(value % 100, zero="") + return prefix + postfix + + def thousands_to_cardinal(self, value): + thousands = value // 1000 + prefix = "ezer" + if thousands != 1: + prefix = self.to_cardinal(thousands, zero="") + prefix + postfix = self.to_cardinal(value % 1000, zero="") + return prefix + ('' if value <= 2000 or not postfix else '-') + postfix + + def big_number_to_cardinal(self, value): + digits = len(str(value)) + digits = digits if digits % 3 != 0 else digits - 2 + exp = 10 ** (digits // 3 * 3) + rest = self.to_cardinal(value % exp, '') + return (self.to_cardinal(value // exp, '') + self.cards[exp] + + ('-' + rest if rest else '')) + + def to_ordinal(self, value): + if value < 0: + return self.negword + self.to_ordinal(-value) + if value == 1: + return 'első' + elif value == 2: + return 'második' + else: + out = self.to_cardinal(value) + for card_word, ord_word in self.partial_ords.items(): + if out[-len(card_word):] == card_word: + out = out[:-len(card_word)] + ord_word + break + return out + 'ik' + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return str(value) + '.' + + def to_year(self, val, suffix=None, longval=True): + # suffix is prefix here + prefix = '' + if val < 0 or suffix is not None: + val = abs(val) + prefix = (suffix + ' ' if suffix is not None else 'i. e. ') + return prefix + self.to_cardinal(val) + + def to_currency(self, val, currency='HUF', cents=True, separator=',', + adjective=False): + return super(Num2Word_HU, self).to_currency( + val, currency, cents, separator, adjective) + + def to_cardinal_float(self, value): + if abs(value) != value: + return self.negword + self.to_cardinal_float(-value) + left, right = str(value).split('.') + return (self.to_cardinal(int(left)) + + ' egész ' + + self.to_cardinal(int(right)) + + ' ' + self.partial_ords[self.cards[10 ** len(right)]]) diff --git a/num2words/lang_ID.py b/num2words/lang_ID.py index 9a2bbfcb..54e636f9 100644 --- a/num2words/lang_ID.py +++ b/num2words/lang_ID.py @@ -44,8 +44,8 @@ class Num2Word_ID(): errmsg_floatord = "Cannot treat float number as ordinal" errmsg_negord = "Cannot treat negative number as ordinal" - errmsg_toobig = "Too large" - max_num = 10 ** 36 + errmsg_toobig = "Number is too large to convert to words (abs(%s) > %s)." + MAXVAL = 10 ** 36 def split_by_koma(self, number): return str(number).split('.') @@ -169,8 +169,8 @@ def join(self, word_blocks, float_part): return ' '.join(word_list) + float_part def to_cardinal(self, number): - if number >= self.max_num: - raise OverflowError(self.errmsg_toobig % (number, self.max_num)) + if number >= self.MAXVAL: + raise OverflowError(self.errmsg_toobig % (number, self.MAXVAL)) minus = '' if number < 0: minus = 'min ' diff --git a/num2words/lang_IS.py b/num2words/lang_IS.py new file mode 100644 index 00000000..e29eb7a7 --- /dev/null +++ b/num2words/lang_IS.py @@ -0,0 +1,127 @@ +# -*- 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 + +# Genders +KK = 0 # Karlkyn (male) +KVK = 1 # Kvenkyn (female) +HK = 2 # Hvorugkyn (neuter) + +GENDERS = { + "einn": ("einn", "ein", "eitt"), + "tveir": ("tveir", "tvær", "tvö"), + "þrír": ("þrír", "þrjár", "þrjú"), + "fjórir": ("fjórir", "fjórar", "fjögur"), +} + +PLURALS = { + "hundrað": ("hundrað", "hundruð"), +} + + +class Num2Word_IS(lang_EU.Num2Word_EU): + + GIGA_SUFFIX = "illjarður" + MEGA_SUFFIX = "illjón" + + def setup(self): + lows = ["okt", "sept", "sext", "kvint", "kvaðr", "tr", "b", "m"] + self.high_numwords = self.gen_high_numwords([], [], lows) + + self.negword = "mínus " + self.pointword = "komma" + + # All words should be excluded, title case is not used in Icelandic + self.exclude_title = ["og", "komma", "mínus"] + + self.mid_numwords = [(1000, "þúsund"), (100, "hundrað"), + (90, "níutíu"), (80, "áttatíu"), (70, "sjötíu"), + (60, "sextíu"), (50, "fimmtíu"), (40, "fjörutíu"), + (30, "þrjátíu")] + self.low_numwords = ["tuttugu", "nítján", "átján", "sautján", + "sextán", "fimmtán", "fjórtán", "þrettán", + "tólf", "ellefu", "tíu", "níu", "átta", + "sjö", "sex", "fimm", "fjórir", "þrír", + "tveir", "einn", "núll"] + self.ords = {"einn": "fyrsti", + "tveir": "annar", + "þrír": "þriðji", + "fjórir": "fjórði", + "fimm": "fimmti", + "sex": "sjötti", + "sjö": "sjöundi", + "átta": "áttundi", + "níu": "níundi", + "tíu": "tíundi", + "ellefu": "ellefti", + "tólf": "tólfti"} + + def pluralize(self, n, noun): + form = 0 if (n % 10 == 1 and n % 100 != 11) else 1 + if form == 0: + return noun + elif self.GIGA_SUFFIX in noun: + return noun.replace(self.GIGA_SUFFIX, "illjarðar") + elif self.MEGA_SUFFIX in noun: + return noun.replace(self.MEGA_SUFFIX, "illjónir") + elif noun not in PLURALS: + return noun + return PLURALS[noun][form] + + def genderize(self, adj, noun): + last = adj.split()[-1] + if last not in GENDERS: + return adj + gender = KK + if "hund" in noun or "þús" in noun: + gender = HK + elif "illjarð" in noun: + gender = KK + elif "illjón" in noun: + gender = KVK + return adj.replace(last, GENDERS[last][gender]) + + def merge(self, lpair, rpair): + ltext, lnum = lpair + rtext, rnum = rpair + + if lnum == 1 and rnum < 100: + return (rtext, rnum) + elif lnum < rnum: + rtext = self.pluralize(lnum, rtext) + ltext = self.genderize(ltext, rtext) + return ("%s %s" % (ltext, rtext), lnum * rnum) + elif lnum > rnum and rnum in self.cards: + rtext = self.pluralize(lnum, rtext) + ltext = self.genderize(ltext, rtext) + return ("%s og %s" % (ltext, rtext), lnum + rnum) + return ("%s %s" % (ltext, rtext), lnum + rnum) + + def to_ordinal(self, value): + raise NotImplementedError + + def to_ordinal_num(self, value): + raise NotImplementedError + + def to_year(self, val, suffix=None, longval=True): + raise NotImplementedError + + def to_currency(self, val, longval=True): + raise NotImplementedError diff --git a/num2words/lang_IT.py b/num2words/lang_IT.py index f1eb0232..427e6d36 100644 --- a/num2words/lang_IT.py +++ b/num2words/lang_IT.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. -# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2018-2019, Filippo Costa. 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 @@ -17,6 +16,8 @@ from __future__ import unicode_literals +from .lang_EU import Num2Word_EU + # Globals # ------- @@ -44,56 +45,27 @@ ] -# Utils -# ===== - -def phonetic_contraction(string): - return (string - .replace("oo", "o") # ex. "centootto" - .replace("ao", "o") # ex. "settantaotto" - .replace("io", "o") # ex. "ventiotto" - .replace("au", "u") # ex. "trentauno" - ) - - -def exponent_length_to_string(exponent_length): - # We always assume `exponent` to be a multiple of 3. If it's not true, then - # Num2Word_IT.big_number_to_cardinal did something wrong. - prefix = EXPONENT_PREFIXES[exponent_length // 6] - if exponent_length % 6 == 0: - return prefix + "ilione" - else: - return prefix + "iliardo" - - -def accentuate(string): - # This is inefficient: it may do several rewritings when deleting - # half-sentence accents. However, it is the easiest method and speed is - # not crucial (duh), so... - return " ".join( - # Deletes half-sentence accents and accentuates the last "tre" - [w.replace("tré", "tre")[:-3] + "tré" - # We shouldn't accentuate a single "tre": is has to be a composite - # word. ~~~~~~~~~~ - if w[-3:] == "tre" and len(w) > 3 - # Deletes half-sentence accents anyway - # ~~~~~~~~~~~~~~~~~~~~~~ - else w.replace("tré", "tre") - for w in string.split() - ]) - - -def omitt_if_zero(number_to_string): - return "" if number_to_string == ZERO else number_to_string +GENERIC_DOLLARS = ('dollaro', 'dollari') +GENERIC_CENTS = ('centesimo', 'centesimi') +CURRENCIES_UNA = ('GBP') # Main class # ========== -class Num2Word_IT: +class Num2Word_IT(Num2Word_EU): + CURRENCY_FORMS = { + 'EUR': (('euro', 'euro'), GENERIC_CENTS), + 'USD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'GBP': (('sterlina', 'sterline'), ('penny', 'penny')), + 'CNY': (('yuan', 'yuan'), ('fen', 'fen')), + } MINUS_PREFIX_WORD = "meno " FLOAT_INFIX_WORD = " virgola " + def setup(self): + Num2Word_EU.setup(self) + def __init__(self): pass @@ -174,13 +146,13 @@ def to_cardinal(self, number): elif isinstance(number, float): string = self.float_to_words(number) elif number < 20: - string = CARDINAL_WORDS[number] + string = CARDINAL_WORDS[int(number)] elif number < 100: - string = self.tens_to_cardinal(number) + string = self.tens_to_cardinal(int(number)) elif number < 1000: - string = self.hundreds_to_cardinal(number) + string = self.hundreds_to_cardinal(int(number)) elif number < 1000000: - string = self.thousands_to_cardinal(number) + string = self.thousands_to_cardinal(int(number)) else: string = self.big_number_to_cardinal(number) return accentuate(string) @@ -195,9 +167,9 @@ def to_ordinal(self, number): elif number % 1 != 0: return self.float_to_words(number, ordinal=True) elif number < 20: - return ORDINAL_WORDS[number] + return ORDINAL_WORDS[int(number)] elif is_outside_teens and tens % 10 == 3: - # Gets ride of the accent ~~~~~~~~~~ + # Gets rid of the accent return self.to_cardinal(number)[:-1] + "eesimo" elif is_outside_teens and tens % 10 == 6: return self.to_cardinal(number) + "esimo" @@ -206,3 +178,64 @@ def to_ordinal(self, number): if string[-3:] == "mil": string += "l" return string + "esimo" + + def to_currency(self, val, currency='EUR', cents=True, separator=' e', + adjective=False): + result = super(Num2Word_IT, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + # Handle exception. In italian language is "un euro", + # "un dollaro" etc. (not "uno euro", "uno dollaro"). + # There is an exception, some currencies need "una": + # e.g. "una sterlina" + if currency in CURRENCIES_UNA: + list_result = result.split(" ") + if list_result[0] == "uno": + list_result[0] = list_result[0].replace("uno", "una") + result = " ".join(list_result) + result = result.replace("uno", "un") + return result + +# Utils +# ===== + + +def phonetic_contraction(string): + return (string + .replace("oo", "o") # ex. "centootto" + .replace("ao", "o") # ex. "settantaotto" + .replace("io", "o") # ex. "ventiotto" + .replace("au", "u") # ex. "trentauno" + .replace("iu", "u") # ex. "ventiunesimo" + ) + + +def exponent_length_to_string(exponent_length): + # We always assume `exponent` to be a multiple of 3. If it's not true, then + # Num2Word_IT.big_number_to_cardinal did something wrong. + prefix = EXPONENT_PREFIXES[exponent_length // 6] + if exponent_length % 6 == 0: + return prefix + "ilione" + else: + return prefix + "iliardo" + + +def accentuate(string): + # This is inefficient: it may do several rewritings when deleting + # half-sentence accents. However, it is the easiest method and speed is + # not crucial (duh), so... + return " ".join( + # Deletes half-sentence accents and accentuates the last "tre" + [w.replace("tré", "tre")[:-3] + "tré" + # We shouldn't accentuate a single "tre": is has to be a composite + # word. ~~~~~~~~~~ + if w[-3:] == "tre" and len(w) > 3 + # Deletes half-sentence accents anyway + # ~~~~~~~~~~~~~~~~~~~~~~ + else w.replace("tré", "tre") + for w in string.split() + ]) + + +def omitt_if_zero(number_to_string): + return "" if number_to_string == ZERO else number_to_string diff --git a/num2words/lang_JA.py b/num2words/lang_JA.py index 928dddf5..1e0e6222 100644 --- a/num2words/lang_JA.py +++ b/num2words/lang_JA.py @@ -335,6 +335,7 @@ def rendaku_merge_pairs(lpair, rpair): (1912, ("大正", "たいしょう")), (1926, ("昭和", "しょうわ")), (1989, ("平成", "へいせい")), + (2019, ("令和", "れいわ")), ] @@ -491,7 +492,7 @@ def to_year(self, val, suffix=None, longval=True, reading=False, return fmt % (era_name, era_year_words) - def to_currency(self, val, currency="JPY", cents=False, seperator="", + def to_currency(self, val, currency="JPY", cents=False, separator="", adjective=False, reading=False, prefer=None): left, right, is_negative = parse_currency_parts( val, is_int_with_cents=cents) diff --git a/num2words/lang_KN.py b/num2words/lang_KN.py new file mode 100644 index 00000000..3bc1ccae --- /dev/null +++ b/num2words/lang_KN.py @@ -0,0 +1,182 @@ +# -*- 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 + +from .lang_EU import Num2Word_EU + + +class Num2Word_KN(Num2Word_EU): + def set_high_numwords(self, high): + for n, word in self.high_numwords: + self.cards[10**n] = word + + def setup(self): + self.low_numwords = [ + "ತೊಂಬತ್ತೊಂಬತ್ತು", + "ತೊಂಬತ್ತೆಂಟು", + "ತೊಂಬತ್ತೇಳು", + "ತೊಂಬತ್ತಾರು", + "ತೊಂಬತ್ತೈದು", + "ತೊಂಬತ್ತ ನಾಲ್ಕು", + "ತೊಂಬತ್ತ ಮೂರು", + "ತೊಂಬತ್ತೆರಡು", + "ತೊಂಬತ್ತೊಂದು", + "ತೊಂಬತ್ತು", + "ಎಂಬತ್ತೊಂಬತ್ತು", + "ಎಂಬತ್ತೆಂಟು", + "ಎಂಬತ್ತೇಳು", + "ಎಂಬತ್ತಾರು", + "ಎಂಬತ್ತೈದು", + "ಎಂಬತ್ತ್ ನಾಲ್ಕು", + "ಎಂಬತ್ತ್ ಮೂರು", + "ಎಂಬತ್ತೆರಡು", + "ಎಂಬತ್ತೊಂದು", + "ಎಂಬತ್ತು", + "ಎಪ್ಪತ್ತೊಂಬತ್ತು", + "ಎಪ್ಪತ್ತೆಂಟು", + "ಎಪ್ಪತ್ತೇಳು", + "ಎಪ್ಪತ್ತಾರು", + "ಎಪ್ಪತ್ತೈದು", + "ಎಪ್ಪತ್ತ್ ನಾಲ್ಕು", + "ಎಪ್ಪತ್ತ್ ಮೂರು", + "ಎಪ್ಪತ್ತೆರಡು", + "ಎಪ್ಪತ್ತೊಂದು", + "ಎಪ್ಪತ್ತು", + "ಅರವತ್ತೊಂಬತ್ತು", + "ಅರವತ್ತೆಂಟು", + "ಅರವತ್ತೇಳು", + "ಅರವತ್ತಾರು", + "ಅರವತ್ತೈದು", + "ಅರವತ್ತ್ ನಾಲ್ಕು", + "ಅರವತ್ತ್ ಮೂರು", + "ಅರವತ್ತೆರಡು", + "ಅರವತ್ತೊಂದು", + "ಅರವತ್ತು", + "ಐವತ್ತೊಂಬತ್ತು", + "ಐವತ್ತೆಂಟು", + "ಐವತ್ತೇಳು", + "ಐವತ್ತಾರು", + "ಐವತ್ತೈದು", + "ಐವತ್ತ್ನಾಲ್ಕು", + "ಐವತ್ತಮೂರು", + "ಐವತ್ತೆರಡು", + "ಐವತ್ತೊಂದು", + "ಐವತ್ತು", + "ನಲವತ್ತೊಂಬತ್ತು", + "ನಲವತ್ತೆಂಟು", + "ನಲವತ್ತೇಳು", + "ನಲವತ್ತಾರು", + "ನಲವತ್ತೈದು", + "ನಲವತ್ತ್ ನಾಲ್ಕು", + "ನಲವತ್ತ್ ಮೂರು", + "ನಲವತ್ತ್ ಎರಡು", + "ನಲವತ್ತೊಂದು", + "ನಲವತ್ತು", + "ಮೂವತ್ತ್ ಒಂಬತ್ತು", + "ಮೂವತ್ಎಂಟು", + "ಮೂವತ್ಏಳು", + "ಮೂವತ್ಆರು", + "ಮೂವತ್ತ್ ಐದು", + "ಮೂವತ್ತ್ ನಾಲ್ಕು", + "ಮೂವತ್ತ್ ಮೂರು", + "ಮೂವತ್ತ್ಎರಡು", + "ಮೂವತ್ತ್ಒಂದು", + "ಮೂವತ್ತು", + "ಇಪ್ಪತ್ತ್ಒಂಬತ್ತು", + "ಇಪ್ಪತ್ತ್ಎಂಟು", + "ಇಪ್ಪತ್ತ್ಏಳು", + "ಇಪ್ಪತ್ತ್ಆರು", + "ಇಪ್ಪತ್ತ್ ಐದು", + "ಇಪ್ಪತ್ತ್ ನಾಲ್ಕು", + "ಇಪ್ಪತ್ತ್ ಮೂರು", + "ಇಪ್ಪತ್ತ್ ಎರಡು", + "ಇಪ್ಪತ್ತ್ ಒಂದು", + "ಇಪ್ಪತ್ತು", + "ಹತ್ತೊಂಬತ್ತು", + "ಹದಿನೆಂಟು", + "ಹದಿನೇಳು", + "ಹದಿನಾರು", + "ಹದಿನೈದು", + "ಹದಿನಾಲ್ಕು", + "ಹದಿಮೂರು", + "ಹನ್ನೆರಡು", + "ಹನ್ನೊಂದು", + "ಹತ್ತು", + "ಒಂಬತ್ತು", + "ಎಂಟು", + "ಏಳು", + "ಆರು", + "ಐದು", + "ನಾಲ್ಕು", + "ಮೂರು", + "ಎರಡು", + "ಒಂದು", + "ಸೊನ್ನೆ", + ] + + self.mid_numwords = [(100, "ನೂರು")] + + self.high_numwords = [(7, "ಕೋಟಿ"), (5, "ಒಂದು ಲಕ್ಷ"), (3, "ಸಾವಿರ")] + + self.pointword = "ಬಿಂದು" + + self.modifiers = [ + "್", + "ಾ", + "ಿ", + "ೀ", + "ೀ", + "ು", + "ೂ", + "ೃ", + "ೆ", + "ೇ", + "ೈ", + "ೊ", + "ೋ", + "ೌ", + "ೕ", + ] + + 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: + if ltext[-1] in self.modifiers: + return ("%s %s" % (ltext[:-1], rtext), lnum + rnum) + else: + 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_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)) + + def to_ordinal(self, value): + self.verify_ordinal(value) + outwords = self.to_cardinal(value) + if outwords[-1] in self.modifiers: + outwords = outwords[:-1] + ordinal_num = outwords + "ನೇ" + return ordinal_num diff --git a/num2words/lang_KO.py b/num2words/lang_KO.py index e192cc64..65f4531e 100644 --- a/num2words/lang_KO.py +++ b/num2words/lang_KO.py @@ -93,7 +93,7 @@ def merge(self, lpair, rpair): def to_ordinal(self, value): self.verify_ordinal(value) - if(value == 1): + if value == 1: return "첫 번째" outwords = self.to_cardinal(value).split(" ") lastwords = outwords[-1].split("백") @@ -123,7 +123,7 @@ def to_year(self, val, suffix=None, longval=True): return ("%s년" % valtext if not suffix else "%s %s년" % (suffix, valtext)) - def to_currency(self, val, currency="KRW", cents=False, seperator="", + def to_currency(self, val, currency="KRW", cents=False, separator="", adjective=False): left, right, is_negative = parse_currency_parts( val, is_int_with_cents=cents) diff --git a/num2words/lang_KZ.py b/num2words/lang_KZ.py new file mode 100644 index 00000000..67df20ed --- /dev/null +++ b/num2words/lang_KZ.py @@ -0,0 +1,133 @@ +# -*- 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 unicode_literals + +from .base import Num2Word_Base +from .utils import get_digits, splitbyx + +ZERO = 'нөл' + +ONES = { + 1: 'бір', + 2: 'екі', + 3: 'үш', + 4: 'төрт', + 5: 'бес', + 6: 'алты', + 7: 'жеті', + 8: 'сегіз', + 9: 'тоғыз', +} + +TEN = 'он' + +TWENTIES = { + 2: 'жиырма', + 3: 'отыз', + 4: 'қырық', + 5: 'елу', + 6: 'алпыс', + 7: 'жетпіс', + 8: 'сексен', + 9: 'тоқсан', +} + +HUNDRED = 'жүз' + +THOUSANDS = { + 1: 'мың', + 2: 'миллион', + 3: 'миллиард', + 4: 'триллион', + 5: 'квадриллион', + 6: 'квинтиллион', + 7: 'секстиллион', + 8: 'септиллион', + 9: 'октиллион', + 10: 'нониллион', +} + + +class Num2Word_KZ(Num2Word_Base): + CURRENCY_FORMS = { + 'USD': ('доллар', 'цент'), + 'KZT': ('теңге', 'тиын'), + } + + def setup(self): + self.negword = "минус" + self.pointword = "бүтін" + + def to_cardinal(self, number): + n = str(number).replace(',', '.') + if '.' in n: + left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + return u'%s %s %s' % ( + self._int2word(int(left)), + self.pointword, + (ZERO + ' ') * leading_zero_count + self._int2word(int(right)) + ) + else: + return self._int2word(int(n)) + + def pluralize(self, n, form): + return form + + def _cents_verbose(self, number, currency): + return self._int2word(number, currency == 'KZT') + + def _int2word(self, n, feminine=False): + if n < 0: + return ' '.join([self.negword, self._int2word(abs(n))]) + + if n == 0: + return ZERO + + words = [] + chunks = list(splitbyx(str(n), 3)) + i = len(chunks) + for x in chunks: + i -= 1 + + if x == 0: + continue + + n1, n2, n3 = get_digits(x) + + if n3 > 0: + if n3 > 1: + words.append(ONES[n3]) + words.append(HUNDRED) + + if n2 == 1: + words.append(TEN) + elif n2 > 1: + words.append(TWENTIES[n2]) + + if n1 > 0: + words.append(ONES[n1]) + + if i > 0: + words.append(THOUSANDS[i]) + + return ' '.join(words) + + def to_ordinal(self, number): + # TODO: Implement to_ordinal + raise NotImplementedError() diff --git a/num2words/lang_LT.py b/num2words/lang_LT.py index 8c6623e2..8f723e88 100644 --- a/num2words/lang_LT.py +++ b/num2words/lang_LT.py @@ -124,11 +124,14 @@ def to_cardinal(self, number): base_str, n = self.parse_minus(n) if '.' in n: left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + self._int2word(int(right))) return '%s%s %s %s' % ( base_str, self._int2word(int(left)), self.pointword, - self._int2word(int(right)) + decimal_part ) else: return "%s%s" % (base_str, self._int2word(int(n))) diff --git a/num2words/lang_LV.py b/num2words/lang_LV.py index 289c37f7..6e71c609 100644 --- a/num2words/lang_LV.py +++ b/num2words/lang_LV.py @@ -132,11 +132,14 @@ def to_cardinal(self, number): base_str, n = self.parse_minus(n) if '.' in n: left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + self._int2word(int(right))) return '%s%s %s %s' % ( base_str, self._int2word(int(left)), self.pointword, - self._int2word(int(right)) + decimal_part ) else: return "%s%s" % (base_str, self._int2word(int(n))) diff --git a/num2words/lang_NL.py b/num2words/lang_NL.py index ec052d31..7251e2ac 100644 --- a/num2words/lang_NL.py +++ b/num2words/lang_NL.py @@ -22,7 +22,10 @@ class Num2Word_NL(Num2Word_EU): CURRENCY_FORMS = { - 'EUR': (('euro', 'euros'), ('cent', 'cents')), + 'EUR': (('euro', 'euro'), ('cent', 'cent')), + 'GBP': (('pond', 'pond'), ('penny', 'pence')), + 'USD': (('dollar', 'dollar'), ('cent', 'cent')), + 'CNY': (('yuan', 'yuan'), ('jiao', 'fen')), } GIGA_SUFFIX = "iljard" @@ -73,7 +76,10 @@ def setup(self): "zes", "vijf", "vier", "drie", "twee", "één", "nul"] - self.ords = {"één": "eerst", + # Wiktionary says it is "nulde", not "nulte" or "nule" + # https://en.wiktionary.org/wiki/nulde + self.ords = {"nul": "nuld", + "één": "eerst", "twee": "tweed", "drie": "derd", "vier": "vierd", @@ -132,7 +138,7 @@ def to_ordinal(self, value): def to_ordinal_num(self, value): self.verify_ordinal(value) - return str(value) + "." + return str(value) + "e" def pluralize(self, n, forms): """ diff --git a/num2words/lang_NO.py b/num2words/lang_NO.py index 0fb43e43..b4d33380 100644 --- a/num2words/lang_NO.py +++ b/num2words/lang_NO.py @@ -23,6 +23,7 @@ class Num2Word_NO(lang_EU.Num2Word_EU): GIGA_SUFFIX = "illard" MEGA_SUFFIX = "illion" + CURRENCY_FORMS = {'NOK': (('krone', 'kroner'), ('øre', 'øre'))} def set_high_numwords(self, high): cap = 3 + 6 * len(high) @@ -50,19 +51,29 @@ def setup(self): "tolv", "elleve", "ti", "ni", "\xe5tte", "syv", "seks", "fem", "fire", "tre", "to", "en", "null"] - self.ords = {"en": "f\xf8rste", - "to": "andre", - "tre": "tredje", - "fire": "fjerde", - "fem": "femte", - "seks": "sjette", - "syv": "syvende", - "\xe5tte": "\xe5ttende", - "ni": "niende", - "ti": "tiende", - "elleve": "ellevte", - "tolv": "tolvte", - "tjue": "tjuende"} + self.ords_pl = {"to": "andre", + "tre": "tredje", + "fire": "fjerde", + "fem": "femte", + "seks": "sjette", + "syv": "syvende", + "\xe5tte": "\xe5ttende", + "ni": "niende", + "ti": "tiende", + "elleve": "ellevte", + "tolv": "tolvte", + "fjorten": "fjortende", + "femten": "femtende", + "seksten": "sekstende", + "sytten": "syttende", + "atten": "attende", + "nitten": "nittende", + "tjue": "tjuende", + "hundre": "hundrede", + "tusen": "tusende", + "million": "millionte"} + # this needs to be done separately to not block 13-19 to_ordinal + self.ords_sg = {"en": "f\xf8rste"} def merge(self, lpair, rpair): ltext, lnum = lpair @@ -70,32 +81,29 @@ def merge(self, lpair, rpair): 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 og %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) - outwords = self.to_cardinal(value).split(" ") - lastwords = outwords[-1].split("-") - lastword = lastwords[-1].lower() - try: - lastword = self.ords[lastword] - except KeyError: - if lastword[-2:] == "ti": - lastword = lastword + "ende" - else: - lastword += "de" - lastwords[-1] = self.title(lastword) - outwords[-1] = "".join(lastwords) - return " ".join(outwords) + outword = self.to_cardinal(value) + for key in self.ords_pl: + if outword.endswith(key): + outword = outword[:len(outword) - len(key)] + self.ords_pl[key] + break + for key in self.ords_sg: + if outword.endswith(key): + outword = outword[:len(outword) - len(key)] + self.ords_sg[key] + break + return outword def to_ordinal_num(self, value): self.verify_ordinal(value) - return "%s%s" % (value, self.to_ordinal(value)[-2:]) + return str(value) + "." def to_year(self, val, longval=True): if not (val // 100) % 10: @@ -103,6 +111,12 @@ def to_year(self, val, longval=True): return self.to_splitnum(val, hightxt="hundre", jointxt="og", longval=longval) - def to_currency(self, val, longval=True): - return self.to_splitnum(val, hightxt="krone/r", lowtxt="\xf8re/r", - jointxt="og", longval=longval, cents=True) + def to_currency(self, val, currency='NOK', cents=True, separator=' og', + adjective=False): + result = super(Num2Word_NO, self).to_currency( + val, currency=currency, cents=cents, separator=separator, + adjective=adjective) + + # do not print "og null øre" + result = result.replace(' og null øre', '') + return result diff --git a/num2words/lang_PL.py b/num2words/lang_PL.py index 92da65d2..376b0a10 100644 --- a/num2words/lang_PL.py +++ b/num2words/lang_PL.py @@ -1,165 +1,272 @@ -# -*- 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 unicode_literals - -from .base import Num2Word_Base -from .utils import get_digits, splitbyx - -ZERO = ('zero',) - -ONES = { - 1: ('jeden',), - 2: ('dwa',), - 3: ('trzy',), - 4: ('cztery',), - 5: ('pięć',), - 6: ('sześć',), - 7: ('siedem',), - 8: ('osiem',), - 9: ('dziewięć',), -} - -TENS = { - 0: ('dziesięć',), - 1: ('jedenaście',), - 2: ('dwanaście',), - 3: ('trzynaście',), - 4: ('czternaście',), - 5: ('piętnaście',), - 6: ('szesnaście',), - 7: ('siedemnaście',), - 8: ('osiemnaście',), - 9: ('dziewiętnaście',), -} - -TWENTIES = { - 2: ('dwadzieścia',), - 3: ('trzydzieści',), - 4: ('czterdzieści',), - 5: ('pięćdziesiąt',), - 6: ('sześćdziesiąt',), - 7: ('siedemdziesiąt',), - 8: ('osiemdziesiąt',), - 9: ('dziewięćdzisiąt',), -} - -HUNDREDS = { - 1: ('sto',), - 2: ('dwieście',), - 3: ('trzysta',), - 4: ('czterysta',), - 5: ('pięćset',), - 6: ('sześćset',), - 7: ('siedemset',), - 8: ('osiemset',), - 9: ('dziewięćset',), -} - -THOUSANDS = { - 1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3 - 2: ('milion', 'miliony', 'milionów'), # 10^6 - 3: ('miliard', 'miliardy', 'miliardów'), # 10^9 - 4: ('bilion', 'biliony', 'bilionów'), # 10^12 - 5: ('biliard', 'biliardy', 'biliardów'), # 10^15 - 6: ('trylion', 'tryliony', 'trylionów'), # 10^18 - 7: ('tryliard', 'tryliardy', 'tryliardów'), # 10^21 - 8: ('kwadrylion', 'kwadryliony', 'kwadrylionów'), # 10^24 - 9: ('kwadryliard', 'kwadryliardy', 'kwadryliardów'), # 10^27 - 10: ('kwintylion', 'kwintyliony', 'kwintylionów'), # 10^30 - 11: ('kwintyliard', 'kwintyliardy', 'kwintyliardów'), # 10^33 - 12: ('sekstylion', 'sekstyliony', 'sekstylionów'), # 10^36 - 13: ('sekstyliard', 'sekstyliardy', 'sekstyliardów'), # 10^39 - 14: ('septylion', 'septyliony', 'septylionów'), # 10^42 - 15: ('septyliard', 'septyliardy', 'septyliardów'), # 10^45 - 16: ('oktylion', 'oktyliony', 'oktylionów'), # 10^48 - 17: ('oktyliard', 'oktyliardy', 'oktyliardów'), # 10^51 - 18: ('nonylion', 'nonyliony', 'nonylionów'), # 10^54 - 19: ('nonyliard', 'nonyliardy', 'nonyliardów'), # 10^57 - 20: ('decylion', 'decyliony', 'decylionów'), # 10^60 - 21: ('decyliard', 'decyliardy', 'decyliardów'), # 10^63 -} - - -class Num2Word_PL(Num2Word_Base): - CURRENCY_FORMS = { - 'PLN': ( - ('złoty', 'złote', 'złotych'), ('grosz', 'grosze', 'groszy') - ), - 'EUR': ( - ('euro', 'euro', 'euro'), ('cent', 'centy', 'centów') - ), - } - - def setup(self): - self.negword = "minus" - self.pointword = "przecinek" - - def to_cardinal(self, number): - n = str(number).replace(',', '.') - if '.' in n: - left, right = n.split('.') - return u'%s %s %s' % ( - self._int2word(int(left)), - self.pointword, - self._int2word(int(right)) - ) - else: - return self._int2word(int(n)) - - def pluralize(self, n, forms): - if n == 1: - form = 0 - elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20): - form = 1 - else: - form = 2 - return forms[form] - - def to_ordinal(self, number): - raise NotImplementedError() - - def _int2word(self, n): - if n == 0: - return ZERO[0] - - words = [] - chunks = list(splitbyx(str(n), 3)) - i = len(chunks) - for x in chunks: - i -= 1 - - if x == 0: - continue - - n1, n2, n3 = get_digits(x) - - if n3 > 0: - words.append(HUNDREDS[n3][0]) - - if n2 > 1: - words.append(TWENTIES[n2][0]) - - if n2 == 1: - words.append(TENS[n1][0]) - elif n1 > 0 and not (i > 0 and x == 1): - words.append(ONES[n1][0]) - - if i > 0: - words.append(self.pluralize(x, THOUSANDS[i])) - - return ' '.join(words) +# -*- 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 unicode_literals + +import itertools + +from .base import Num2Word_Base +from .utils import get_digits, splitbyx + +ZERO = ('zero',) + +ONES = { + 1: ('jeden',), + 2: ('dwa',), + 3: ('trzy',), + 4: ('cztery',), + 5: ('pięć',), + 6: ('sześć',), + 7: ('siedem',), + 8: ('osiem',), + 9: ('dziewięć',), +} + +ONES_ORDINALS = { + 1: ('pierwszy', "pierwszo"), + 2: ('drugi', "dwu"), + 3: ('trzeci', "trzy"), + 4: ('czwarty', "cztero"), + 5: ('piąty', "pięcio"), + 6: ('szósty', "sześcio"), + 7: ('siódmy', "siedmio"), + 8: ('ósmy', "ośmio"), + 9: ('dziewiąty', "dziewięcio"), + 10: ('dziesiąty', "dziesięcio"), + 11: ('jedenasty', "jedenasto"), + 12: ('dwunasty', "dwunasto"), + 13: ('trzynasty', "trzynasto"), + 14: ('czternasty', "czternasto"), + 15: ('piętnasty', "piętnasto"), + 16: ('szesnasty', "szesnasto"), + 17: ('siedemnasty', "siedemnasto"), + 18: ('osiemnasty', "osiemnasto"), + 19: ('dziewiętnasty', "dziewiętnasto"), +} + +TENS = { + 0: ('dziesięć',), + 1: ('jedenaście',), + 2: ('dwanaście',), + 3: ('trzynaście',), + 4: ('czternaście',), + 5: ('piętnaście',), + 6: ('szesnaście',), + 7: ('siedemnaście',), + 8: ('osiemnaście',), + 9: ('dziewiętnaście',), +} + + +TWENTIES = { + 2: ('dwadzieścia',), + 3: ('trzydzieści',), + 4: ('czterdzieści',), + 5: ('pięćdziesiąt',), + 6: ('sześćdziesiąt',), + 7: ('siedemdziesiąt',), + 8: ('osiemdziesiąt',), + 9: ('dziewięćdziesiąt',), +} + +TWENTIES_ORDINALS = { + 2: ('dwudziesty', "dwudziesto"), + 3: ('trzydziesty', "trzydiesto"), + 4: ('czterdziesty', "czterdziesto"), + 5: ('pięćdziesiąty', "pięćdziesięcio"), + 6: ('sześćdziesiąty', "sześćdziesięcio"), + 7: ('siedemdziesiąty', "siedemdziesięcio"), + 8: ('osiemdziesiąty', "osiemdziesięcio"), + 9: ('dziewięćdziesiąty', "dziewięćdziesięcio"), +} + +HUNDREDS = { + 1: ('sto',), + 2: ('dwieście',), + 3: ('trzysta',), + 4: ('czterysta',), + 5: ('pięćset',), + 6: ('sześćset',), + 7: ('siedemset',), + 8: ('osiemset',), + 9: ('dziewięćset',), +} + +HUNDREDS_ORDINALS = { + 1: ('setny', "stu"), + 2: ('dwusetny', "dwustu"), + 3: ('trzysetny', "trzystu"), + 4: ('czterysetny', "czterystu"), + 5: ('pięćsetny', "pięcset"), + 6: ('sześćsetny', "sześćset"), + 7: ('siedemsetny', "siedemset"), + 8: ('osiemsetny', "ośiemset"), + 9: ('dziewięćsetny', "dziewięćset"), +} + +THOUSANDS = { + 1: ('tysiąc', 'tysiące', 'tysięcy'), # 10^3 +} + +prefixes_ordinal = { + 1: "tysięczny", + 2: "milionowy", + 3: "milairdowy" +} + +prefixes = ( # 10^(6*x) + "mi", # 10^6 + "bi", # 10^12 + "try", # 10^18 + "kwadry", # 10^24 + "kwinty", # 10^30 + "seksty", # 10^36 + "septy", # 10^42 + "okty", # 10^48 + "nony", # 10^54 + "decy" # 10^60 +) +suffixes = ("lion", "liard") # 10^x or 10^(x+3) + +for idx, (p, s) in enumerate(itertools.product(prefixes, suffixes)): + name = p + s + THOUSANDS[idx+2] = (name, name + 'y', name + 'ów') + + +class Num2Word_PL(Num2Word_Base): + CURRENCY_FORMS = { + 'PLN': ( + ('złoty', 'złote', 'złotych'), ('grosz', 'grosze', 'groszy') + ), + 'EUR': ( + ('euro', 'euro', 'euro'), ('cent', 'centy', 'centów') + ), + 'USD': ( + ( + 'dolar amerykański', + 'dolary amerykańskie', + 'dolarów amerykańskich' + ), + ( + 'cent', + 'centy', + 'centów' + ) + ), + } + + def setup(self): + self.negword = "minus" + self.pointword = "przecinek" + + def to_cardinal(self, number): + n = str(number).replace(',', '.') + if '.' in n: + left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + self._int2word(int(right))) + return u'%s %s %s' % ( + self._int2word(int(left)), + self.pointword, + decimal_part + ) + else: + return self._int2word(int(n)) + + def pluralize(self, n, forms): + if n == 1: + form = 0 + elif 5 > n % 10 > 1 and (n % 100 < 10 or n % 100 > 20): + form = 1 + else: + form = 2 + return forms[form] + + def last_fragment_to_ordinal(self, last, words, level): + n1, n2, n3 = get_digits(last) + last_two = n2*10+n1 + if last_two == 0: + words.append(HUNDREDS_ORDINALS[n3][level]) + elif level == 1 and last == 1: + return + elif last_two < 20: + if n3 > 0: + words.append(HUNDREDS[n3][level]) + words.append(ONES_ORDINALS[last_two][level]) + elif last_two % 10 == 0: + if n3 > 0: + words.append(HUNDREDS[n3][level]) + words.append(TWENTIES_ORDINALS[n2][level]) + else: + if n3 > 0: + words.append(HUNDREDS[n3][0]) + words.append(TWENTIES_ORDINALS[n2][0]) + words.append(ONES_ORDINALS[n1][0]) + + def to_ordinal(self, number): + if number % 1 != 0: + raise NotImplementedError() + words = [] + fragments = list(splitbyx(str(number), 3)) + level = 0 + last = fragments[-1] + while last == 0: + level = level+1 + fragments.pop() + last = fragments[-1] + if len(fragments) > 1: + pre_part = self._int2word(number-(last*1000**level)) + words.append(pre_part) + self.last_fragment_to_ordinal(last, words, 0 if level == 0 else 1) + output = " ".join(words) + if last == 1 and level > 0 and output != "": + output = output + " " + if level > 0: + output = output + prefixes_ordinal[level] + return output + + def _int2word(self, n): + if n == 0: + return ZERO[0] + + words = [] + chunks = list(splitbyx(str(n), 3)) + i = len(chunks) + for x in chunks: + i -= 1 + + if x == 0: + continue + + n1, n2, n3 = get_digits(x) + + if n3 > 0: + words.append(HUNDREDS[n3][0]) + + if n2 > 1: + words.append(TWENTIES[n2][0]) + + if n2 == 1: + words.append(TENS[n1][0]) + elif n1 > 0 and not (i > 0 and x == 1): + words.append(ONES[n1][0]) + + if i > 0: + words.append(self.pluralize(x, THOUSANDS[i])) + + return ' '.join(words) diff --git a/num2words/lang_PT.py b/num2words/lang_PT.py index 3c47b17a..ddfa7713 100644 --- a/num2words/lang_PT.py +++ b/num2words/lang_PT.py @@ -215,24 +215,19 @@ def to_year(self, val, longval=True): return self.to_cardinal(abs(val)) + ' antes de Cristo' return self.to_cardinal(val) - def to_currency(self, val, currency='EUR', cents=True, seperator=' e', + def to_currency(self, val, currency='EUR', cents=True, separator=' e', adjective=False): # change negword because base.to_currency() does not need space after backup_negword = self.negword self.negword = self.negword[:-1] result = super(Num2Word_PT, self).to_currency( - val, currency=currency, cents=cents, seperator=seperator, + val, currency=currency, cents=cents, separator=separator, adjective=adjective) # undo the change on negword self.negword = backup_negword # transforms "milhões euros" em "milhões de euros" - try: - cr1, _ = self.CURRENCY_FORMS[currency] - except KeyError: - raise NotImplementedError( - 'Currency code "%s" not implemented for "%s"' % - (currency, self.__class__.__name__)) + cr1, _ = self.CURRENCY_FORMS[currency] for ext in ( 'milhão', 'milhões', 'bilião', diff --git a/num2words/lang_PT_BR.py b/num2words/lang_PT_BR.py index 4c73cac3..2aea06cb 100644 --- a/num2words/lang_PT_BR.py +++ b/num2words/lang_PT_BR.py @@ -49,7 +49,7 @@ def merge(self, curr, next): if nnum < 1000000: return next ctext = "um" - elif cnum == 100 and not nnum == 1000: + elif cnum == 100 and nnum % 1000 != 0: ctext = "cento" if nnum < cnum: @@ -77,7 +77,7 @@ def to_cardinal(self, value): for ext in ( 'mil', 'milhão', 'milhões', 'bilhão', 'bilhões', 'trilhão', 'trilhões', 'quatrilhão', 'quatrilhões'): - if re.match('.*{} e \\w*ento'.format(ext), result): + if re.match('.*{} e \\w*entos? (?=.*e)'.format(ext), result): result = result.replace( '{} e'.format(ext), '{},'.format(ext), 1 ) diff --git a/num2words/lang_RO.py b/num2words/lang_RO.py index d4693b86..feb96105 100644 --- a/num2words/lang_RO.py +++ b/num2words/lang_RO.py @@ -23,8 +23,9 @@ class Num2Word_RO(lang_EU.Num2Word_EU): GIGA_SUFFIX = "iliard/e" MEGA_SUFFIX = "ilion" - # inflection for million follows different rule + # inflection for mi/billion follows different rule MEGA_SUFFIX_I = "ilioane" + GIGA_SUFFIX_I = "iliarde" def setup(self): super(Num2Word_RO, self).setup() @@ -33,7 +34,8 @@ def setup(self): self.pointword = "virgulă" self.exclude_title = ["și", "virgulă", "minus"] self.errmsg_toobig = ( - "Numărul e prea mare pentru a fi convertit în cuvinte." + "Numărul e prea mare pentru a \ +fi convertit în cuvinte (abs(%s) > %s)." ) self.mid_numwords = [(1000, "mie/i"), (100, "sută/e"), (90, "nouăzeci"), (80, "optzeci"), @@ -48,13 +50,13 @@ def setup(self): "unu", "zero"] self.gen_numwords = ["", "o", "două", "trei", "patru", "cinci", "șase", "șapte", "opt", "nouă"] - self.gen_numwords_m = ["", "un", "două", "trei", "patru", "cinci", + self.gen_numwords_n = ["", "un", "două", "trei", "patru", "cinci", "șase", "șapte", "opt", "nouă"] self.numwords_inflections = { 100: self.gen_numwords, 1000: self.gen_numwords, - 1000000: self.gen_numwords_m, - 1000000000: self.gen_numwords_m + 1000000: self.gen_numwords_n, + 1000000000: self.gen_numwords_n } self.ords = {"unu": "primul", "doi": "al doilea", @@ -67,24 +69,29 @@ def setup(self): def merge(self, lpair, rpair): ltext, lnum = lpair rtext, rnum = rpair - rtext_i = self.inflect(rnum, rtext) - if lnum > 1 and rtext_i.endswith(self.MEGA_SUFFIX): - rtext_i = rtext_i.replace(self.MEGA_SUFFIX, self.MEGA_SUFFIX_I) + rtext_i = self.inflect(rnum, rtext, lnum) if 1 <= lnum < 10: if rnum not in self.numwords_inflections: return (rtext, rnum) else: - rtext_i = self.inflect(lnum * rnum, rtext) + rtext_i = self.inflect(lnum * rnum, rtext, lnum) lresult = (self.numwords_inflections[rnum][lnum], rtext_i) return ("%s %s" % lresult, rnum) elif 10 < lnum < 100: if lnum % 10 == 0: - return ("%s și %s" % (ltext, rtext), lnum + rnum) + if rnum in self.numwords_inflections: + rtext_i = self.inflect(lnum * rnum, rtext, lnum) + return ("%s %s" % (ltext, rtext_i), lnum * rnum) + else: + return ("%s și %s" % (ltext, rtext), lnum + rnum) else: - return ("%s %s" % (ltext, rtext_i), lnum * rnum) + rtext_i = self.inflect(lnum * rnum, rtext, lnum) + ltext_i = ltext if lnum % 10 != 2 \ + else ltext.replace("doi", "două") + return ("%s %s" % (ltext_i, rtext_i), lnum * rnum) else: if rnum in self.numwords_inflections: - rtext_i = self.inflect(lnum * rnum, rtext) + rtext_i = self.inflect(lnum * rnum, rtext, lnum) return ("%s %s" % (ltext, rtext_i), lnum * rnum) def to_ordinal(self, value): @@ -101,21 +108,52 @@ def to_ordinal_num(self, value): return "1-ul" return "al %s-lea" % (value) - def inflect(self, value, text): + def pluralize(self, n, forms): + if n == 1: + form = 0 + elif n == 0 or (n % 100 > 0 and n % 100 < 20): + form = 1 + else: + form = 2 + return forms[form] + + def inflect(self, value, text, side_effect=-1): text = text.split("/") - if value in (1, 100, 1000, 100000, 1000000000): - return text[0] - if len(text) > 1 and text[0][-1] in "aăeiou": - text[0] = text[0][:-1] - return "".join(text) + result = text[0] + if len(text) > 1: + forms = [ + text[0], + text[0][:-1] + text[1], + "de " + text[0][:-1] + text[1] + ] + result = self.pluralize(side_effect, forms) + # mega inflections are different + if side_effect > 1 and result.endswith(self.MEGA_SUFFIX): + result = result.replace(self.MEGA_SUFFIX, self.MEGA_SUFFIX_I) + elif side_effect > 1 and result.endswith("iliare"): + result = result.replace("iliare", self.GIGA_SUFFIX_I) + return result - def to_currency(self, val, longval=True, old=False): - cents = int(round(val*100)) - result = self.to_splitnum(cents, hightxt="leu/i", lowtxt="ban/i", - divisor=100, jointxt="și", longval=longval) + def to_currency(self, val, currency="RON", cents=False, separator=" și", + adjective=False): + # romanian currency has a particularity for numeral: one + self.gen_numwords[1] = "una" + result = super(Num2Word_RO, self).to_currency( + int(round(val*100)), + currency, + True, + separator, + adjective + ) + self.gen_numwords[1] = "o" # revert numeral return result.replace( "unu leu", "un leu" - ).replace("unu ban", "un ban") + ).replace( + "unu ban", "un ban" + ).replace( + # if the romanian low text is 0, it is not usually printed + separator + " zero bani", "" + ) def to_year(self, val, suffix=None, longval=True): result = super(Num2Word_RO, self).to_year( diff --git a/num2words/lang_RU.py b/num2words/lang_RU.py index 3b025268..2ff1c0a0 100644 --- a/num2words/lang_RU.py +++ b/num2words/lang_RU.py @@ -20,80 +20,227 @@ from .base import Num2Word_Base from .utils import get_digits, splitbyx -ZERO = ('ноль',) - -ONES_FEMININE = { - 1: ('одна',), - 2: ('две',), - 3: ('три',), - 4: ('четыре',), - 5: ('пять',), - 6: ('шесть',), - 7: ('семь',), - 8: ('восемь',), - 9: ('девять',), +GENDER_PLURAL_INDEXES = { + 'm': 0, 'masculine': 0, 'м': 0, 'мужской': 0, + 'f': 1, 'feminine': 1, 'ж': 0, 'женский': 0, + 'n': 2, 'neuter': 2, 'с': 0, 'средний': 0, + 'p': 3, 'plural': 3 } +CASE_INDEXES = { + 'n': 0, 'nominative': 0, 'и': 0, 'именительный': 0, + 'g': 1, 'genitive': 1, 'р': 1, 'родительный': 1, + 'd': 2, 'dative': 2, 'д': 2, 'дательный': 2, + 'a': 3, 'accusative': 3, 'в': 3, 'винительный': 3, + 'i': 4, 'instrumental': 4, 'т': 4, 'творительный': 4, + 'p': 5, 'prepositional': 5, 'п': 5, 'предложный': 5 +} +# Default values +D_CASE = 'n' +D_PLURAL = False +D_GENDER = 'm' +D_ANIMATE = True + + +def get_num_element(cases_dict, num, **kwargs): + return case_classifier_element(cases_dict[num], **kwargs) + + +def case_classifier_element(classifier, case=D_CASE, plural=D_PLURAL, + gender=D_GENDER, animate=D_ANIMATE): + case = classifier[CASE_INDEXES[case]] + if isinstance(case, str): + return case + + if plural: + gender = case[GENDER_PLURAL_INDEXES['plural']] + else: + gender = case[GENDER_PLURAL_INDEXES[gender]] + if isinstance(gender, str): + return gender + + if animate: + return gender[0] + return gender[1] + +# format: +# {n : [case_1 .. case_5]} +# case: text or [gender_1 .. gender_3 plural_4] +# gender: text or [animate, inanimate] ONES = { - 1: ('один',), - 2: ('два',), - 3: ('три',), - 4: ('четыре',), - 5: ('пять',), - 6: ('шесть',), - 7: ('семь',), - 8: ('восемь',), - 9: ('девять',), + 0: ['ноль', 'ноля', 'нолю', 'ноль', 'нолём', 'ноле'], + 1: [['один', 'одна', 'одно', 'одни'], + ['одного', 'одной', 'одного', 'одних'], + ['одному', 'одной', 'одному', 'одним'], + [['одного', 'один'], 'одну', 'одно', ['одних', 'одни']], + ['одним', 'одной', 'одним', 'одними'], + ['одном', 'одной', 'одном', 'одних']], + 2: [['два', 'две', 'два', 'двое'], + ['двух'] * 3 + ['двоих'], + ['двум'] * 3 + ['двоим'], + [['двух', 'два'], ['двух', 'две'], 'два', 'двоих'], + ['двумя'] * 3 + ['двоими'], + ['двух'] * 3 + ['двоих']], + 3: [['три'] * 3 + ['трое'], + ['трёх'] * 3 + ['троих'], + ['трём'] * 3 + ['троим'], + [['трёх', 'три'], ['трёх', 'три'], 'три', 'троих'], + ['тремя'] * 3 + ['троими'], + ['трёх'] * 3 + ['троих']], + 4: [['четыре'] * 3 + ['четверо'], + ['четырёх'] * 3 + ['четверых'], + ['четырём'] * 3 + ['четверым'], + [['четырёх', 'четыре'], ['четырёх', 'четыре'], 'четыре', 'четверых'], + ['четырьмя'] * 3 + ['четверыми'], + ['четырёх'] * 3 + ['четверых']], + 5: ['пять', 'пяти', 'пяти', 'пять', 'пятью', 'пяти'], + 6: ['шесть', 'шести', 'шести', 'шесть', 'шестью', 'шести'], + 7: ['семь', 'семи', 'семи', 'семь', 'семью', 'семи'], + 8: ['восемь', 'восьми', 'восьми', 'восемь', 'восемью', 'восьми'], + 9: ['девять', 'девяти', 'девяти', 'девять', 'девятью', 'девяти'] } -TENS = { - 0: ('десять',), - 1: ('одиннадцать',), - 2: ('двенадцать',), - 3: ('тринадцать',), - 4: ('четырнадцать',), - 5: ('пятнадцать',), - 6: ('шестнадцать',), - 7: ('семнадцать',), - 8: ('восемнадцать',), - 9: ('девятнадцать',), +ONES_ORD_PREFIXES = {0: 'нулев', 1: 'перв', 2: 'втор', 4: 'четвёрт', 5: 'пят', + 6: 'шест', 7: 'седьм', 8: 'восьм', 9: 'девят'} +ONES_ORD_POSTFIXES_GROUPS = {0: 0, 1: 1, 2: 0, 4: 1, 5: 1, 6: 0, 7: 0, 8: 0, + 9: 1} +CASE_POSTFIXES = [[{0: 'ой', 1: 'ый'}, 'ая', 'ое', 'ые'], + ['ого', 'ой', 'ого', 'ых'], + ['ому', 'ой', 'ому', 'ым'], + [['ого', {0: 'ой', 1: 'ый'}], 'ую', 'ое', ['ых', 'ые']], + ['ым', 'ой', 'ым', 'ыми'], + ['ом', 'ой', 'ом', 'ых']] + + +def get_cases(prefix, post_group): + return [[ + prefix + postfix if isinstance(postfix, str) else + [prefix + animate if isinstance(animate, str) else + prefix + animate[post_group] + for animate in postfix] if isinstance(postfix, list) else + prefix + postfix[post_group] + for postfix in case] + for case in CASE_POSTFIXES] + + +def get_ord_classifier(prefixes, post_groups): + if isinstance(post_groups, int): + post_groups = {n: post_groups for n, i in prefixes.items()} + return { + num: get_cases(prefix, post_groups[num]) + for num, prefix in prefixes.items() + } + + +ONES_ORD = { + 3: [['третий', 'третья', 'третье', 'третьи'], + ['третьего', 'третьей', 'третьего', 'третьих'], + ['третьему', 'третьей', 'третьему', 'третьим'], + [['третьего', 'третий'], 'третью', 'третье', ['третьих', 'третьи']], + ['третьим', 'третьей', 'третьим', 'третьими'], + ['третьем', 'третьей', 'третьем', 'третьих']], } +ONES_ORD.update( + get_ord_classifier(ONES_ORD_PREFIXES, ONES_ORD_POSTFIXES_GROUPS) +) + +TENS_PREFIXES = {1: 'один', 2: 'две', 3: 'три', 4: 'четыр', 5: 'пят', + 6: 'шест', 7: 'сем', 8: 'восем', 9: 'девят'} +TENS_POSTFIXES = ['надцать', 'надцати', 'надцати', 'надцать', 'надцатью', + 'надцати'] +TENS = {0: ['десять', 'десяти', 'десяти', 'десять', 'десятью', 'десяти']} +TENS.update({ + num: [prefix + postfix for postfix in TENS_POSTFIXES] + for num, prefix in TENS_PREFIXES.items() +}) + +TENS_ORD_PREFIXES = {0: "десят"} +TENS_ORD_PREFIXES.update({ + num: prefix + 'надцат' for num, prefix in TENS_PREFIXES.items() +}) +TENS_ORD = get_ord_classifier(TENS_ORD_PREFIXES, 1) TWENTIES = { - 2: ('двадцать',), - 3: ('тридцать',), - 4: ('сорок',), - 5: ('пятьдесят',), - 6: ('шестьдесят',), - 7: ('семьдесят',), - 8: ('восемьдесят',), - 9: ('девяносто',), + 2: ['двадцать', 'двадцати', 'двадцати', 'двадцать', 'двадцатью', + 'двадцати'], + 3: ['тридцать', 'тридцати', 'тридцати', 'тридцать', 'тридцатью', + 'тридцати'], + 4: ['сорок', 'сорока', 'сорока', 'сорок', 'сорока', 'сорока'], + 5: ['пятьдесят', 'пятидесяти', 'пятидесяти', 'пятьдесят', 'пятьюдесятью', + 'пятидесяти'], + 6: ['шестьдесят', 'шестидесяти', 'шестидесяти', 'шестьдесят', + 'шестьюдесятью', 'шестидесяти'], + 7: ['семьдесят', 'семидесяти', 'семидесяти', 'семьдесят', 'семьюдесятью', + 'семидесяти'], + 8: ['восемьдесят', 'восьмидесяти', 'восьмидесяти', 'восемьдесят', + 'восемьюдесятью', 'восьмидесяти'], + 9: ['девяносто', 'девяноста', 'девяноста', 'девяносто', 'девяноста', + 'девяноста'], } +TWENTIES_ORD_PREFIXES = {2: 'двадцат', 3: 'тридцат', 4: 'сороков', + 5: 'пятидесят', 6: 'шестидесят', 7: 'семидесят', + 8: 'восьмидесят', 9: 'девяност'} +TWENTIES_ORD_POSTFIXES_GROUPS = {2: 1, 3: 1, 4: 0, 5: 1, 6: 1, 7: 1, 8: 1, + 9: 1} +TWENTIES_ORD = get_ord_classifier(TWENTIES_ORD_PREFIXES, + TWENTIES_ORD_POSTFIXES_GROUPS) + HUNDREDS = { - 1: ('сто',), - 2: ('двести',), - 3: ('триста',), - 4: ('четыреста',), - 5: ('пятьсот',), - 6: ('шестьсот',), - 7: ('семьсот',), - 8: ('восемьсот',), - 9: ('девятьсот',), + 1: ['сто', 'ста', 'ста', 'сто', 'ста', 'ста'], + 2: ['двести', 'двухсот', 'двумстам', 'двести', 'двумястами', 'двухстах'], + 3: ['триста', 'трёхсот', 'трёмстам', 'триста', 'тремястами', 'трёхстах'], + 4: ['четыреста', 'четырёхсот', 'четырёмстам', 'четыреста', 'четырьмястами', + 'четырёхстах'], + 5: ['пятьсот', 'пятисот', 'пятистам', 'пятьсот', 'пятьюстами', 'пятистах'], + 6: ['шестьсот', 'шестисот', 'шестистам', 'шестьсот', 'шестьюстами', + 'шестистах'], + 7: ['семьсот', 'семисот', 'семистам', 'семьсот', 'семьюстами', 'семистах'], + 8: ['восемьсот', 'восьмисот', 'восьмистам', 'восемьсот', 'восемьюстами', + 'восьмистах'], + 9: ['девятьсот', 'девятисот', 'девятистам', 'девятьсот', 'девятьюстами', + 'девятистах'], +} + +HUNDREDS_ORD_PREFIXES = { + num: case[1] if num != 1 else 'сот' for num, case in HUNDREDS.items() } +HUNDREDS_ORD = get_ord_classifier(HUNDREDS_ORD_PREFIXES, 1) + +THOUSANDS_PREFIXES = {2: 'миллион', 3: 'миллиард', 4: 'триллион', + 5: 'квадриллион', 6: 'квинтиллион', 7: 'секстиллион', + 8: 'септиллион', 9: 'октиллион', 10: 'нониллион'} +THOUSANDS_POSTFIXES = [('', 'а', 'ов'), + ('а', 'ов', 'ов'), + ('у', 'ам', 'ам'), + ('', 'а', 'ов'), + ('ом', 'ами', 'ами'), + ('е', 'ах', 'ах')] THOUSANDS = { - 1: ('тысяча', 'тысячи', 'тысяч'), # 10^3 - 2: ('миллион', 'миллиона', 'миллионов'), # 10^6 - 3: ('миллиард', 'миллиарда', 'миллиардов'), # 10^9 - 4: ('триллион', 'триллиона', 'триллионов'), # 10^12 - 5: ('квадриллион', 'квадриллиона', 'квадриллионов'), # 10^15 - 6: ('квинтиллион', 'квинтиллиона', 'квинтиллионов'), # 10^18 - 7: ('секстиллион', 'секстиллиона', 'секстиллионов'), # 10^21 - 8: ('септиллион', 'септиллиона', 'септиллионов'), # 10^24 - 9: ('октиллион', 'октиллиона', 'октиллионов'), # 10^27 - 10: ('нониллион', 'нониллиона', 'нониллионов'), # 10^30 + 1: [['тысяча', 'тысячи', 'тысяч'], + ['тысячи', 'тысяч', 'тысяч'], + ['тысяче', 'тысячам', 'тысячам'], + ['тысячу', 'тысячи', 'тысяч'], + ['тысячей', 'тысячами', 'тысячами'], + ['тысяче', 'тысячах', 'тысячах']] } +THOUSANDS.update({ + num: [ + [prefix + postfix for postfix in case] for case in THOUSANDS_POSTFIXES + ] for num, prefix in THOUSANDS_PREFIXES.items() +}) + + +def get_thousands_elements(num, case): + return THOUSANDS[num][CASE_INDEXES[case]] + + +THOUSANDS_ORD_PREFIXES = {1: 'тысячн'} +THOUSANDS_ORD_PREFIXES.update({ + num: prefix + 'н' for num, prefix in THOUSANDS_PREFIXES.items() +}) +THOUSANDS_ORD = get_ord_classifier(THOUSANDS_ORD_PREFIXES, 1) class Num2Word_RU(Num2Word_Base): @@ -107,108 +254,125 @@ class Num2Word_RU(Num2Word_Base): 'USD': ( ('доллар', 'доллара', 'долларов'), ('цент', 'цента', 'центов') ), + 'UAH': ( + ('гривна', 'гривны', 'гривен'), ('копейка', 'копейки', 'копеек') + ), + 'KZT': ( + ('тенге', 'тенге', 'тенге'), ('тиын', 'тиына', 'тиынов') + ), + 'BYN': ( + ('белорусский рубль', 'белорусских рубля', 'белорусских рублей'), + ('копейка', 'копейки', 'копеек') + ), + 'UZS': ( + ('сум', 'сума', 'сумов'), ('тийин', 'тийина', 'тийинов') + ), + 'PLN': ( + ('польский злотый', 'польских слотых', 'польских злотых'), + ('грош', 'гроша', 'грошей') + ), } def setup(self): self.negword = "минус" - self.pointword = "запятая" - self.ords = {"ноль": "нулевой", - "один": "первый", - "два": "второй", - "три": "третий", - "четыре": "четвертый", - "пять": "пятый", - "шесть": "шестой", - "семь": "седьмой", - "восемь": "восьмой", - "девять": "девятый", - "сто": "сотый"} - self.ords_feminine = {"один": "", - "одна": "", - "две": "двух", - "три": "трёх", - "четыре": "четырёх", - "пять": "пяти", - "шесть": "шести", - "семь": "семи", - "восемь": "восьми", - "девять": "девяти"} - - def to_cardinal(self, number): + self.pointword = ('целая', 'целых', 'целых') + self.pointword_ord = get_cases("цел", 1) + + def to_cardinal(self, number, case=D_CASE, plural=D_PLURAL, + gender=D_GENDER, animate=D_ANIMATE): n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') - return u'%s %s %s' % ( - self._int2word(int(left)), - self.pointword, - self._int2word(int(right)) + decimal_part = self._int2word(int(right), cardinal=True, + gender='f') + return u'%s %s %s %s' % ( + self._int2word(int(left), cardinal=True, gender='f'), + self.pluralize(int(left), self.pointword), + decimal_part, + self.__decimal_bitness(right) ) else: - return self._int2word(int(n)) + return self._int2word(int(n), cardinal=True, case=case, + plural=plural, gender=gender, + animate=animate) + + def __decimal_bitness(self, n): + if n[-1] == "1" and n[-2:] != "11": + return self._int2word(10 ** len(n), cardinal=False, gender='f') + return self._int2word(10 ** len(n), cardinal=False, case='g', + plural=True) def pluralize(self, n, forms): - if n % 100 < 10 or n % 100 > 20: - if n % 10 == 1: - form = 0 - elif 5 > n % 10 > 1: - form = 1 - else: - form = 2 - else: - form = 2 - return forms[form] + if n % 100 in (11, 12, 13, 14): + return forms[2] + if n % 10 == 1: + return forms[0] + if n % 10 in (2, 3, 4): + return forms[1] + return forms[2] - def to_ordinal(self, number): + def to_ordinal(self, number, case=D_CASE, plural=D_PLURAL, gender=D_GENDER, + animate=D_ANIMATE): self.verify_ordinal(number) - outwords = self.to_cardinal(number).split(" ") - lastword = outwords[-1].lower() - try: - if len(outwords) > 1: - if outwords[-2] in self.ords_feminine: - outwords[-2] = self.ords_feminine.get( - outwords[-2], outwords[-2]) - elif outwords[-2] == 'десять': - outwords[-2] = outwords[-2][:-1] + 'и' - if len(outwords) == 3: - if outwords[-3] in ['один', 'одна']: - outwords[-3] = '' - lastword = self.ords[lastword] - except KeyError: - if lastword[:-3] in self.ords_feminine: - lastword = self.ords_feminine.get( - lastword[:-3], lastword) + "сотый" - elif lastword[-1] == "ь" or lastword[-2] == "т": - lastword = lastword[:-1] + "ый" - elif lastword[-1] == "к": - lastword = lastword + "овой" - elif lastword[-5:] == "десят": - lastword = lastword.replace('ь', 'и') + 'ый' - elif lastword[-2] == "ч" or lastword[-1] == "ч": - if lastword[-2] == "ч": - lastword = lastword[:-1] + "ный" - if lastword[-1] == "ч": - lastword = lastword + "ный" - elif lastword[-1] == "н" or lastword[-2] == "н": - lastword = lastword[:lastword.rfind('н') + 1] + "ный" - elif lastword[-1] == "д" or lastword[-2] == "д": - lastword = lastword[:lastword.rfind('д') + 1] + "ный" - outwords[-1] = self.title(lastword) - return " ".join(outwords).strip() + n = str(number).replace(',', '.') + return self._int2word(int(n), cardinal=False, case=case, plural=plural, + gender=gender, animate=animate) + + def _money_verbose(self, number, currency): + if currency == 'UAH': + return self._int2word(number, gender='f') + return self._int2word(number, gender='m') def _cents_verbose(self, number, currency): - return self._int2word(number, currency == 'RUB') + if currency in ('UAH', 'RUB', 'BYN'): + return self._int2word(number, gender='f') + return self._int2word(number, gender='m') + + def _int2word(self, n, feminine=False, cardinal=True, case=D_CASE, + plural=D_PLURAL, gender=D_GENDER, animate=D_ANIMATE): + """ + n: number + feminine: not used - for backward compatibility + cardinal:True - cardinal + False - ordinal + case: 'n' - nominative + 'g' - genitive + 'd' - dative + 'a' - accusative + 'i' - instrumental + 'p' - prepositional + plural: True - plural + False - singular + gender: 'f' - masculine + 'm' - feminine + 'n' - neuter + animate: True - animate + False - inanimate + """ + # For backward compatibility + if feminine: + gender = 'f' + + kwargs = {'case': case, 'plural': plural, 'gender': gender, + 'animate': animate} - def _int2word(self, n, feminine=False): if n < 0: - return ' '.join([self.negword, self._int2word(abs(n))]) + return ' '.join([self.negword, self._int2word(abs(n), + cardinal=cardinal, + **kwargs)]) if n == 0: - return ZERO[0] + return get_num_element(ONES, 0, **kwargs) if cardinal else \ + get_num_element(ONES_ORD, 0, **kwargs) words = [] chunks = list(splitbyx(str(n), 3)) + ord_join = chunks[-1] == 0 # join in one word if ending on 'тысячный' i = len(chunks) + rightest_nonzero_chunk_i = i - 1 - max( + [i for i, e in enumerate(chunks) if e != 0]) for x in chunks: + chunk_words = [] i -= 1 if x == 0: @@ -216,19 +380,122 @@ def _int2word(self, n, feminine=False): n1, n2, n3 = get_digits(x) - if n3 > 0: - words.append(HUNDREDS[n3][0]) - - if n2 > 1: - words.append(TWENTIES[n2][0]) + if cardinal: + chunk_words.extend( + self.__chunk_cardianl(n3, n2, n1, i, **kwargs) + ) + if i > 0: + chunk_words.append( + self.pluralize(x, get_thousands_elements(i, case))) + # ordinal, not joined like 'двухтысячный' + elif not (ord_join and rightest_nonzero_chunk_i == i): + chunk_words.extend( + self.__chunk_ordinal(n3, n2, n1, i, **kwargs) + ) + if i > 0: + t_case = case if rightest_nonzero_chunk_i == i else 'n' + chunk_words.append( + self.pluralize(x, get_thousands_elements(i, t_case))) + # ordinal, joined + else: + chunk_words.extend( + self.__chunk_ordinal_join(n3, n2, n1, i, **kwargs) + ) + if i > 0: + chunk_words.append( + get_num_element(THOUSANDS_ORD, i, **kwargs)) - if n2 == 1: - words.append(TENS[n1][0]) - elif n1 > 0: - ones = ONES_FEMININE if i == 1 or feminine and i == 0 else ONES - words.append(ones[n1][0]) + chunk_words = [''.join(chunk_words)] - if i > 0: - words.append(self.pluralize(x, THOUSANDS[i])) + words.extend(chunk_words) return ' '.join(words) + + def __chunk_cardianl(self, hundreds, tens, ones, chunk_num, **kwargs): + words = [] + if hundreds > 0: + words.append(get_num_element(HUNDREDS, hundreds, **kwargs)) + + if tens > 1: + words.append(get_num_element(TWENTIES, tens, **kwargs)) + + if tens == 1: + words.append(get_num_element(TENS, ones, **kwargs)) + elif ones > 0: + if chunk_num == 0: + w_ones = get_num_element(ONES, ones, **kwargs) + elif chunk_num == 1: + # Thousands are feminine + f_kwargs = kwargs.copy() + f_kwargs['gender'] = 'f' + w_ones = get_num_element(ONES, ones, **f_kwargs) + else: + w_ones = get_num_element(ONES, ones, **kwargs) + + words.append(w_ones) + return words + + def __chunk_ordinal(self, hundreds, tens, ones, chunk_num, **kwargs): + words = [] + if hundreds > 0: + if tens == 0 and ones == 0: + words.append(get_num_element(HUNDREDS_ORD, hundreds, **kwargs)) + else: + words.append(get_num_element(HUNDREDS, hundreds)) + + if tens > 1: + if ones == 0: + words.append(get_num_element(TWENTIES_ORD, tens, **kwargs)) + else: + words.append(get_num_element(TWENTIES, tens)) + + if tens == 1: + words.append(get_num_element(TENS_ORD, ones, **kwargs)) + elif ones > 0: + if chunk_num == 0: + w_ones = get_num_element(ONES_ORD, ones, **kwargs) + # тысячный, миллионнный и т.д. + elif chunk_num > 0 and ones == 1 and hundreds == 0 and tens == 0: + w_ones = None + elif chunk_num == 1: + # Thousands are feminine + w_ones = get_num_element(ONES, ones, gender='f') + else: + w_ones = get_num_element(ONES, ones) + + if w_ones: + words.append(w_ones) + + return words + + def __chunk_ordinal_join(self, hundreds, tens, ones, chunk_num, **kwargs): + words = [] + + if hundreds > 1: + words.append(get_num_element(HUNDREDS, hundreds, case='g')) + elif hundreds == 1: + words.append(get_num_element(HUNDREDS, hundreds)) # стО, not стА + + if tens == 9: + words.append(get_num_element(TWENTIES, tens)) # девяностО, not А + elif tens > 1: + words.append(get_num_element(TWENTIES, tens, case='g')) + + if tens == 1: + words.append(get_num_element(TENS, ones, case='g')) + elif ones > 0: + if chunk_num == 0: + w_ones = get_num_element(ONES_ORD, ones, **kwargs) + # тысячный, миллионнный и т.д., двадцатиодномиллионный + elif chunk_num > 0 and ones == 1 and tens != 1: + if tens == 0 and hundreds == 0: + w_ones = None + else: + w_ones = get_num_element(ONES, 1, gender='n') + else: + w_ones = get_num_element(ONES, ones, case='g') + + if w_ones: + words.append(w_ones) + + return words diff --git a/num2words/lang_SK.py b/num2words/lang_SK.py new file mode 100644 index 00000000..35ece024 --- /dev/null +++ b/num2words/lang_SK.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# 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 + +from .base import Num2Word_Base +from .utils import get_digits, splitbyx + +ZERO = ('nula',) + +ONES = { + 1: ('jeden', 'jeden', set()), + 2: ('dva', 'dve', {1, 3, 5, 7, 9}), + 3: ('tri', 'tri', set()), + 4: ('štyri', 'štyri', set()), + 5: ('päť', 'päť', set()), + 6: ('šesť', 'šesť', set()), + 7: ('sedem', 'sedem', set()), + 8: ('osem', 'osem', set()), + 9: ('deväť', 'deväť', set()), +} + +TENS = { + 0: ('desať',), + 1: ('jedenásť',), + 2: ('dvanásť',), + 3: ('trinásť',), + 4: ('štrnásť',), + 5: ('pätnásť',), + 6: ('šestnásť',), + 7: ('sedemnásť',), + 8: ('osemnásť',), + 9: ('devätnásť',), +} + +TWENTIES = { + 2: ('dvadsať',), + 3: ('tridsať',), + 4: ('štyridsať',), + 5: ('päťdesiat',), + 6: ('šesťdesiat',), + 7: ('sedemdesiat',), + 8: ('osemdesiat',), + 9: ('deväťdesiat',), +} + +HUNDREDS = { + 1: ('sto',), + 2: ('dvesto',), + 3: ('tristo',), + 4: ('štyristo',), + 5: ('päťsto',), + 6: ('šesťsto',), + 7: ('sedemsto',), + 8: ('osemsto',), + 9: ('deväťsto',), +} + +THOUSANDS = { + 1: ('tisíc', 'tisíc', 'tisíc'), # 10^3 + 2: ('milión', 'milióny', 'miliónov'), # 10^6 + 3: ('miliarda', 'miliardy', 'miliárd'), # 10^9 + 4: ('bilión', 'bilióny', 'biliónov'), # 10^12 + 5: ('biliarda', 'biliardy', 'biliárd'), # 10^15 + 6: ('trilión', 'trilióny', 'triliónov'), # 10^18 + 7: ('triliarda', 'triliardy', 'triliárd'), # 10^21 + 8: ('kvadrilión', 'kvadrilióny', 'kvadriliónov'), # 10^24 + 9: ('kvadriliarda', 'kvadriliardy', 'kvadriliárd'), # 10^27 + 10: ('kvintilión', 'kvintillióny', 'kvintiliónov'), # 10^30 +} + + +class Num2Word_SK(Num2Word_Base): + CURRENCY_FORMS = { + 'EUR': ( + ('euro', 'eurá', 'eur'), ('cent', 'centy', 'centov') + ), + } + + def setup(self): + self.negword = "mínus" + self.pointword = "celých" + + def to_cardinal(self, number): + n = str(number).replace(',', '.') + if '.' in n: + left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + self._int2word(int(right))) + return u'%s %s %s' % ( + self._int2word(int(left)), + self.pointword, + decimal_part + ) + else: + return self._int2word(int(n)) + + def pluralize(self, n, forms): + if n == 1: + form = 0 + elif 0 < n < 5: + form = 1 + else: + form = 2 + return forms[form] + + def to_ordinal(self, value): + raise NotImplementedError() + + def _int2word(self, n): + if n == 0: + return ZERO[0] + + words = [] + chunks = list(splitbyx(str(n), 3)) + i = len(chunks) + for x in chunks: + i -= 1 + + if x == 0: + continue + + n1, n2, n3 = get_digits(x) + + word_chunk = [] + + if n3 > 0: + word_chunk.append(HUNDREDS[n3][0]) + + if n2 > 1: + word_chunk.append(TWENTIES[n2][0]) + + if n2 == 1: + word_chunk.append(TENS[n1][0]) + elif n1 > 0 and not (i > 0 and x == 1): + if n2 == 0 and n3 == 0 and i in ONES[n1][2]: + word_chunk.append(ONES[n1][1]) + else: + word_chunk.append(ONES[n1][0]) + if i > 1 and word_chunk: + word_chunk.append(' ') + if i > 0: + word_chunk.append(self.pluralize(x, THOUSANDS[i])) + words.append(''.join(word_chunk)) + + return ' '.join(words[:-1]) + ''.join(words[-1:]) diff --git a/num2words/lang_SL.py b/num2words/lang_SL.py index 5472a613..617b0335 100644 --- a/num2words/lang_SL.py +++ b/num2words/lang_SL.py @@ -22,8 +22,8 @@ class Num2Word_SL(Num2Word_EU): - GIGA_SUFFIX = "iljard" - MEGA_SUFFIX = "iljon" + GIGA_SUFFIX = "ilijard" + MEGA_SUFFIX = "ilijon" def setup(self): super(Num2Word_SL, self).setup() @@ -31,12 +31,14 @@ def setup(self): self.negword = "minus " self.pointword = "celih" self.errmsg_nonnum = "Only numbers may be converted to words." - self.errmsg_toobig = "Number is too large to convert to words." + self.errmsg_toobig = ( + "Number is too large to convert to words (abs(%s) > %s)." + ) self.exclude_title = [] self.mid_numwords = [(1000, "tisoč"), (900, "devetsto"), (800, "osemsto"), (700, "sedemsto"), - (600, "šesto"), (500, "petsto"), + (600, "šeststo"), (500, "petsto"), (400, "štiristo"), (300, "tristo"), (200, "dvesto"), (100, "sto"), (90, "devetdeset"), (80, "osemdeset"), @@ -57,16 +59,31 @@ def setup(self): "osem": "osm", "sto": "stot", "tisoč": "tisoč", - "miljon": "miljont" + "milijon": "milijont" } self.ordflag = False def merge(self, curr, next): ctext, cnum, ntext, nnum = curr + next - if ctext == "dve" and not self.ordflag: + if ctext.endswith("dve") and self.ordflag and nnum <= 1000000: + ctext = ctext[:len(ctext)-1] + "a" + + if ctext == "dve" and not self.ordflag and nnum < 1000000000: ctext = "dva" + if (ctext.endswith("tri") or ctext.endswith("štiri")) and\ + nnum == 1000000 and not self.ordflag: + if ctext.endswith("štiri"): + ctext = ctext[:-1] + ctext = ctext + "je" + + if cnum >= 20 and cnum < 100 and nnum == 2: + ntext = "dva" + + if ctext.endswith("ena") and nnum >= 1000: + ctext = ctext[0:-1] + if cnum == 1: if nnum < 10**6 or self.ordflag: return next @@ -89,15 +106,28 @@ def merge(self, curr, next): elif not ntext.endswith("d"): ntext += "i" + elif ctext.endswith("en"): + if ntext.endswith("d") or ntext.endswith("n"): + ntext += "" + + elif ctext.endswith("dve") and ntext.endswith("n"): + ctext = ctext[:-1] + "a" + ntext += "a" + + elif ctext.endswith("je") and ntext.endswith("n"): + ntext += "i" + else: if ntext.endswith("d"): + ntext += "a" + elif ntext.endswith("n"): ntext += "" elif ntext.endswith("d"): ntext += "e" else: ntext += "ov" - if nnum >= 10**2 and self.ordflag is False: + if nnum >= 10**2 and self.ordflag is False and ctext: ctext += " " val = cnum * nnum diff --git a/num2words/lang_SR.py b/num2words/lang_SR.py index 919cad03..254209fe 100644 --- a/num2words/lang_SR.py +++ b/num2words/lang_SR.py @@ -110,10 +110,13 @@ def to_cardinal(self, number, feminine=False): n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') + leading_zero_count = len(right) - len(right.lstrip('0')) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + self._int2word(int(right), feminine)) return u'%s %s %s' % ( self._int2word(int(left), feminine), self.pointword, - self._int2word(int(right), feminine) + decimal_part ) else: return self._int2word(int(n), feminine) @@ -173,14 +176,14 @@ def _int2word(self, number, feminine=False): return ' '.join(words) - def to_currency(self, val, currency='EUR', cents=True, seperator=',', + def to_currency(self, val, currency='EUR', cents=True, separator=',', adjective=False): """ Args: val: Numeric value currency (str): Currency code cents (bool): Verbose cents - seperator (str): Cent seperator + separator (str): Cent separator adjective (bool): Prefix currency name with adjective Returns: str: Formatted string @@ -210,7 +213,7 @@ def to_currency(self, val, currency='EUR', cents=True, seperator=',', minus_str, self.to_cardinal(left, feminine=cr1[-1]), self.pluralize(left, cr1), - seperator, + separator, cents_str, self.pluralize(right, cr2) ) diff --git a/num2words/lang_SV.py b/num2words/lang_SV.py new file mode 100644 index 00000000..4e32841c --- /dev/null +++ b/num2words/lang_SV.py @@ -0,0 +1,117 @@ +# -*- 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_SV(lang_EU.Num2Word_EU): + GIGA_SUFFIX = "iljarder" + MEGA_SUFFIX = "iljoner" + + def set_high_numwords(self, high): + cap = 3 + 6 * len(high) + + for word, n in zip(high, range(cap, 3, -6)): + if self.GIGA_SUFFIX: + self.cards[10 ** n] = word + self.GIGA_SUFFIX + + if self.MEGA_SUFFIX: + self.cards[10 ** (n - 3)] = word + self.MEGA_SUFFIX + + def setup(self): + super(Num2Word_SV, self).setup() + + self.negword = "minus " + self.pointword = "komma" + self.exclude_title = ["och", "komma", "minus"] + + self.mid_numwords = [(1000, "tusen"), (100, "hundra"), + (90, "nittio"), (80, "åttio"), (70, "sjuttio"), + (60, "sextio"), (50, "femtio"), (40, "förtio"), + (30, "trettio")] + self.low_numwords = ["tjugo", "nitton", "arton", "sjutton", + "sexton", "femton", "fjorton", "tretton", + "tolv", "elva", "tio", "nio", "åtta", + "sju", "sex", "fem", "fyra", "tre", "två", + "ett", "noll"] + self.ords = {"noll": "nollte", + "ett": "första", + "två": "andra", + "tre": "tredje", + "fyra": "fjärde", + "fem": "femte", + "sex": "sjätte", + "sju": "sjunde", + "åtta": "åttonde", + "nio": "nionde", + "tio": "tionde", + "elva": "elfte", + "tolv": "tolfte", + "tjugo": "tjugonde"} + + 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 >= 1000000 and lnum == 1: + return ("%s %s" % ('en', rtext[:-2]), lnum + rnum) + elif rnum >= 1000000 and lnum > 1: + 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(" ") + lastword = outwords[-1] + ending_length = 0 + try: + lastword_ending = self.ords[lastword[-4:]] + ending_length = 4 + except KeyError: + try: + lastword_ending = self.ords[lastword[-3:]] + ending_length = 3 + except KeyError: + lastword_ending = "de" + if lastword_ending == 'de': + lastword_first_part = self.title(lastword)[:] + else: + lastword_first_part = self.title(lastword)[:-ending_length] + lastword_correct = lastword_first_part + lastword_ending + outwords[-1] = lastword_correct + return " ".join(outwords) + + def to_ordinal_num(self, value): + raise NotImplementedError( + "'ordinal_num' is not implemented for swedish language") + + def to_year(self, val, longval=True): + raise NotImplementedError( + "'year' is not implemented for swedish language") + + def to_currency(self, val, longval=True): + raise NotImplementedError( + "'currency' is not implemented for swedish language") diff --git a/num2words/lang_TE.py b/num2words/lang_TE.py new file mode 100644 index 00000000..274d3125 --- /dev/null +++ b/num2words/lang_TE.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals + +from .lang_EU import Num2Word_EU + + +class Num2Word_TE(Num2Word_EU): + def set_high_numwords(self, high): + for n, word in self.high_numwords: + self.cards[10**n] = word + + def setup(self): + self.low_numwords = [ + "తొంభై తొమ్మిది", + "తొంభై ఎనిమిది", + "తొంభై ఏడు", + "తొంభై ఆరు", + "తొంభై అయిదు", + "తొంభై నాలుగు", + "తొంభై మూడు", + "తొంభై రెండు", + "తొంభై ఒకటి", + "తొంభై", + "ఎనభై తొమ్మిది", + "ఎనభై ఎనిమిది", + "ఎనభై ఏడు", + "ఎనభై ఆరు", + "ఎనభై అయిదు", + "ఎనభై నాలుగు", + "ఎనభై మూడు", + "ఎనభై రెండు", + "ఎనభై ఒకటి", + "ఎనభై", + "డెబ్బై తొమ్మిది", + "డెబ్బై ఎనిమిది", + "డెబ్బై ఏడు", + "డెబ్బై ఆరు", + "డెబ్బై అయిదు", + "డెబ్బై నాలుగు", + "డెబ్బై మూడు", + "డెబ్బై రెండు", + "డెబ్బై ఒకటి", + "డెబ్బై", + "అరవై తొమ్మిది", + "అరవై ఎనిమిది", + "అరవై ఏడు", + "అరవై ఆరు", + "అరవై అయిదు", + "అరవై నాలుగు", + "అరవై మూడు", + "అరవై రెండు", + "అరవై ఒకటి", + "అరవై", + "యాభై తొమ్మిది", + "యాభై ఎనిమిది", + "యాభై ఏడు", + "యాభై ఆరు", + "యాభై అయిదు", + "యాభై నాలుగు", + "యాభై మూడు", + "యాభై రెండు", + "యాభై ఒకటి", + "యాభై ", + "నలభై తొమ్మిది", + "నలభై ఎనిమిది", + "నలభై ఏడు", + "నలభై ఆరు", + "నలభై అయిదు", + "నలభై నాలుగు", + "నలభై మూడు", + "నలభై రెండు", + "నలభై ఒకటి", + "నలభై", + "ముప్పై తొమ్మిది", + "ముప్పై ఎనిమిది", + "ముప్పై ఏడు", + "ముప్పై ఆరు", + "ముప్పై ఐదు", + "ముప్పై నాలుగు", + "ముప్పై మూడు", + "ముప్పై రెండు", + "ముప్పై ఒకటి", + "ముప్పై", + "ఇరవై తొమ్మిది", + "ఇరవై ఎనిమిది", + "ఇరవై ఏడు", + "ఇరవై ఆరు", + "ఇరవై అయిదు", + "ఇరవై నాలుగు", + "ఇరవై మూడు", + "ఇరవై రెండు", + "ఇరవై ఒకటి", + "ఇరవై", + "పందొమ్మిది", + "పధ్ధెనిమిది", + "పదిహేడు", + "పదహారు", + "పదునయిదు", + "పధ్నాలుగు", + "పదమూడు", + "పన్నెండు", + "పదకొండు", + "పది", + "తొమ్మిది", + "ఎనిమిది", + "ఏడు", + "ఆరు", + "అయిదు", + "నాలుగు", + "మూడు", + "రెండు", + "ఒకటి", + "సున్న", + ] + + self.mid_numwords = [(100, "వంద")] + + self.high_numwords = [(7, "కోట్ల"), (5, "లక్ష"), (3, "వేయి")] + + self.pointword = "బిందువు " + + self.modifiers = [ + " ్ ", + "ా ", + " ి ", + " ీ ", + " ు ", + " ూ ", + " ృ ", + " ౄ ", + " ె ", + " ే ", + " ై ", + " ొ", + " ో ", + " ౌ ", + " ఁ ", + " ం ", + " ః ", + ] + + 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: + if ltext[-1] in self.modifiers: + return ("%s %s" % (ltext[:-1], rtext), lnum + rnum) + else: + 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_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-1:]) + + def to_ordinal(self, value): + self.verify_ordinal(value) + outwords = self.to_cardinal(value) + if outwords[-1] in self.modifiers: + outwords = outwords[:-1] + ordinal_num = outwords + "వ" + return ordinal_num diff --git a/num2words/lang_TET.py b/num2words/lang_TET.py new file mode 100644 index 00000000..141a8c66 --- /dev/null +++ b/num2words/lang_TET.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*-Num2Word_TET +# 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 num2words.currency import parse_currency_parts + +from .lang_EU import Num2Word_EU + +DOLLAR = ('dolar', 'dolar') +CENTS = ('sentavu', 'sentavu') + + +class Num2Word_TET(Num2Word_EU): + + CURRENCY_FORMS = { + 'AUD': (DOLLAR, CENTS), + 'CAD': (DOLLAR, CENTS), + 'EUR': (('euro', 'euros'), CENTS), + 'GBP': (('pound sterling', 'pound sterling'), ('pence', 'pence')), + 'USD': (DOLLAR, CENTS), + } + + GIGA_SUFFIX = None + MEGA_SUFFIX = "iliaun" + + def setup(self): + super().setup() + lows = ["kuatr", "tr", "b", "m"] + self.high_numwords = self.gen_high_numwords([], [], lows) + self.negword = "menus " + self.pointword = "vírgula" + self.exclude_title = ["resin", "vírgula", "menus"] + self.count = 0 + + self.mid_numwords = [ + (1000, "rihun"), (100, "atus"), (90, "sianulu"), + (80, "ualunulu"), (70, "hitunulu"), (60, "neenulu"), + (50, "limanulu"), (40, "haatnulu"), (30, "tolunulu"), + (20, "ruanulu") + ] + self.low_numwords = [ + "sanulu", + "sia", "ualu", "hitu", "neen", "lima", "haat", "tolu", "rua", + "ida", "mamuk" + ] + self.hundreds = { + 1: "atus", + 2: "atus rua", + 3: "atus tolu", + 4: "atus haat", + 5: "atus lima", + 6: "atus neen", + 7: "atus hitu", + 8: "atus ualu", + 9: "atus sia", + } + + def merge(self, curr, next): + ctext, cnum, ntext, nnum = curr + next + + if cnum == 1 and nnum < 100: + return next + + if nnum < cnum: + if nnum < 10: + value_str = str(cnum + nnum) + if int(value_str) > 100: + zero_list = value_str[1:-1] + all_zero = all(element == '0' for element in zero_list) + if all_zero: + if self.count >= 1: + self.count += 0 + return ( + "ho %s %s" % (ctext, ntext), + cnum + nnum + ) + self.count += 1 + return ("%s %s" % (ctext, ntext), cnum + nnum) + + return ("%s resin %s" % (ctext, ntext), cnum + nnum) + else: + return ("%s %s" % (ctext, ntext), cnum + nnum) + + return (ntext + " " + ctext, cnum * nnum) + + def ho_result(self, result, value): + index = result.find('ho') + count_ho = result.count('ho') + + if index != -1 and count_ho >= 1: + index_rihun = result.find('rihun') + value_str = len(str(value)) + if index_rihun != -1 and value_str > 7: + result = result.replace("rihun ho", "ho rihun") + lows = ["kuatr", "tr", "b", "m"] + MEGA_SUFFIX = "iliaun" + for low in lows: + result = result.replace( + low + MEGA_SUFFIX + " ho", "ho " + low + MEGA_SUFFIX) + remove_first_ho = result.startswith('ho') + if remove_first_ho: + result = result[3:] + return result + + def remove_ho(self, result, value): + value_str = str(value) + result = self.ho_result(result, value) + end_value = value_str[:-4] + end_true = end_value.endswith('0') + if end_true is False: + if value > 100: + if value_str[-1] != '0' and value_str[-2] == '0': + result = result.replace("ho", "") + result = result.replace(" ", " ") + + return result + + def to_cardinal(self, value): + result = super().to_cardinal(value) + + results = self.remove_ho(result, value) + return results + + def to_ordinal(self, value): + self.verify_ordinal(value) + out = "" + val = self.splitnum(value) + outs = val + while len(val) != 1: + outs = [] + left, right = val[:2] + if isinstance(left, tuple) and isinstance(right, tuple): + outs.append(self.merge(left, right)) + if val[2:]: + outs.append(val[2:]) + else: + for elem in val: + if isinstance(elem, list): + if len(elem) == 1: + outs.append(elem[0]) + else: + outs.append(self.clean(elem)) + else: + outs.append(elem) + val = outs + + words, num = outs[0] + + words = self.remove_ho(words, value) + + if num in [90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 5, 3, 2]: + words = 'da'+words+'k' + if num in [6, 4]: + words = 'da'+words + if num == 1: + words = 'dahuluk' + if num in [900, 800, 700, 500, 300, 200, 100]: + words = 'dah'+words+'k' + if num in [600, 400]: + words = 'dah'+words + + words_split = words.split() + if len(words_split) >= 3 and num < 100: + first_word = 'da'+words_split[0] + second_word = " ".join(words_split[1:]) + if 'haat' in second_word or 'neen' in second_word: + words = first_word+" "+second_word + else: + words = first_word+" "+second_word+'k' + + word_first = 'dah'+words_split[0] + if word_first == 'dahatus' and len(words_split) >= 3: + word_second = " ".join(words_split[1:]) + if 'haat' in word_second or 'neen' in word_second: + words = word_first+" "+word_second + else: + words = word_first+" "+word_second+'k' + + if len(str(num)) > 3: + if 'haat' in words_split[-1:] or 'neen' in words_split[-1:]: + words = 'da'+words + else: + words = 'da'+words+'k' + + result = self.title(out + words) + + return result + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%sº" % (value) + + def to_year(self, val, longval=True): + if val < 0: + return self.to_cardinal(abs(val)) + ' antes Kristu' + return self.to_cardinal(val) + + def to_currency(self, val, currency='USD', cents=True): + """ + Args: + val: Numeric value + currency (str): Currency code + cents (bool): Verbose cents + adjective (bool): Prefix currency name with adjective + Returns: + str: Formatted string + + """ + left, right, is_negative = parse_currency_parts(val) + + try: + cr1, cr2 = self.CURRENCY_FORMS[currency] + + except KeyError: + raise NotImplementedError( + 'Currency code "%s" not implemented for "%s"' % + (currency, self.__class__.__name__)) + + minus_str = "%s " % self.negword.strip() if is_negative else "" + money_str = self._money_verbose(left, currency) + cents_str = self._cents_verbose(right, currency) \ + if cents else self._cents_terse(right, currency) + + if right == 0: + return u'%s%s %s' % ( + minus_str, + self.pluralize(left, cr1), + money_str + ) + else: + return u'%s%s %s %s %s' % ( + minus_str, + self.pluralize(left, cr1), + money_str, + self.pluralize(right, cr2), + cents_str + ) diff --git a/num2words/lang_TG.py b/num2words/lang_TG.py new file mode 100644 index 00000000..48291a26 --- /dev/null +++ b/num2words/lang_TG.py @@ -0,0 +1,149 @@ +# -*- 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 + +GENERIC_DOLLARS = ("доллар", "доллар") +GENERIC_CENTS = ("сент", "сент") + + +class Num2Word_TG(lang_EU.Num2Word_EU): + CURRENCY_FORMS = { + # repalced by EUR + "EUR": (("евро", "евро"), GENERIC_CENTS), + # replaced by EUR + "USD": (GENERIC_DOLLARS, GENERIC_CENTS), + "RUB": (("рубл", "рубл"), ("копейк", "копейк")), + "TJS": (("сомонӣ", "сомонӣ"), ("дирам", "дирам")), + } + + 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_TG, self).setup() + + lows = ["квинт", "квадр", "тр", "м", "м"] + self.high_numwords = self.gen_high_numwords([], [], lows) + self.negword = "минус " + self.pointword = "нуқта" + self.exclude_title = ["ва", "минус", "нуқта"] + + self.mid_numwords = [ + (1000, "ҳазор"), + (100, "сад"), + (90, "навад"), + (80, "ҳаштод"), + (70, "ҳафтод"), + (60, "шаст"), + (50, "панҷоҳ"), + (40, "чил"), + (30, "си"), + ] + self.low_numwords = [ + "бист", + "нуздаҳ", + "ҳаждаҳ", + "ҳабдаҳ", + "шонздаҳ", + "понздаҳ", + "чордаҳ", + "сенздаҳ", + "дувоздаҳ", + "ёздаҳ", + "даҳ", + "нӯҳ", + "ҳашт", + "ҳафт", + "шаш", + "панҷ", + "чор", + "се", + "ду", + "як", + "сифр", + ] + + 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 + rtext, rnum = rpair + if lnum == 1 and rnum < 100: + return (rtext, rnum) + elif 100 > lnum > rnum: + if ltext == "си": + return ("%sю %s" % (ltext, rtext), lnum + rnum) + elif ltext == "панҷоҳ": + return ("панҷову %s" % (rtext), lnum + rnum) + else: + return ("%sу %s" % (ltext, rtext), lnum + rnum) + elif lnum >= 100 > rnum: + return ("%sу %s" % (ltext, rtext), lnum + rnum) + elif rnum > lnum: + if ltext == "яксад" and rtext not in self.low_numwords: + return ("сад %s" % (rtext), lnum * rnum) + if rtext == "сад": + return ("%s%s" % (ltext, rtext), lnum * rnum) + else: + return ("%s %s" % (ltext, rtext), lnum * rnum) + return ("%sу %s" % (ltext, rtext), lnum + rnum) + + def to_ordinal(self, value): + self.verify_ordinal(value) + cardinal = self.to_cardinal(value) + outwords = cardinal.split(" ") + lastword = outwords[-1] + if lastword in ["ду", "се", "си"]: + return "%sюм" % (cardinal) + else: + return "%sум" % (cardinal) + + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-2:]) diff --git a/num2words/lang_TR.py b/num2words/lang_TR.py index 3f43fedd..2f20dd66 100644 --- a/num2words/lang_TR.py +++ b/num2words/lang_TR.py @@ -18,23 +18,25 @@ from __future__ import unicode_literals +from .base import Num2Word_Base -class Num2Word_TR(object): + +class Num2Word_TR(Num2Word_Base): def __init__(self): self.precision = 2 self.negword = u"eksi" self.pointword = u"virgül" - self.CURRENCY_UNIT = (u"lira",) - self.CURRENCY_SUBUNIT = (u"kuruş",) + self.CURRENCY_UNIT = u"lira" + self.CURRENCY_SUBUNIT = u"kuruş" self.errmsg_nonnum = u"Sadece sayılar yazıya çevrilebilir." self.errmsg_floatord = u"Tam sayı olmayan {} sıralamada kullanılamaz." self.errmsg_negord = u"Pozitif olmayan {} sıralamada kullanılamaz." self.errmsg_toobig = u"abs({}) sayı yazıya çevirmek için çok büyük. " \ u"Yazıya çevrilebilecek en büyük rakam {}." self.exclude_title = [] - self.DECIMAL_SIGN = (",",) - self.ORDINAL_SIGN = (".",) - self.ZERO = (u"sıfır",) + self.DECIMAL_SIGN = "," + self.ORDINAL_SIGN = "." + self.ZERO = u"sıfır" self.CARDINAL_ONES = { "1": u"bir", "2": u"iki", @@ -122,11 +124,17 @@ def to_cardinal(self, value): if not int(value) == value: return self.to_cardinal_float(value) + + if str(value).startswith("-"): + pre_word, value = self.negword, float(str(value)[1:]) + else: + pre_word, value = "", float(value) + self.to_splitnum(value) if self.order_of_last_zero_digit >= len(self.integers_to_read[0]): # number like 00 and all 0s and even more, raise error - return wrd + return "%s%s" % (pre_word, wrd) if self.total_triplets_to_read == 1: if self.total_digits_outside_triplets == 2: @@ -135,7 +143,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TENS.get( self.integers_to_read[0][0], "" ) - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit == 0: # number like xy, read cardinal xy and return wrd += self.CARDINAL_TENS.get( @@ -144,7 +152,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_ONES.get( self.integers_to_read[0][1], "" ) - return wrd + return "%s%s" % (pre_word, wrd) if self.total_digits_outside_triplets == 1: if self.order_of_last_zero_digit == 0: @@ -152,7 +160,9 @@ def to_cardinal(self, value): wrd += self.CARDINAL_ONES.get( self.integers_to_read[0][0], "" ) - return wrd + if self.integers_to_read[0][0] == "0": + return self.ZERO + return "%s%s" % (pre_word, wrd) if self.total_digits_outside_triplets == 0: if self.order_of_last_zero_digit == 2: @@ -161,7 +171,7 @@ def to_cardinal(self, value): self.integers_to_read[0][0], "" ) wrd += self.CARDINAL_HUNDRED[0] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit == 1: # number like xy0, read cardinal xy0 and return wrd += self.HUNDREDS.get( @@ -171,7 +181,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TENS.get( self.integers_to_read[0][1], "" ) - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit == 0: # number like xyz, read cardinal xyz and return wrd += self.HUNDREDS.get( @@ -184,7 +194,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_ONES.get( self.integers_to_read[0][2], "" ) - return wrd + return "%s%s" % (pre_word, wrd) if self.total_triplets_to_read >= 2: if self.total_digits_outside_triplets == 2: @@ -198,7 +208,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[ self.total_triplets_to_read - 1 ] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit == len( self.integers_to_read[0]) - 2: # number like xy and all 0s, read cardinal xy 0..0 @@ -212,7 +222,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[ self.total_triplets_to_read - 1 ] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit < len( self.integers_to_read[0]) - 2: # number like xy and others, read cardinal xy n..n @@ -240,7 +250,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[ self.total_triplets_to_read - 1 ] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit < len( self.integers_to_read[0]) - 1: # number like x and others, read cardinal x n..n @@ -264,7 +274,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[ self.total_triplets_to_read - 1 ] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit == len( self.integers_to_read[0]) - 2: # number like xy0 and all 0s, read cardinal xy0 0..0 @@ -279,7 +289,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[ self.total_triplets_to_read - 1 ] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit == len( self.integers_to_read[0]) - 3: # number like xyz and all 0s, read cardinal xyz 0..0 @@ -295,7 +305,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[ self.total_triplets_to_read - 1 ] - return wrd + return "%s%s" % (pre_word, wrd) if self.order_of_last_zero_digit < len( self.integers_to_read[0]) - 3: # number like xyz and all others, read cardinal xyz n..n @@ -335,11 +345,11 @@ def to_cardinal(self, value): last_read_digit_order) - 1: if i == 1: wrd += self.CARDINAL_HUNDRED[0] - return wrd + return "%s%s" % (pre_word, wrd) elif i > 1: wrd += self.CARDINAL_HUNDRED[0] wrd += self.CARDINAL_TRIPLETS[i - 1] - return wrd + return "%s%s" % (pre_word, wrd) else: wrd += self.CARDINAL_HUNDRED[0] @@ -353,14 +363,14 @@ def to_cardinal(self, value): self.integers_to_read[0][ last_read_digit_order + 1], "" ) - return wrd + return "%s%s" % (pre_word, wrd) elif i > 1: wrd += self.CARDINAL_TENS.get( self.integers_to_read[0][ last_read_digit_order + 1], "" ) wrd += self.CARDINAL_TRIPLETS[i - 1] - return wrd + return "%s%s" % (pre_word, wrd) else: wrd += self.CARDINAL_TENS.get( self.integers_to_read[0][ @@ -377,7 +387,7 @@ def to_cardinal(self, value): self.integers_to_read[0][ last_read_digit_order + 2], "" ) - return wrd + return "%s%s" % (pre_word, wrd) if i == 2: if not self.integers_to_read[0][ last_read_digit_order: @@ -394,14 +404,14 @@ def to_cardinal(self, value): last_read_digit_order + 2], "" ) wrd += self.CARDINAL_TRIPLETS[i - 1] - return wrd + return "%s%s" % (pre_word, wrd) if i > 2: wrd += self.CARDINAL_ONES.get( self.integers_to_read[0][ last_read_digit_order + 2], "" ) wrd += self.CARDINAL_TRIPLETS[i - 1] - return wrd + return "%s%s" % (pre_word, wrd) else: if not self.integers_to_read[0][ last_read_digit_order: @@ -431,7 +441,7 @@ def to_cardinal(self, value): wrd += self.CARDINAL_TRIPLETS[i - 1] - return wrd + return "%s%s" % (pre_word, wrd) def to_cardinal_float(self, value): self.to_splitnum(value) @@ -444,7 +454,7 @@ def to_cardinal_float(self, value): wrd += self.CARDINAL_ONES.get(self.integers_to_read[1][1], "") if self.integers_to_read[0] == "0": - wrd = self.ZERO[0] + wrd + wrd = self.ZERO + wrd else: wrd = self.to_cardinal(int(self.integers_to_read[0])) + wrd return wrd @@ -507,6 +517,8 @@ def to_ordinal(self, value): wrd += self.ORDINAL_ONES.get( self.integers_to_read[0][0], "" ) + if self.integers_to_read[0][0] == "0": + return u"sıfırıncı" return wrd if self.total_digits_outside_triplets == 0: @@ -800,6 +812,10 @@ def to_ordinal(self, value): return wrd + def to_ordinal_num(self, value): + self.verify_ordinal(value) + return "%s%s" % (value, self.to_ordinal(value)[-4:]) + def to_splitnum(self, val): float_digits = str(int(val * 10 ** self.precision)) if not int(val) == 0: @@ -830,9 +846,11 @@ def to_splitnum(self, val): found = 1 def to_currency(self, value): + if int(value) == 0: + return u"bedelsiz" valueparts = self.to_cardinal(value).split(self.pointword) if len(valueparts) == 1: - return valueparts[0] + self.CURRENCY_UNIT[0] + return valueparts[0] + self.CURRENCY_UNIT if len(valueparts) == 2: - return self.CURRENCY_UNIT[0].join(valueparts) + \ - self.CURRENCY_SUBUNIT[0] + return self.CURRENCY_UNIT.join(valueparts) + \ + self.CURRENCY_SUBUNIT diff --git a/num2words/lang_UK.py b/num2words/lang_UK.py index 45f87124..188d7ced 100644 --- a/num2words/lang_UK.py +++ b/num2words/lang_UK.py @@ -23,105 +23,920 @@ ZERO = ('нуль',) ONES_FEMININE = { - 1: ('одна',), - 2: ('двi',), - 3: ('три',), - 4: ('чотири',), - 5: ('п\'ять',), - 6: ('шiсть',), - 7: ('сiм',), - 8: ('вiсiм',), - 9: ('дев\'ять',), + 1: ('одна', "однієї", "одній", "одну", "однією", "одній"), + 2: ('дві', "двох", "двом", "дві", "двома", "двох"), + 3: ('три', "трьох", "трьом", "три", "трьома", "трьох"), + 4: ('чотири', "чотирьох", "чотирьом", "чотири", "чотирма", "чотирьох"), + 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), + 6: ('шість', "шести", "шести", "шість", "шістьма", "шести"), + 7: ('сім', "семи", "семи", "сім", "сьома", "семи"), + 8: ('вісім', "восьми", "восьми", "вісім", "вісьма", "восьми"), + 9: ("дев'ять", "дев'яти", "дев'яти", "дев'ять", "дев'ятьма", "дев'яти"), } ONES = { - 1: ('один',), - 2: ('два',), - 3: ('три',), - 4: ('чотири',), - 5: ('п\'ять',), - 6: ('шiсть',), - 7: ('сiм',), - 8: ('вiсiм',), - 9: ('дев\'ять',), + 1: ('один', 'одного', "одному", "один", "одним", "одному"), + 2: ('два', 'двох', "двом", "два", "двома", "двох"), + 3: ('три', 'трьох', "трьом", "три", "трьома", "трьох"), + 4: ('чотири', 'чотирьох', "чотирьом", "чотири", "чотирма", "чотирьох"), + 5: ('п\'ять', "п'яти", "п'яти", "п'ять", "п'ятьма", "п'яти"), + 6: ('шість', 'шести', "шести", "шість", "шістьма", "шести"), + 7: ('сім', 'семи', "семи", "сім", "сьома", "семи"), + 8: ('вісім', 'восьми', "восьми", "вісім", "вісьма", "восьми"), + 9: ("дев'ять", "дев'яти", "дев'яти", "дев'ять", "дев'ятьма", "дев'яти"), } +ONES_ORDINALS = { + 1: ("перший", "одно"), + 2: ("другий", "двох"), + 3: ("третій", "трьох"), + 4: ("четвертий", "чотирьох"), + 5: ("п'ятий", "п'яти"), + 6: ("шостий", "шести"), + 7: ("сьомий", "семи"), + 8: ("восьмий", "восьми"), + 9: ("дев'ятий", "дев'яти"), + 10: ("десятий", "десяти"), + 11: ("одинадцятий", "одинадцяти"), + 12: ("дванадцятий", "дванадцяти"), + 13: ("тринадцятий", "тринадцяти"), + 14: ("чотирнадцятий", "чотирнадцяти"), + 15: ("п'ятнадцятий", "п'ятнадцяти"), + 16: ("шістнадцятий", "шістнадцяти"), + 17: ("сімнадцятий", "сімнадцяти"), + 18: ("вісімнадцятий", "вісімнадцяти"), + 19: ("дев'ятнадцятий", "дев'ятнадцяти"), +} TENS = { - 0: ('десять',), - 1: ('одинадцять',), - 2: ('дванадцять',), - 3: ('тринадцять',), - 4: ('чотирнадцять',), - 5: ('п\'ятнадцять',), - 6: ('шiстнадцять',), - 7: ('сiмнадцять',), - 8: ('вiсiмнадцять',), - 9: ('дев\'ятнадцять',), + 0: ('десять', + 'десяти', + "десяти", + "десять", + "десятьма", + "десяти"), + 1: ('одинадцять', + 'одинадцяти', + "одинадцяти", + "одинадцять", + "одинадцятьма", + "одинадцяти"), + 2: ('дванадцять', + 'дванадцяти', + "дванадцяти", + "дванадцять", + "дванадцятьма", + "дванадцяти"), + 3: ('тринадцять', + 'тринадцяти', + "тринадцяти", + "тринадцять", + "тринадцятьма", + "тринадцяти"), + 4: ('чотирнадцять', + 'чотирнадцяти', + "чотирнадцяти", + "чотирнадцять", + "чотирнадцятьма", + "чотирнадцяти"), + 5: ("п'ятнадцять", + "п'ятнадцяти", + "п'ятнадцяти", + "п'ятнадцять", + "п'ятнадцятьма", + "п'ятнадцяти"), + 6: ('шістнадцять', + 'шістнадцяти', + "шістнадцяти", + "шістнадцять", + "шістнадцятьма", + "шістнадцяти"), + 7: ('сімнадцять', + 'сімнадцяти', + "сімнадцяти", + "сімнадцять", + "сімнадцятьма", + "сімнадцяти"), + 8: ('вісімнадцять', + 'вісімнадцяти', + "вісімнадцяти", + "вісімнадцять", + "вісімнадцятьма", + "вісімнадцяти"), + 9: ("дев'ятнадцять", + "дев'ятнадцяти", + "дев'ятнадцяти", + "дев'ятнадцять", + "дев'ятнадцятьма", + "дев'ятнадцяти"), } TWENTIES = { - 2: ('двадцять',), - 3: ('тридцять',), - 4: ('сорок',), - 5: ('п\'ятдесят',), - 6: ('шiстдесят',), - 7: ('сiмдесят',), - 8: ('вiсiмдесят',), - 9: ('дев\'яносто',), + 2: ('двадцять', + "двадцяти", + "двадцяти", + "двадцять", + "двадцятьма", + "двадцяти"), + 3: ('тридцять', + "тридцяти", + "тридцяти", + "тридцять", + "тридцятьма", + "тридцяти"), + 4: ('сорок', + "сорока", + "сорока", + "сорок", + "сорока", + "сорока"), + 5: ('п\'ятдесят', + "п'ятдесяти", + "п'ятдесяти", + "п'ятдесят", + "п'ятдесятьма", + "п'ятдесяти"), + 6: ('шістдесят', + "шістдесяти", + "шістдесяти", + "шістдесят", + "шістдесятьма", + "шістдесяти"), + 7: ('сімдесят', + "сімдесяти", + "сімдесяти", + "сімдесят", + "сімдесятьма", + "сімдесяти"), + 8: ('вісімдесят', + "вісімдесяти", + "вісімдесяти", + "вісімдесят", + "вісімдесятьма", + "вісімдесяти"), + 9: ('дев\'яносто', + "дев'яноста", + "дев'яноста", + "дев'яносто", + "дев'яностами", + "дев'яноста"), +} + +TWENTIES_ORDINALS = { + 2: ("двадцятий", "двадцяти"), + 3: ("тридцятий", "тридцяти"), + 4: ("сороковий", "сорока"), + 5: ("п'ятдесятий", "п'ятдесяти"), + 6: ("шістдесятий", "шістдесяти"), + 7: ("сімдесятий", "сімдесяти"), + 8: ("вісімдесятий", "вісімдесяти"), + 9: ("дев'яностий", "дев'яности"), } HUNDREDS = { - 1: ('сто',), - 2: ('двiстi',), - 3: ('триста',), - 4: ('чотириста',), - 5: ('п\'ятсот',), - 6: ('шiстсот',), - 7: ('сiмсот',), - 8: ('вiсiмсот',), - 9: ('дев\'ятсот',), + 1: ('сто', + "ста", + "ста", + "сто", + "стами", + "стах"), + 2: ('двісті', + "двохста", + "двомстам", + "двісті", + "двомастами", + "двохстах"), + 3: ('триста', + "трьохста", + "трьомстам", + "триста", + "трьомастами", + "трьохстах"), + 4: ('чотириста', + "чотирьохста", + "чотирьомстам", + "чотириста", + "чотирмастами", + "чотирьохстах"), + 5: ('п\'ятсот', + "п'ятиста", + "п'ятистам", + "п'ятсот", + "п'ятьмастами", + "п'ятистах"), + 6: ('шістсот', + "шестиста", + "шестистам", + "шістсот", + "шістьмастами", + "шестистах"), + 7: ('сімсот', + "семиста", + "семистам", + "сімсот", + "сьомастами", + "семистах"), + 8: ('вісімсот', + "восьмиста", + "восьмистам", + "вісімсот", + "восьмастами", + "восьмистах"), + 9: ("дев'ятсот", + "дев'ятиста", + "дев'ятистам", + "дев'ятсот", + "дев'ятьмастами", + "дев'ятистах"), +} + +HUNDREDS_ORDINALS = { + 1: ("сотий", "сто"), + 2: ("двохсотий", "двохсот"), + 3: ("трьохсотий", "трьохсот"), + 4: ("чотирьохсотий", "чотирьохсот"), + 5: ("п'ятисотий", "п'ятсот"), + 6: ("шестисотий", "шістсот"), + 7: ("семисотий", "сімсот"), + 8: ("восьмисотий", "вісімсот"), + 9: ("дев'ятисотий", "дев'ятсот"), } THOUSANDS = { - 1: ('тисяча', 'тисячi', 'тисяч'), # 10^3 - 2: ('мiльйон', 'мiльйони', 'мiльйонiв'), # 10^6 - 3: ('мiльярд', 'мiльярди', 'мiльярдiв'), # 10^9 - 4: ('трильйон', 'трильйони', 'трильйонiв'), # 10^12 - 5: ('квадрильйон', 'квадрильйони', 'квадрильйонiв'), # 10^15 - 6: ('квiнтильйон', 'квiнтильйони', 'квiнтильйонiв'), # 10^18 - 7: ('секстильйон', 'секстильйони', 'секстильйонiв'), # 10^21 - 8: ('септильйон', 'септильйони', 'септильйонiв'), # 10^24 - 9: ('октильйон', 'октильйони', 'октильйонiв'), # 10^27 - 10: ('нонiльйон', 'нонiльйони', 'нонiльйонiв'), # 10^30 + # 10^3 + 1: (('тисяча', 'тисячі', 'тисяч'), + ('тисячи', 'тисяч', 'тисяч'), + ('тисячі', 'тисячам', 'тисячам'), + ('тисячу', 'тисячі', 'тисяч'), + ('тисячею', 'тисячами', 'тисячами'), + ('тисячі', 'тисячах', 'тисячах'),), + # 10^6 + 2: (('мільйон', 'мільйони', 'мільйонів'), + ('мільйона', 'мільйонів', 'мільйонів'), + ('мільйону', 'мільйонам', 'мільйонам'), + ('мільйон', 'мільйони', 'мільйонів'), + ('мільйоном', 'мільйонами', 'мільйонів'), + ('мільйоні', 'мільйонах', 'мільйонах'),), + # 10^9 + 3: (('мільярд', 'мільярди', 'мільярдів'), + ('мільярда', 'мільярдів', 'мільярдів'), + ('мільярду', 'мільярдам', 'мільярдам'), + ('мільярд', 'мільярди', 'мільярдів'), + ('мільярдом', 'мільярдами', 'мільярдів'), + ('мільярді', 'мільярдах', 'мільярдах'),), + # 10^12 + 4: (('трильйон', 'трильйони', 'трильйонів'), + ('трильйона', 'трильйонів', 'трильйонів'), + ('трильйону', 'трильйонам', 'трильйонам'), + ('трильйон', 'трильйони', 'трильйонів'), + ('трильйоном', 'трильйонами', 'трильйонів'), + ('трильйоні', 'трильйонах', 'трильйонах'),), + # 10^15 + 5: (('квадрильйон', 'квадрильйони', 'квадрильйонів'), + ('квадрильйона', 'квадрильйонів', 'квадрильйонів'), + ('квадрильйону', 'квадрильйонам', 'квадрильйонам'), + ('квадрильйон', 'квадрильйони', 'квадрильйонів'), + ('квадрильйоном', 'квадрильйонами', 'квадрильйонів'), + ('квадрильйоні', 'квадрильйонах', 'квадрильйонах'),), + # 10^18 + 6: (('квінтильйон', 'квінтильйони', 'квінтильйонів'), + ('квінтильйона', 'квінтильйонів', 'квінтильйонів'), + ('квінтильйону', 'квінтильйонам', 'квінтильйонам'), + ('квінтильйон', 'квінтильйони', 'квінтильйонів'), + ('квінтильйоном', 'квінтильйонами', 'квінтильйонів'), + ('квінтильйоні', 'квінтильйонах', 'квінтильйонах'),), + # 10^21 + 7: (('секстильйон', 'секстильйони', 'секстильйонів'), + ('секстильйона', 'секстильйонів', 'секстильйонів'), + ('секстильйону', 'секстильйонам', 'секстильйонам'), + ('секстильйон', 'секстильйони', 'секстильйонів'), + ('секстильйоном', 'секстильйонами', 'секстильйонів'), + ('секстильйоні', 'секстильйонах', 'секстильйонах'),), + # 10^24 + 8: (('септильйон', 'септильйони', 'септильйонів'), + ('септильйона', 'септильйонів', 'септильйонів'), + ('септильйону', 'септильйонам', 'септильйонам'), + ('септильйон', 'септильйони', 'септильйонів'), + ('септильйоном', 'септильйонами', 'септильйонів'), + ('септильйоні', 'септильйонах', 'септильйонах'),), + # 10^27 + 9: (('октильйон', 'октильйони', 'октильйонів'), + ('октильйона', 'октильйонів', 'октильйонів'), + ('октильйону', 'октильйонам', 'октильйонам'), + ('октильйон', 'октильйони', 'октильйонів'), + ('октильйоном', 'октильйонами', 'октильйонів'), + ('октильйоні', 'октильйонах', 'октильйонах'),), + # 10^30 + 10: (('нонільйон', 'нонільйони', 'нонільйонів'), + ('нонільйона', 'нонільйонів', 'нонільйонів'), + ('нонільйону', 'нонільйонам', 'нонільйонам'), + ('нонільйон', 'нонільйони', 'нонільйонів'), + ('нонільйоном', 'нонільйонами', 'нонільйонів'), + ('нонільйоні', 'нонільйонах', 'нонільйонах'),), } +prefixes_ordinal = { + 1: "тисячний", + 2: "мільйонний", + 3: "мільярдний", + 4: "трильйонний", + 5: "квадрильйонний", + 6: "квінтильйонний", + 7: "секстильйонний", + 8: "септильйонний", + 9: "октильйонний", + 10: "нонільйонний", +} + +FEMININE_MONEY = ('AOA', 'BAM', 'BDT', 'BWP', 'CZK', 'DKK', + 'ERN', 'HNL', 'HRK', 'IDR', 'INR', 'ISK', + 'JPY', 'KPW', 'KRW', 'LKR', 'MOP', 'MRU', + 'MUR', 'MVR', 'MWK', 'NGN', 'NIO', 'NOK', + 'NPR', 'PKR', 'SCR', 'SEK', 'STN', 'TRY', + 'WST', 'UAH', 'ZMW') +FEMININE_CENTS = ('ALL', 'BDT', 'BGN', 'BYN', 'GHS', 'HRK', + 'ILS', 'INR', 'NPR', 'OMR', 'OMR', 'PKR', + 'RSD', 'RUB', 'UAH') + +GENERIC_DOLLARS = ('долар', 'долари', 'доларів') +GENERIC_CENTS = ('цент', 'центи', 'центів') + class Num2Word_UK(Num2Word_Base): CURRENCY_FORMS = { - 'UAH': ( - ('гривня', 'гривнi', 'гривень'), - ('копiйка', 'копiйки', 'копiйок') + 'AED': ( + ('дирхам', 'дирхами', 'дирхамів'), + ('філс', 'філси', 'філсів') + ), + 'AFN': ( + ('афгані', 'афгані', 'афгані'), + ('пул', 'пули', 'пулів') + ), + 'ALL': ( + ('лек', 'леки', 'леків'), + ('кіндарка', 'кіндарки', 'кіндарок') + ), + 'AMD': ( + ('драм', 'драми', 'драмів'), + ('лум', 'лум', 'лум') + ), + 'ANG': ( + ('гульден', 'гульдени', 'гульденів'), + GENERIC_CENTS + ), + 'AOA': ( + ('кванза', 'кванзи', 'кванз'), + ('сентимо', 'сентимо', 'сентимо') + ), + 'ARS': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'AUD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'AWG': ( + ('флорин', 'флорини', 'флоринів'), + GENERIC_CENTS + ), + 'AZN': ( + ('манат', 'манати', 'манатів'), + ('гяпік', 'гяпіки', 'гяпіків') + ), + 'BAM': ( + ('марка', 'марки', 'марок'), + ('фенінг', 'фенінги', 'фенінгів') + ), + 'BBD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BDT': ( + ('така', 'таки', 'так'), + ('пойша', 'пойші', 'пойш') + ), + 'BGN': ( + ('лев', 'леви', 'левів'), + ('стотинка', 'стотинки', 'стотинок') + ), + 'BHD': ( + ('динар', 'динари', 'динарів'), + ('філс', 'філси', 'філсів') + ), + 'BIF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'BMD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BND': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BOB': ( + ('болівіано', 'болівіано', 'болівіано'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'BRL': ( + ('реал', 'реали', 'реалів'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'BSD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'BTN': ( + ('нгултрум', 'нгултруми', 'нгултрумів'), + ('четрум', 'четруми', 'четрумів') + ), + 'BWP': ( + ('пула', 'пули', 'пул'), + ('тхебе', 'тхебе', 'тхебе') + ), + 'BYN': ( + ('рубель', 'рублі', 'рублів'), + ('копійка', 'копійки', 'копійок') + ), + 'BZD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'CAD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'CDF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'CHF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'CLP': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'CNY': ( + ('юань', 'юані', 'юанів'), + ('финь', 'фині', 'финів') + ), + 'COP': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'CRC': ( + ('колон', 'колони', 'колонів'), + ('сентімо', 'сентімо', 'сентімо') + ), + 'CUC': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'CUP': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'CVE': ( + ('ескудо', 'ескудо', 'ескудо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'CZK': ( + ('крона', 'крони', 'крон'), + ('гелер', 'гелери', 'гелерів') + ), + 'DJF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'DKK': ( + ('крона', 'крони', 'крон'), + ('ере', 'ере', 'ере') + ), + 'DOP': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'DZD': ( + ('динар', 'динари', 'динарів'), + ('сантим', 'сантими', 'сантимів') + ), + 'EGP': ( + ('фунт', 'фунти', 'фунтів'), + ('піастр', 'піастри', 'піастрів') + ), + 'ERN': ( + ('накфа', 'накфи', 'накф'), + GENERIC_CENTS + ), + 'ETB': ( + ('бир', 'бири', 'бирів'), + GENERIC_CENTS ), 'EUR': ( - ('євро', 'євро', 'євро'), ('цент', 'центи', 'центiв') + ('євро', 'євро', 'євро'), + GENERIC_CENTS + ), + 'FJD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'FKP': ( + ('фунт', 'фунти', 'фунтів'), + ('пенс', 'пенси', 'пенсів') + ), + 'GBP': ( + ('фунт', 'фунти', 'фунтів'), + ('пенс', 'пенси', 'пенсів') + ), + 'GEL': ( + ('ларі', 'ларі', 'ларі'), + ('тетрі', 'тетрі', 'тетрі') + ), + 'GHS': ( + ('седі', 'седі', 'седі'), + ('песева', 'песеви', 'песев') + ), + 'GIP': ( + ('фунт', 'фунти', 'фунтів'), + ('пенс', 'пенси', 'пенсів') + ), + 'GMD': ( + ('даласі', 'даласі', 'даласі'), + ('бутут', 'бутути', 'бутутів') + ), + 'GNF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'GTQ': ( + ('кетсаль', 'кетсалі', 'кетсалів'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'GYD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'HKD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'HNL': ( + ('лемпіра', 'лемпіри', 'лемпір'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'HRK': ( + ('куна', 'куни', 'кун'), + ('ліпа', 'ліпи', 'ліп') + ), + 'HTG': ( + ('гурд', 'гурди', 'гурдів'), + ('сантим', 'сантими', 'сантимів') + ), + 'HUF': ( + ('форинт', 'форинти', 'форинтів'), + ('філлер', 'філлери', 'філлерів') + ), + 'IDR': ( + ('рупія', 'рупії', 'рупій'), + GENERIC_CENTS + ), + 'ILS': ( + ('шекель', 'шекелі', 'шекелів'), + ('агора', 'агори', 'агор') + ), + 'INR': ( + ('рупія', 'рупії', 'рупій'), + ('пайса', 'пайси', 'пайс') + ), + 'IQD': ( + ('динар', 'динари', 'динарів'), + ('філс', 'філси', 'філсів') + ), + 'IRR': ( + ('ріал', 'ріали', 'ріалів'), + ('динар', 'динари', 'динарів') + ), + 'ISK': ( + ('крона', 'крони', 'крон'), + ('ейре', 'ейре', 'ейре') + ), + 'JMD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'JOD': ( + ('динар', 'динари', 'динарів'), + ('філс', 'філси', 'філсів') + ), + 'JPY': ( + ('єна', 'єни', 'єн'), + ('сен', 'сен', 'сен') + ), + 'KES': ( + ('шилінг', 'шилінги', 'шилінгів'), + GENERIC_CENTS + ), + 'KGS': ( + ('сом', 'соми', 'сомів'), + ('тиїн', 'тиїни', 'тиїнів') + ), + 'KHR': ( + ('рієль', 'рієлі', 'рієлів'), + ('су', 'су', 'су') + ), + 'KMF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'KPW': ( + ('вона', 'вони', 'вон'), + ('чон', 'чони', 'чонів') + ), + 'KRW': ( + ('вона', 'вони', 'вон'), + ('джеон', 'джеони', 'джеонів') + ), + 'KWD': ( + ('динар', 'динари', 'динарів'), + ('філс', 'філси', 'філсів') + ), + 'KYD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'KZT': ( + ('теньге', 'теньге', 'теньге'), + ('тиїн', 'тиїни', 'тиїнів')), + 'LAK': ( + ('кіп', 'кіпи', 'кіпів'), + ('ат', 'ати', 'атів') + ), + 'LBP': ( + ('фунт', 'фунти', 'фунтів'), + ('піастр', 'піастри', 'піастрів') + ), + 'LKR': ( + ('рупія', 'рупії', 'рупій'), + GENERIC_CENTS + ), + 'LRD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'LSL': ( + ('лоті', 'малоті', 'малоті'), + ('сенте', 'лісенте', 'лісенте') + ), + 'LYD': ( + ('динар', 'динари', 'динарів'), + ('дирхам', 'дирхами', 'дирхамів') + ), + 'MAD': ( + ('дирхам', 'дирхами', 'дирхамів'), + ('сантим', 'сантими', 'сантимів') + ), + 'MDL': ( + ('лей', 'леї', 'леї'), + ('бан', 'бані', 'бані') + ), + 'MGA': ( + ('аріарі', 'аріарі', 'аріарі'), + ('іраймбіланья', 'іраймбіланья', 'іраймбіланья') + ), + 'MKD': ( + ('денар', 'денари', 'денарів'), + ('дені', 'дені', 'дені') + ), + 'MMK': ( + ('к\'ят', 'к\'ят', 'к\'ят'), + ('п\'я', 'п\'я', 'п\'я') + ), + 'MNT': ( + ('тугрик', 'тугрики', 'тугриків'), + ('мунгу', 'мунгу', 'мунгу') + ), + 'MOP': ( + ('патака', 'патакі', 'патак'), + ('аво', 'аво', 'аво') + ), + 'MRU': ( + ('угія', 'угії', 'угій'), + ('хумс', 'хумс', 'хумс') + ), + 'MUR': ( + ('рупія', 'рупії', 'рупій'), + GENERIC_CENTS + ), + 'MVR': ( + ('руфія', 'руфії', 'руфій'), + ('ларі', 'ларі', 'ларі') + ), + 'MWK': ( + ('квача', 'квачі', 'квач'), + ('тамбала', 'тамбала', 'тамбала') + ), + 'MXN': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'MYR': ( + ('рингіт', 'рингіти', 'рингітів'), + GENERIC_CENTS + ), + 'MZN': ( + ('метікал', 'метікали', 'метікалів'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'NAD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'NGN': ( + ('найра', 'найри', 'найр'), + ('кобо', 'кобо', 'кобо') + ), + 'NIO': ( + ('кордоба', 'кордоби', 'кордоб'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'NOK': ( + ('крона', 'крони', 'крон'), + ('ере', 'ере', 'ере') + ), + 'NPR': ( + ('рупія', 'рупії', 'рупій'), + ('пайса', 'пайси', 'пайс') + ), + 'NZD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'OMR': ( + ('ріал', 'ріали', 'ріалів'), + ('байза', 'байзи', 'байз') + ), + 'PAB': ( + ('бальбоа', 'бальбоа', 'бальбоа'), + ('сентесімо', 'сентесімо', 'сентесімо') + ), + 'PEN': ( + ('соль', 'соль', 'соль'), + ('сентімо', 'сентімо', 'сентімо') + ), + 'PGK': ( + ('кіна', 'кіна', 'кіна'), + ('тойя', 'тойя', 'тойя') + ), + 'PHP': ( + ('песо', 'песо', 'песо'), + ('сентаво', 'сентаво', 'сентаво') + ), + 'PKR': ( + ('рупія', 'рупії', 'рупій'), + ('пайса', 'пайси', 'пайс') + ), + 'PLN': ( + ('злотий', 'злоті', 'злотих'), + ('грош', 'гроші', 'грошів') + ), + 'PYG': ( + ('гуарані', 'гуарані', 'гуарані'), + ('сентімо', 'сентімо', 'сентімо') + ), + 'QAR': ( + ('ріал', 'ріали', 'ріалів'), + ('дирхам', 'дирхами', 'дирхамів') + ), + 'RON': ( + ('лей', 'леї', 'леї'), + ('бан', 'бані', 'бані') + ), + 'RSD': ( + ('динар', 'динари', 'динарів'), + ('пара', 'пари', 'пар') + ), + 'RUB': ( + ('рубль', 'рублі', 'рублів'), + ('копійка', 'копійки', 'копійок') + ), + 'RWF': ( + ('франк', 'франки', 'франків'), + ('сантим', 'сантими', 'сантимів') + ), + 'SAR': ( + ('ріал', 'ріали', 'ріалів'), + ('халал', 'халали', 'халалів') + ), + 'SBD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'SCR': ( + ('рупія', 'рупії', 'рупій'), + GENERIC_CENTS + ), + 'SDG': ( + ('фунт', 'фунти', 'фунтів'), + ('піастр', 'піастри', 'піастрів') + ), + 'SEK': ( + ('крона', 'крони', 'крон'), + ('ере', 'ере', 'ере') + ), + 'SGD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'SHP': ( + ('фунт', 'фунти', 'фунтів'), + ('пенс', 'пенси', 'пенсів') + ), + 'SLL': ( + ('леоне', 'леоне', 'леоне'), + GENERIC_CENTS + ), + 'SOS': ( + ('шилінг', 'шилінги', 'шилінгів'), + GENERIC_CENTS + ), + 'SRD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'SSP': ( + ('фунт', 'фунти', 'фунтів'), + ('піастр', 'піастри', 'піастрів') + ), + 'STN': ( + ('добра', 'добри', 'добр'), + ('сентімо', 'сентімо', 'сентімо') + ), + 'SYP': ( + ('фунт', 'фунти', 'фунтів'), + ('піастр', 'піастри', 'піастрів') + ), + 'SZL': ( + ('ліланґені', 'ліланґені', 'ліланґені'), + GENERIC_CENTS + ), + 'THB': ( + ('бат', 'бати', 'батів'), + ('сатанг', 'сатанги', 'сатангів') + ), + 'TJS': ( + ('сомоні', 'сомоні', 'сомоні'), + ('дірам', 'дірами', 'дірамів') + ), + 'TMT': ( + ('манат', 'манати', 'манатів'), + ('тенге', 'тенге', 'тенге') + ), + 'TND': ( + ('динар', 'динари', 'динарів'), + ('міллім', 'мілліми', 'міллімів') + ), + 'TOP': ( + ('паанга', 'паанга', 'паанга'), + ('сеніті', 'сеніті', 'сеніті') + ), + 'TRY': ( + ('ліра', 'ліри', 'лір'), + ('куруш', 'куруші', 'курушів') + ), + 'TTD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'TWD': ( + ('новий долар', 'нові долари', 'нових доларів'), + GENERIC_CENTS + ), + 'TZS': ( + ('шилінг', 'шилінги', 'шилінгів'), + GENERIC_CENTS + ), + 'UAH': ( + ('гривня', 'гривні', 'гривень'), + ('копійка', 'копійки', 'копійок') + ), + 'UGX': ( + ('шилінг', 'шилінги', 'шилінгів'), + GENERIC_CENTS + ), + 'USD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'UYU': ( + ('песо', 'песо', 'песо'), + ('сентесімо', 'сентесімо', 'сентесімо') + ), + 'UZS': ( + ('сум', 'суми', 'сумів'), + ('тиїн', 'тиїни', 'тиїнів') + ), + 'VND': ( + ('донг', 'донги', 'донгів'), + ('су', 'су', 'су') + ), + 'WST': ( + ('тала', 'тали', 'тал'), + ('сене', 'сене', 'сене') + ), + 'XCD': (GENERIC_DOLLARS, GENERIC_CENTS), + 'YER': ( + ('ріал', 'ріали', 'ріалів'), + ('філс', 'філси', 'філсів') + ), + 'ZAR': ( + ('ранд', 'ранди', 'рандів'), + GENERIC_CENTS + ), + 'ZMW': ( + ('квача', 'квачі', 'квач'), + ('нгве', 'нгве', 'нгве') ), } def setup(self): - self.negword = "мiнус" + self.negword = "мінус" self.pointword = "кома" - def to_cardinal(self, number): + def to_cardinal(self, number, **kwargs): + if 'case' in kwargs: + case = kwargs['case'] + morphological_case = [ + "nominative", + "genitive", + "dative", + "accusative", + "instrumental", + "locative"].index(case) + else: + morphological_case = 0 + + if 'gender' in kwargs: + gender = kwargs['gender'] == 'feminine' + else: + gender = False + n = str(number).replace(',', '.') if '.' in n: left, right = n.split('.') - return '%s %s %s' % ( - self._int2word(int(left)), + leading_zero_count = len(right) - len(right.lstrip('0')) + right_side = self._int2word(int(right), gender, morphological_case) + decimal_part = ((ZERO[0] + ' ') * leading_zero_count + + right_side) + return u'%s %s %s' % ( + self._int2word(int(left), gender, morphological_case), self.pointword, - self._int2word(int(right)) + decimal_part ) else: - return self._int2word(int(n)) + return self._int2word(int(n), gender, morphological_case) def pluralize(self, n, forms): if n % 100 < 10 or n % 100 > 20: @@ -136,9 +951,11 @@ def pluralize(self, n, forms): return forms[form] - def _int2word(self, n, feminine=True): + def _int2word(self, n, feminine=False, morphological_case=0): if n < 0: - return ' '.join([self.negword, self._int2word(abs(n))]) + n_value = self._int2word(abs(n), feminine, morphological_case) + return ' '.join([self.negword, + n_value]) if n == 0: return ZERO[0] @@ -155,25 +972,96 @@ def _int2word(self, n, feminine=True): n1, n2, n3 = get_digits(x) if n3 > 0: - words.append(HUNDREDS[n3][0]) + words.append(HUNDREDS[n3][morphological_case]) if n2 > 1: - words.append(TWENTIES[n2][0]) + words.append(TWENTIES[n2][morphological_case]) if n2 == 1: - words.append(TENS[n1][0]) + words.append(TENS[n1][morphological_case]) # elif n1 > 0 and not (i > 0 and x == 1): elif n1 > 0: ones = ONES_FEMININE if i == 1 or feminine and i == 0 else ONES - words.append(ones[n1][0]) + words.append(ones[n1][morphological_case]) if i > 0: - words.append(self.pluralize(x, THOUSANDS[i])) + thousands_val = THOUSANDS[i][morphological_case] + words.append(self.pluralize(x, thousands_val)) return ' '.join(words) + def _money_verbose(self, number, currency): + return self._int2word(number, currency in FEMININE_MONEY) + def _cents_verbose(self, number, currency): - return self._int2word(number, currency == 'UAH') + return self._int2word(number, currency in FEMININE_CENTS) + + @staticmethod + def last_fragment_to_ordinal(last, words, level): + n1, n2, n3 = get_digits(last) + last_two = n2*10+n1 + if last_two == 0: + words.append(HUNDREDS_ORDINALS[n3][level]) + elif level == 1 and last == 1: + return + elif last_two < 20: + if level == 0: + if n3 > 0: + words.append(HUNDREDS[n3][0]) + words.append(ONES_ORDINALS[last_two][0]) + else: + last_fragment_string = '' + if n3 > 0: + last_fragment_string += HUNDREDS_ORDINALS[n3][1] + last_fragment_string += ONES_ORDINALS[last_two][1] + words.append(last_fragment_string) + elif last_two % 10 == 0: + if level == 0: + if n3 > 0: + words.append(HUNDREDS[n3][0]) + words.append(TWENTIES_ORDINALS[n2][0]) + else: + last_fragment_string = '' + if n3 > 0: + last_fragment_string += HUNDREDS_ORDINALS[n3][1] + last_fragment_string += TWENTIES_ORDINALS[n2][1] + words.append(last_fragment_string) + else: + if level == 0: + if n3 > 0: + words.append(HUNDREDS[n3][0]) + words.append(TWENTIES[n2][0]) + words.append(ONES_ORDINALS[n1][0]) + else: + last_fragment_string = '' + if n3 > 0: + last_fragment_string += HUNDREDS_ORDINALS[n3][1] + last_fragment_string += TWENTIES_ORDINALS[n2][1] + last_fragment_string += ONES_ORDINALS[n1][1] + words.append(last_fragment_string) def to_ordinal(self, number): - raise NotImplementedError() + self.verify_ordinal(number) + + words = [] + fragments = list(splitbyx(str(number), 3)) + level = 0 + last = fragments[-1] + while last == 0: + level = level + 1 + fragments.pop() + last = fragments[-1] + if len(fragments) > 1: + pre_part = self._int2word(number - (last * 1000 ** level)) + words.append(pre_part) + Num2Word_UK.last_fragment_to_ordinal( + last, + words, + 0 if level == 0 else 1 + ) + output = " ".join(words) + if last == 1 and level > 0 and output != "": + output = output + " " + if level > 0: + output = output + prefixes_ordinal[level] + return output diff --git a/requirements-test.txt b/requirements-test.txt index 7165ac7e..3d9b3a23 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,3 +1,4 @@ +tox flake8 flake8-copyright isort diff --git a/setup.py b/setup.py index fbc34f7b..4ca9fda6 100644 --- a/setup.py +++ b/setup.py @@ -27,8 +27,12 @@ 'Intended Audience :: Developers', 'License :: OSI Approved :: GNU Library or Lesser General Public License ' '(LGPL)', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', + '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', 'Topic :: Software Development :: Internationalization', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Localization', @@ -61,11 +65,12 @@ def find_version(fname): version=find_version("bin/num2words"), description='Modules to convert numbers to words. Easily extensible.', long_description=LONG_DESC, + long_description_content_type="text/markdown", license='LGPL', author='Taro Ogawa ', author_email='tos@users.sourceforge.net', maintainer='Savoir-faire Linux inc.', - maintainer_email='istvan.szalai@savoirfairelinux.com', + maintainer_email='support@savoirfairelinux.com', keywords=' number word numbers words convert conversion i18n ' 'localisation localization internationalisation ' 'internationalization', diff --git a/tests/test_am.py b/tests/test_am.py new file mode 100644 index 00000000..58709c37 --- /dev/null +++ b/tests/test_am.py @@ -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'), + 'አሥራ ስምንት መቶ ስድሳ አምስት') diff --git a/tests/test_ar.py b/tests/test_ar.py index 5e1ea410..91e648a6 100644 --- a/tests/test_ar.py +++ b/tests/test_ar.py @@ -42,13 +42,13 @@ def test_default_currency(self): self.assertEqual(num2words(20000.12, to='currency', lang='ar'), 'عشرون ألف ريال و اثنتا عشرة هللة') self.assertEqual(num2words(1000000, to='currency', lang='ar'), - 'واحد مليون ريال') - val = 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر ريالاً' + 'مليون ريال') + val = 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر ريالاً' self.assertEqual(num2words(923411, to='currency', lang='ar'), val) self.assertEqual(num2words(63411, to='currency', lang='ar'), - 'ثلاثة و ستون ألفاً و أربعمائة و أحد عشر ريالاً') + 'ثلاثة و ستون ألفاً و أربعمائة و أحد عشر ريالاً') self.assertEqual(num2words(1000000.99, to='currency', lang='ar'), - 'واحد مليون ريال و تسع و تسعون هللة') + 'مليون ريال و تسع و تسعون هللة') def test_currency_parm(self): self.assertEqual( @@ -62,12 +62,13 @@ def test_currency_parm(self): 'عشرون ألف جنيه و اثنتا عشرة قرش') self.assertEqual( num2words(923411, to='currency', lang='ar', currency="SR"), - 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر ريالاً') + 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر ريالاً') self.assertEqual( num2words(1000000.99, to='currency', lang='ar', currency="KWD"), - 'واحد مليون دينار و تسع و تسعون فلس') + 'مليون دينار و تسع و تسعون فلس') def test_ordinal(self): + self.assertEqual(num2words(1, to='ordinal', lang='ar'), 'اول') self.assertEqual(num2words(2, to='ordinal', lang='ar'), 'ثاني') self.assertEqual(num2words(3, to='ordinal', lang='ar'), 'ثالث') @@ -82,21 +83,82 @@ def test_ordinal(self): 'مائة و اثنان') self.assertEqual( num2words(923411, to='ordinal_num', lang='ar'), - 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر') + 'تسعمائة و ثلاثة و عشرون ألفاً و أربعمائة و أحد عشر') + + # See https://github.com/savoirfairelinux/num2words/issues/403 + self.assertEqual(num2words(23, lang="ar"), 'ثلاثة و عشرون') + self.assertEqual(num2words(23, to='ordinal', + lang="ar"), 'ثلاث و عشرون') + self.assertEqual(num2words(23, lang="ar"), 'ثلاثة و عشرون') def test_cardinal(self): + self.assertEqual(num2words(0, to='cardinal', lang='ar'), 'صفر') self.assertEqual(num2words(12, to='cardinal', lang='ar'), 'اثنا عشر') + self.assertEqual(num2words(12.3, to='cardinal', lang='ar'), + 'اثنا عشر , ثلاثون') + self.assertEqual(num2words(12.01, to='cardinal', lang='ar'), + 'اثنا عشر , إحدى') + self.assertEqual(num2words(12.02, to='cardinal', lang='ar'), + 'اثنا عشر , اثنتان') + self.assertEqual(num2words(12.03, to='cardinal', lang='ar'), + 'اثنا عشر , ثلاث') + self.assertEqual(num2words(12.34, to='cardinal', lang='ar'), + 'اثنا عشر , أربع و ثلاثون') + # Not implemented + self.assertEqual(num2words(12.345, to='cardinal', lang='ar'), + num2words(12.34, to='cardinal', lang='ar')) self.assertEqual(num2words(-8324, to='cardinal', lang='ar'), - 'سالب ثمانية آلاف و ثلاثمائة و أربعة و عشرون') + 'سالب ثمانية آلاف و ثلاثمائة و أربعة و عشرون') + + self.assertEqual(num2words(200, to='cardinal', lang='ar'), + 'مئتا') + self.assertEqual(num2words(700, to='cardinal', lang='ar'), + 'سبعمائة') + self.assertEqual(num2words(101010, to='cardinal', lang='ar'), + 'مائة و ألف ألف و عشرة') + self.assertEqual( num2words(3431.12, to='cardinal', lang='ar'), - 'ثلاثة آلاف و أربعمائة و واحد و ثلاثون , اثنتا عشرة') + 'ثلاثة آلاف و أربعمائة و واحد و ثلاثون , اثنتا عشرة') self.assertEqual(num2words(431, to='cardinal', lang='ar'), 'أربعمائة و واحد و ثلاثون') self.assertEqual(num2words(94231, to='cardinal', lang='ar'), - 'أربعة و تسعون ألفاً و مئتان و واحد و ثلاثون') + 'أربعة و تسعون ألفاً و مئتان و واحد و ثلاثون') self.assertEqual(num2words(1431, to='cardinal', lang='ar'), - 'واحد ألف و أربعمائة و واحد و ثلاثون') + 'ألف و أربعمائة و واحد و ثلاثون') + self.assertEqual(num2words(740, to='cardinal', lang='ar'), + 'سبعمائة و أربعون') + self.assertEqual(num2words(741, to='cardinal', lang='ar'), + # 'سبعة مائة و واحد و أربعون' + 'سبعمائة و واحد و أربعون' + ) + self.assertEqual(num2words(262, to='cardinal', lang='ar'), + 'مئتان و اثنان و ستون' + ) + self.assertEqual(num2words(798, to='cardinal', lang='ar'), + 'سبعمائة و ثمانية و تسعون' + ) + self.assertEqual(num2words(710, to='cardinal', lang='ar'), + 'سبعمائة و عشرة') + self.assertEqual(num2words(711, to='cardinal', lang='ar'), + # 'سبعة مائة و إحدى عشر' + 'سبعمائة و أحد عشر' + ) + self.assertEqual(num2words(700, to='cardinal', lang='ar'), + 'سبعمائة') + self.assertEqual(num2words(701, to='cardinal', lang='ar'), + 'سبعمائة و واحد') + + self.assertEqual( + num2words(1258888, to='cardinal', lang='ar'), + 'مليون و مئتان و ثمانية و خمسون ألفاً و ثمانمائة و ثمانية و ثمانون' + ) + + self.assertEqual(num2words(1100, to='cardinal', lang='ar'), + 'ألف و مائة') + + self.assertEqual(num2words(1000000521, to='cardinal', lang='ar'), + 'مليار و خمسمائة و واحد و عشرون') def test_prefix_and_suffix(self): self.assertEqual(num2words(645, to='currency', @@ -107,7 +169,38 @@ def test_year(self): self.assertEqual(num2words(2000, to='year', lang='ar'), 'ألفا') def test_max_numbers(self): - with self.assertRaises(Exception) as context: - num2words(10 ** 36, to='year', lang='ar') - self.assertTrue('Too large' in str(context.exception)) + for number in 10**51, 10**51 + 2: + + with self.assertRaises(OverflowError) as context: + num2words(number, lang='ar') + + self.assertTrue('must be less' in str(context.exception)) + + def test_big_numbers(self): + self.assertEqual( + num2words(1000000045000000000000003000000002000000300, + to='cardinal', lang='ar'), + 'تريديسيليون و خمسة و أربعون ديسيليوناً\ + و ثلاثة كوينتليونات و ملياران و ثلاثمائة' + ) + self.assertEqual( + num2words(-1000000000000000000000003000000002000000302, + to='cardinal', lang='ar'), + 'سالب تريديسيليون و ثلاثة كوينتليونات \ +و ملياران و ثلاثمائة و اثنان' + ) + self.assertEqual( + num2words(9999999999999999999999999999999999999999999999992, + to='cardinal', lang='ar'), + 'تسعة كوينتينيليونات و تسعمائة و\ + تسعة و تسعون كوادريسيليوناً و تسعمائة و تسعة\ + و تسعون تريديسيليوناً و تسعمائة و تسعة و تسعون دوديسيليوناً و تسعمائة\ + و تسعة و تسعون أندسيليوناً و تسعمائة و تسعة و تسعون ديسيليوناً\ + و تسعمائة و تسعة و تسعون نونيليوناً و تسعمائة و تسعة و تسعون\ + أوكتيليوناً و تسعمائة و تسعة و تسعون سبتيليوناً و تسعمائة و تسعة\ + و تسعون سكستيليوناً و تسعمائة و تسعة و تسعون كوينتليوناً و تسعمائة و\ + تسعة و تسعون كوادريليوناً و تسعمائة و تسعة و تسعون تريليوناً\ + و تسعمائة و تسعة و تسعون ملياراً و تسعمائة و تسعة و تسعون مليوناً\ + و تسعمائة و تسعة و تسعون ألفاً و تسعمائة و اثنان و تسعون' + ) diff --git a/tests/test_az.py b/tests/test_az.py new file mode 100644 index 00000000..af52cb27 --- /dev/null +++ b/tests/test_az.py @@ -0,0 +1,289 @@ +# -*- 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 Num2WordAZTest(TestCase): + lang = 'az' + + CARDINAL_TEST_CASES = ( + (0, 'sıfır',), + (1, 'bir',), + (2, 'iki',), + (3, 'üç',), + (4, 'dörd',), + (5, 'beş',), + (6, 'altı',), + (7, 'yeddi',), + (8, 'səkkiz',), + (9, 'doqquz',), + (10, 'on',), + (11, 'on bir',), + (20, 'iyirmi',), + (22, 'iyirmi iki',), + (30, 'otuz',), + (33, 'otuz üç',), + (40, 'qırx',), + (44, 'qırx dörd',), + (50, 'əlli',), + (55, 'əlli beş',), + (60, 'altmış',), + (66, 'altmış altı',), + (70, 'yetmiş',), + (77, 'yetmiş yeddi',), + (80, 'səksən',), + (88, 'səksən səkkiz',), + (90, 'doxsan',), + (99, 'doxsan doqquz',), + (100, 'yüz',), + (200, 'iki yüz',), + (678, 'altı yüz yetmiş səkkiz',), + (999, 'doqquz yüz doxsan doqquz',), + (1000, 'min',), + (100_000, 'yüz min',), + (328_914, 'üç yüz iyirmi səkkiz min doqquz yüz on dörd',), + (1_000_000, 'bir milyon',), + (1_000_000_000, 'bir milyard',), + (10**12, 'bir trilyon',), + (10**15, 'bir katrilyon',), + (10**18, 'bir kentilyon',), + (10**21, 'bir sekstilyon',), + (10**24, 'bir septilyon',), + (10**27, 'bir oktilyon',), + (10**30, 'bir nonilyon',), + (10**33, 'bir desilyon',), + (10**36, 'bir undesilyon',), + (10**39, 'bir dodesilyon',), + (10**42, 'bir tredesilyon',), + (10**45, 'bir katordesilyon',), + (10**48, 'bir kendesilyon',), + (10**51, 'bir seksdesilyon',), + (10**54, 'bir septendesilyon',), + (10**57, 'bir oktodesilyon',), + (10**60, 'bir novemdesilyon',), + (10**63, 'bir vigintilyon',), + (-0, 'sıfır',), + (-1, 'mənfi bir',), + (-2, 'mənfi iki',), + (-3, 'mənfi üç',), + (-4, 'mənfi dörd',), + (-5, 'mənfi beş',), + (-6, 'mənfi altı',), + (-7, 'mənfi yeddi',), + (-8, 'mənfi səkkiz',), + (-9, 'mənfi doqquz',), + (-10, 'mənfi on',), + (-11, 'mənfi on bir',), + (-20, 'mənfi iyirmi',), + (-22, 'mənfi iyirmi iki',), + (-30, 'mənfi otuz',), + (-33, 'mənfi otuz üç',), + (-40, 'mənfi qırx',), + (-44, 'mənfi qırx dörd',), + (-50, 'mənfi əlli',), + (-55, 'mənfi əlli beş',), + (-60, 'mənfi altmış',), + (-66, 'mənfi altmış altı',), + (-70, 'mənfi yetmiş',), + (-77, 'mənfi yetmiş yeddi',), + (-80, 'mənfi səksən',), + (-88, 'mənfi səksən səkkiz',), + (-90, 'mənfi doxsan',), + (-99, 'mənfi doxsan doqquz',), + (-100, 'mənfi yüz',), + (-200, 'mənfi iki yüz',), + (-678, 'mənfi altı yüz yetmiş səkkiz',), + (-999, 'mənfi doqquz yüz doxsan doqquz',), + (-1000, 'mənfi min',), + (-100_000, 'mənfi yüz min',), + (-328_914, 'mənfi üç yüz iyirmi səkkiz min doqquz yüz on dörd',), + (-1_000_000, 'mənfi bir milyon',), + (-1_000_000_000, 'mənfi bir milyard',), + (-10**12, 'mənfi bir trilyon',), + (-10**15, 'mənfi bir katrilyon',), + (-10**18, 'mənfi bir kentilyon',), + (-10**21, 'mənfi bir sekstilyon',), + (-10**24, 'mənfi bir septilyon',), + (-10**27, 'mənfi bir oktilyon',), + (-10**30, 'mənfi bir nonilyon',), + (-10**33, 'mənfi bir desilyon',), + (-10**36, 'mənfi bir undesilyon',), + (-10**39, 'mənfi bir dodesilyon',), + (-10**42, 'mənfi bir tredesilyon',), + (-10**45, 'mənfi bir katordesilyon',), + (-10**48, 'mənfi bir kendesilyon',), + (-10**51, 'mənfi bir seksdesilyon',), + (-10**54, 'mənfi bir septendesilyon',), + (-10**57, 'mənfi bir oktodesilyon',), + (-10**60, 'mənfi bir novemdesilyon',), + (-10**63, 'mənfi bir vigintilyon'), + ) + + CARDINAL_FRACTION_TEST_CASES = ( + (0.2, 'sıfır nöqtə iki',), + (0.02, 'sıfır nöqtə sıfır iki',), + (0.23, 'sıfır nöqtə iyirmi üç',), + (0.0023, 'sıfır nöqtə sıfır sıfır iyirmi üç',), + (1.43, 'bir nöqtə qırx üç',), + (-0.2, 'mənfi sıfır nöqtə iki',), + (-0.02, 'mənfi sıfır nöqtə sıfır iki',), + (-0.23, 'mənfi sıfır nöqtə iyirmi üç',), + (-0.0023, 'mənfi sıfır nöqtə sıfır sıfır iyirmi üç',), + (-1.43, 'mənfi bir nöqtə qırx üç',), + ) + + ORDINAL_TEST_CASES = ( + (0, 'sıfırıncı',), + (1, 'birinci',), + (2, 'ikinci',), + (3, 'üçüncü',), + (4, 'dördüncü',), + (5, 'beşinci',), + (6, 'altıncı',), + (7, 'yeddinci',), + (8, 'səkkizinci',), + (9, 'doqquzuncu',), + (10, 'onuncu',), + (11, 'on birinci',), + (20, 'iyirminci',), + (22, 'iyirmi ikinci',), + (30, 'otuzuncu',), + (33, 'otuz üçüncü',), + (40, 'qırxıncı',), + (44, 'qırx dördüncü',), + (50, 'əllinci',), + (55, 'əlli beşinci',), + (60, 'altmışıncı',), + (66, 'altmış altıncı',), + (70, 'yetmişinci',), + (77, 'yetmiş yeddinci',), + (80, 'səksəninci',), + (88, 'səksən səkkizinci',), + (90, 'doxsanıncı',), + (99, 'doxsan doqquzuncu',), + (100, 'yüzüncü',), + (1000, 'mininci',), + (328_914, 'üç yüz iyirmi səkkiz min doqquz yüz on dördüncü',), + (1_000_000, 'bir milyonuncu'), + ) + + ORDINAL_NUM_TEST_CASES = ( + (0, '0-cı',), + (1, '1-ci',), + (2, '2-ci',), + (3, '3-cü',), + (4, '4-cü',), + (5, '5-ci',), + (6, '6-cı',), + (7, '7-ci',), + (8, '8-ci',), + (9, '9-cu',), + (10, '10-cu',), + (11, '11-ci',), + (20, '20-ci',), + (22, '22-ci',), + (30, '30-cu',), + (33, '33-cü',), + (40, '40-cı',), + (44, '44-cü',), + (50, '50-ci',), + (55, '55-ci',), + (60, '60-cı',), + (66, '66-cı',), + (70, '70-ci',), + (77, '77-ci',), + (80, '80-ci',), + (88, '88-ci',), + (90, '90-cı',), + (99, '99-cu',), + (100, '100-cü',), + (1000, '1000-ci',), + (328_914, '328914-cü',), + (1_000_000, '1000000-cu'), + ) + + YEAR_TEST_CASES = ( + (167, 'yüz altmış yeddi'), + (1552, 'min beş yüz əlli iki'), + (1881, 'min səkkiz yüz səksən bir'), + (2022, 'iki min iyirmi iki'), + (-1, 'e.ə. bir'), + (-500, 'e.ə. beş yüz'), + (-5000, 'e.ə. beş min'), + ) + + CURRENCY_TEST_CASES = ( + (0.0, 'sıfır manat, sıfır qəpik'), + (0.01, 'sıfır manat, bir qəpik'), + (0.1, 'sıfır manat, on qəpik'), + (1.5, 'bir manat, əlli qəpik'), + (1.94, 'bir manat, doxsan dörd qəpik'), + (17.82, 'on yeddi manat, səksən iki qəpik'), + ) + + def test_cardinal(self): + """Test cardinal conversion for integer numbers.""" + + for number, expected in self.CARDINAL_TEST_CASES: + actual = num2words(number, lang=self.lang, to='cardinal') + + self.assertEqual(actual, expected) + + def test_cardinal_fracion(self): + """Test cardinal conversion for numbers with fraction.""" + + for number, expected in self.CARDINAL_FRACTION_TEST_CASES: + actual = num2words(number, lang=self.lang, to='cardinal') + + self.assertEqual(actual, expected) + + def test_ordinal(self): + """Test ordinal conversion.""" + + for number, expected in self.ORDINAL_TEST_CASES: + actual = num2words(number, lang=self.lang, to='ordinal') + + self.assertEqual(actual, expected) + + def test_ordinal_num(self): + """Test 'ordinal_num' conversion.""" + + for number, expected in self.ORDINAL_NUM_TEST_CASES: + actual = num2words(number, lang=self.lang, to='ordinal_num') + + self.assertEqual(actual, expected) + + def test_year(self): + """Test year conversion.""" + + for number, expected in self.YEAR_TEST_CASES: + actual = num2words(number, lang=self.lang, to='year') + + self.assertEqual(actual, expected) + + def test_currency(self): + """Test currency conversion.""" + + for number, expected in self.CURRENCY_TEST_CASES: + actual = num2words( + number, lang=self.lang, currency='AZN', to='currency') + + self.assertEqual(actual, expected) diff --git a/tests/test_base.py b/tests/test_base.py index ea7701c8..efa1bc81 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -32,3 +32,33 @@ def setUpClass(cls): def test_to_currency_not_implemented(self): with self.assertRaises(NotImplementedError): self.base.to_currency(Decimal('1.00'), currency='EUR') + + def test_error_to_cardinal_float(self): + from num2words.base import Num2Word_Base + self.base = Num2Word_Base() + with self.assertRaises(TypeError): + self.base.to_cardinal_float("a") + + def test_error_merge(self): + from num2words.base import Num2Word_Base + self.base = Num2Word_Base() + with self.assertRaises(NotImplementedError): + self.base.merge(2, 3) + + def test_is_title(self): + from num2words.base import Num2Word_Base + self.base = Num2Word_Base() + self.assertEqual( + self.base.title("one"), + "one" + ) + self.base.is_title = True + self.assertEqual( + self.base.title("one"), + "One" + ) + self.base.exclude_title.append('one') + self.assertEqual( + self.base.title("one"), + "one" + ) diff --git a/tests/test_be.py b/tests/test_be.py new file mode 100644 index 00000000..c674e98b --- /dev/null +++ b/tests/test_be.py @@ -0,0 +1,401 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2023, Sergei Ruzki/Ivan Shakh 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 + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsBYTest(TestCase): + def test_cardinal(self): + self.assertEqual(num2words(100, lang="be"), "сто") + self.assertEqual(num2words(101, lang="be"), "сто адзін") + self.assertEqual(num2words(110, lang="be"), "сто дзесяць") + self.assertEqual(num2words(115, lang="be"), "сто пятнаццаць") + self.assertEqual(num2words(123, lang="be"), "сто дваццаць тры") + self.assertEqual(num2words(1000, lang="be"), "адна тысяча") + self.assertEqual(num2words(1001, lang="be"), "адна тысяча адзін") + self.assertEqual(num2words(2012, lang="be"), "дзве тысячы дванаццаць") + self.assertEqual( + num2words(12519.85, lang="be"), + "дванаццаць тысяч пяцьсот дзевятнаццаць коска восемдзесят пяць", + ) + self.assertEqual( + num2words(1234567890, lang="be"), + "адзін мільярд дзвесце трыццаць чатыры мільёны пяцьсот " + "шэсцьдзясят сем тысяч восемсот дзевяноста", + ) + self.assertEqual( + num2words(461407892039002157189883901676, lang="be"), + "чатырыста шэсцьдзясят адзін " + "актыльён чатырыста сем сэптыльёнаў восемсот дзевяноста " + "два секстыльёны трыццаць дзевяць квінтыльёнаў два квадрыльёны " + "сто пяцьдзясят сем трыльёнаў сто восемдзесят дзевяць мільярдаў " + "восемсот восемдзесят тры мільёны дзевяцьсот адна тысяча " + "шэсцьсот семдзесят шэсць", + ) + self.assertEqual( + num2words(94234693663034822824384220291, lang="be"), + "дзевяноста чатыры актыльёны " + "дзвесце трыццаць чатыры сэптыльёны шэсцьсот дзевяноста тры " + "секстыльёны шэсцьсот шэсцьдзясят тры квінтыльёны трыццаць " + "чатыры квадрыльёны восемсот дваццаць два трыльёны восемсот " + "дваццаць чатыры мільярды трыста восемдзесят чатыры мільёны " + "дзвесце дваццаць тысяч дзвесце дзевяноста адзін", + ) + self.assertEqual(num2words(5, lang="be"), "пяць") + self.assertEqual(num2words(15, lang="be"), "пятнаццаць") + self.assertEqual(num2words(154, lang="be"), "сто пяцьдзясят чатыры") + self.assertEqual( + num2words(1135, lang="be"), "адна тысяча сто трыццаць пяць" + ) + self.assertEqual( + num2words(418531, lang="be"), + "чатырыста васямнаццаць тысяч пяцьсот трыццаць адзін", + ) + self.assertEqual( + num2words(1000139, lang="be"), "адзін мільён сто трыццаць дзевяць" + ) + self.assertEqual(num2words(-1, lang="be"), "мінус адзін") + self.assertEqual(num2words(-15, lang="be"), "мінус пятнаццаць") + self.assertEqual(num2words(-100, lang="be"), "мінус сто") + + def test_floating_point(self): + self.assertEqual(num2words(5.2, lang="be"), "пяць коска два") + self.assertEqual(num2words(10.02, lang="be"), "дзесяць коска нуль два") + self.assertEqual( + num2words(15.007, lang="be"), "пятнаццаць коска нуль нуль сем" + ) + self.assertEqual( + num2words(561.42, lang="be"), + "пяцьсот шэсцьдзясят адзін коска сорак два", + ) + + self.assertEqual( + num2words(561.0, lang="be"), "пяцьсот шэсцьдзясят адзін коска нуль" + ) + + def test_to_ordinal(self): + self.assertEqual(num2words(1, lang="be", to="ordinal"), "першы") + self.assertEqual(num2words(5, lang="be", to="ordinal"), "пяты") + self.assertEqual(num2words(6, lang="be", to="ordinal"), "шосты") + self.assertEqual(num2words(10, lang="be", to="ordinal"), "дзясяты") + + self.assertEqual(num2words(13, lang="be", to="ordinal"), "трынаццаты") + self.assertEqual(num2words(20, lang="be", to="ordinal"), "дваццаты") + self.assertEqual( + num2words(23, lang="be", to="ordinal"), "дваццаць трэці" + ) + self.assertEqual( + num2words(23, lang="be", to="ordinal", gender="f"), + "дваццаць трэцяя", + ) + self.assertEqual( + num2words(23, lang="be", to="ordinal", gender=True), + "дваццаць трэцяя", + ) + self.assertEqual( + num2words(23, lang="be", to="ordinal", gender="n"), + "дваццаць трэцяе", + ) + self.assertEqual( + num2words(46, lang="be", to="ordinal", gender="m"), + "сорак шосты", + ) + self.assertEqual(num2words(40, lang="be", to="ordinal"), "саракавы") + self.assertEqual( + num2words(61, lang="be", to="ordinal"), "шэсцьдзясят першы" + ) + self.assertEqual(num2words(70, lang="be", to="ordinal"), "сямідзясяты") + self.assertEqual(num2words(100, lang="be", to="ordinal"), "соты") + self.assertEqual( + num2words(136, lang="be", to="ordinal"), "сто трыццаць шосты" + ) + self.assertEqual(num2words(500, lang="be", to="ordinal"), "пяцісоты") + + self.assertEqual( + num2words(500, lang="be", to="ordinal", gender="f"), "пяцісотая" + ) + + self.assertEqual( + num2words(500, lang="be", to="ordinal", gender="n"), "пяцісотае" + ) + + self.assertEqual(num2words(1000, lang="be", to="ordinal"), "тысячны") + + self.assertEqual( + num2words(1000, lang="be", to="ordinal", gender="f"), "тысячная" + ) + + self.assertEqual( + num2words(1000, lang="be", to="ordinal", gender="n"), "тысячнае" + ) + + self.assertEqual( + num2words(1001, lang="be", to="ordinal"), "тысяча першы" + ) + self.assertEqual( + num2words(3000, lang="be", to="ordinal"), "трохтысячны" + ) + self.assertEqual( + num2words(10000, lang="be", to="ordinal"), "дзесяцітысячны" + ) + self.assertEqual( + num2words(30000, lang="be", to="ordinal"), "трыццацітысячны" + ) + self.assertEqual( + num2words(42000, lang="be", to="ordinal"), "саракадвухтысячны" + ) + + self.assertEqual( + num2words(75000, lang="be", to="ordinal"), "сямідзесяціпяцітысячны" + ) + + self.assertEqual( + num2words(1000000, lang="be", to="ordinal"), "мільённы" + ) + self.assertEqual( + num2words(30000000, lang="be", to="ordinal"), "трыццацімільённы" + ) + self.assertEqual( + num2words(1000000000, lang="be", to="ordinal"), "мільярдны" + ) + self.assertEqual( + num2words(3000000000, lang="be", to="ordinal"), "трохмільярдны" + ) + self.assertEqual( + num2words(43000000000, lang="be", to="ordinal"), + "саракатрохмільярдны", + ) + self.assertEqual( + num2words(333000000000, lang="be", to="ordinal"), + "трыстатрыццацітрохмільярдны", + ) + + def test_to_currency(self): + self.assertEqual( + num2words(1.0, lang="be", to="currency", currency="EUR"), + "адзін еўра, нуль цэнтаў", + ) + self.assertEqual( + num2words(1.0, lang="be", to="currency", currency="RUB"), + "адзін расійскі рубель, нуль капеек", + ) + self.assertEqual( + num2words(1.0, lang="be", to="currency", currency="BYN"), + "адзін беларускі рубель, нуль капеек", + ) + self.assertEqual( + num2words(1.0, lang="be", to="currency", currency="UAH"), + "адна грыўна, нуль капеек", + ) + self.assertEqual( + num2words(1234.56, lang="be", to="currency", currency="EUR"), + "адна тысяча дзвесце трыццаць чатыры еўра, " + "пяцьдзясят шэсць цэнтаў", + ) + self.assertEqual( + num2words(1234.56, lang="be", to="currency", currency="RUB"), + "адна тысяча дзвесце трыццаць чатыры расійскія рублі, " + "пяцьдзясят шэсць капеек", + ) + self.assertEqual( + num2words(1234.56, lang="be", to="currency", currency="BYN"), + "адна тысяча дзвесце трыццаць чатыры беларускія рублі, " + "пяцьдзясят шэсць капеек", + ) + self.assertEqual( + num2words(1234.56, lang="be", to="currency", currency="UAH"), + "адна тысяча дзвесце трыццаць чатыры грыўны, " + "пяцьдзясят шэсць капеек", + ) + self.assertEqual( + num2words( + 10111, lang="be", to="currency", currency="EUR", separator=" і" + ), + "сто адзін еўра і адзінаццаць цэнтаў", + ) + self.assertEqual( + num2words( + 10111, lang="be", to="currency", currency="RUB", separator=" і" + ), + "сто адзін расійскі рубель і адзінаццаць капеек", + ) + self.assertEqual( + num2words( + 10111, lang="be", to="currency", currency="BYN", separator=" і" + ), + "сто адзін беларускі рубель і адзінаццаць капеек", + ) + self.assertEqual( + num2words( + 10111, lang="be", to="currency", currency="UAH", separator=" і" + ), + "сто адна грыўна і адзінаццаць капеек", + ) + self.assertEqual( + num2words( + 10121, lang="be", to="currency", currency="EUR", separator=" і" + ), + "сто адзін еўра і дваццаць адзін цэнт", + ) + self.assertEqual( + num2words( + 10121, lang="be", to="currency", currency="RUB", separator=" і" + ), + "сто адзін расійскі рубель і дваццаць адна капейка", + ) + self.assertEqual( + num2words( + 10121, lang="be", to="currency", currency="BYN", separator=" і" + ), + "сто адзін беларускі рубель і дваццаць адна капейка", + ) + self.assertEqual( + num2words( + 10121, lang="be", to="currency", currency="UAH", separator=" і" + ), + "сто адна грыўна і дваццаць адна капейка", + ) + self.assertEqual( + num2words( + 10122, lang="be", to="currency", currency="EUR", separator=" і" + ), + "сто адзін еўра і дваццаць два цэнты", + ) + self.assertEqual( + num2words( + 10122, lang="be", to="currency", currency="RUB", separator=" і" + ), + "сто адзін расійскі рубель і дваццаць дзве капейкі", + ) + self.assertEqual( + num2words( + 10122, lang="be", to="currency", currency="BYN", separator=" і" + ), + "сто адзін беларускі рубель і дваццаць дзве капейкі", + ) + self.assertEqual( + num2words( + 10122, lang="be", to="currency", currency="UAH", separator=" і" + ), + "сто адна грыўна і дваццаць дзве капейкі", + ) + self.assertEqual( + num2words( + 10122, lang="be", to="currency", currency="KZT", separator=" і" + ), + "сто адзін тэнге і дваццаць два тыйіны", + ) + self.assertEqual( + num2words( + -1251985, lang="be", to="currency", currency="EUR", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць еўра, 85 цэнтаў", + ) + self.assertEqual( + num2words( + -1251985, lang="be", to="currency", currency="RUB", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць " + "расійскіх рублёў, 85 капеек", + ) + self.assertEqual( + num2words( + -1251985, lang="be", to="currency", currency="BYN", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць " + "беларускіх рублёў, 85 капеек", + ) + self.assertEqual( + num2words( + -1251985, lang="be", to="currency", currency="UAH", cents=False + ), + "мінус дванаццаць тысяч пяцьсот дзевятнаццаць грыўнаў, 85 капеек", + ) + self.assertEqual( + num2words( + "38.4", + lang="be", + to="currency", + separator=" і", + cents=False, + currency="EUR", + ), + "трыццаць восем еўра і 40 цэнтаў", + ) + self.assertEqual( + num2words( + "38.4", + lang="be", + to="currency", + separator=" і", + cents=False, + currency="RUB", + ), + "трыццаць восем расійскіх рублёў і 40 капеек", + ) + self.assertEqual( + num2words( + "38.4", + lang="be", + to="currency", + separator=" і", + cents=False, + currency="UAH", + ), + "трыццаць восем грыўнаў і 40 капеек", + ) + self.assertEqual( + num2words("1230.56", lang="be", to="currency", currency="USD"), + "адна тысяча дзвесце трыццаць долараў, пяцьдзясят шэсць цэнтаў", + ) + self.assertEqual( + num2words("1231.56", lang="be", to="currency", currency="USD"), + "адна тысяча дзвесце трыццаць адзін долар, " + "пяцьдзясят шэсць цэнтаў", + ) + self.assertEqual( + num2words("1234.56", lang="be", to="currency", currency="USD"), + "адна тысяча дзвесце трыццаць чатыры долары, пяцьдзясят шэсць " + "цэнтаў", + ) + self.assertEqual( + num2words( + 10122, lang="be", to="currency", currency="UZS", separator=" і" + ), + "сто адзін сум і дваццаць два тыйіны", + ) + + self.assertEqual( + num2words(1.0, lang="be", to="currency", currency="PLN"), + "адзін злоты, нуль грошаў", + ) + + self.assertEqual( + num2words(23.40, lang="be", to="currency", currency="PLN"), + "дваццаць тры злотых, сорак грошаў", + ) + + self.assertEqual( + num2words(9999.39, lang="be", to="currency", currency="PLN"), + "дзевяць тысяч дзевяцьсот дзевяноста дзевяць злотых, " + "трыццаць дзевяць грошаў", + ) diff --git a/tests/test_ca.py b/tests/test_ca.py new file mode 100644 index 00000000..ab5be158 --- /dev/null +++ b/tests/test_ca.py @@ -0,0 +1,186 @@ +from __future__ import unicode_literals + +from unittest import TestCase + +from num2words import num2words + +TEST_CASES_CARDINAL = ( + (1, "un"), + (2, "dos"), + (3, "tres"), + (5.5, "cinc punt cinc"), + (11, "onze"), + (12, "dotze"), + (16, "setze"), + (17.42, "disset punt quatre dos"), + (19, "dinou"), + (20, "vint"), + (21, "vint-i-un"), + (26, "vint-i-sis"), + (27.312, "vint-i-set punt tres un dos"), + (28, "vint-i-vuit"), + (30, "trenta"), + (31, "trenta-un"), + (40, "quaranta"), + (44, "quaranta-quatre"), + (50, "cinquanta"), + (53.486, "cinquanta-tres punt quatre vuit sis"), + (55, "cinquanta-cinc"), + (60, "seixanta"), + (67, "seixanta-set"), + (70, "setanta"), + (79, "setanta-nou"), + (89, "vuitanta-nou"), + (95, "noranta-cinc"), + (100, "cent"), + (101, "cent un"), + (199, "cent noranta-nou"), + (203, "dos-cents tres"), + (287, "dos-cents vuitanta-set"), + (300.42, "tres-cents punt quatre dos"), + (356, "tres-cents cinquanta-sis"), + (400, "quatre-cents"), + (434, "quatre-cents trenta-quatre"), + (555, "cinc-cents cinquanta-cinc"), + (578, "cinc-cents setanta-vuit"), + (666, "sis-cents seixanta-sis"), + (689, "sis-cents vuitanta-nou"), + (729, "set-cents vint-i-nou"), + (777, "set-cents setanta-set"), + (888, "vuit-cents vuitanta-vuit"), + (894, "vuit-cents noranta-quatre"), + (999, "nou-cents noranta-nou"), + (1000, "mil"), + (1001, "mil un"), + (1097, "mil noranta-set"), + (1104, "mil cent quatre"), + (1243, "mil dos-cents quaranta-tres"), + (2385, "dos mil tres-cents vuitanta-cinc"), + (3766, "tres mil set-cents seixanta-sis"), + (4196, "quatre mil cent noranta-sis"), + (4196.42, "quatre mil cent noranta-sis punt quatre dos"), + (5846, "cinc mil vuit-cents quaranta-sis"), + (6459, "sis mil quatre-cents cinquanta-nou"), + (7232, "set mil dos-cents trenta-dos"), + (8569, "vuit mil cinc-cents seixanta-nou"), + (9539, "nou mil cinc-cents trenta-nou"), + (1000000, "un milió"), + (1000001, "un milió un"), + (4000000, "quatre milions"), + (10000000000000, "deu bilions"), + (100000000000000, "cent bilions"), + (1000000000000000000, "un trilió"), + (1000000000000000000000, "mil trilions"), + (10000000000000000000000000, "deu quadrilions"), +) + +TEST_CASES_ORDINAL = ( + (1, "primer"), + (2, "segon"), + (8, "vuitè"), + (12, "dotzè"), + (14, "catorzè"), + (28, "vint-i-vuitè"), + (33, "trenta-tresè"), + (88, "vuitanta-vuitè"), + (100, "centè"), + (128, "cent vint-i-vuitè"), + (199, "cent noranta-novè"), + (1000, "milè"), + (1827, "mil vuit-cents vint-i-setè"), + (12345, "dotze mil tres-cents quaranta-cinquè"), + (1000000, "milionè"), + (1000000000000000, "mil bilionè"), + (1000000000000000, "mil bilionè"), + (1000000000000000000, "un trilionè"), # over 1e18 is not supported +) + +TEST_CASES_ORDINAL_NUM = ( + (1, "1r"), + (8, "8è"), + (12, "12è"), + (14, "14è"), + (28, "28è"), + (100, "100è"), + (1000, "1000è"), + (1000000, "1000000è"), +) + +TEST_CASES_TO_CURRENCY = ( + (1.00, "un euro amb zero cèntims"), + (1.01, "un euro amb un cèntim"), + (2.00, "dos euros amb zero cèntims"), + (8.00, "vuit euros amb zero cèntims"), + (12.00, "dotze euros amb zero cèntims"), + (21.00, "vint-i-un euros amb zero cèntims"), + (81.25, "vuitanta-un euros amb vint-i-cinc cèntims"), + (350.90, "tres-cents cinquanta euros amb noranta cèntims"), + (100.00, "cent euros amb zero cèntims"), +) + +TEST_CASES_TO_CURRENCY_ESP = ( + (1.00, "una pesseta amb zero cèntims"), + (1.01, "una pesseta amb un cèntim"), + (2.00, "dues pessetes amb zero cèntims"), + (8.00, "vuit pessetes amb zero cèntims"), + (12.00, "dotze pessetes amb zero cèntims"), + (21.00, "vint-i-una pessetes amb zero cèntims"), + (81.25, "vuitanta-una pessetes amb vint-i-cinc cèntims"), + (350.90, "tres-centes cinquanta pessetes amb noranta cèntims"), + (100.00, "cent pessetes amb zero cèntims"), +) + +TEST_CASES_TO_CURRENCY_USD = ( + (1.00, "un dòlar amb zero centaus"), + (2.00, "dos dòlars amb zero centaus"), + (8.00, "vuit dòlars amb zero centaus"), + (12.00, "dotze dòlars amb zero centaus"), + (21.00, "vint-i-un dòlars amb zero centaus"), + (81.25, "vuitanta-un dòlars amb vint-i-cinc centaus"), + (350.90, "tres-cents cinquanta dòlars amb noranta centaus"), + (100.00, "cent dòlars amb zero centaus"), +) + + +TEST_CASES_TO_CURRENCY_GBP = ( + (1.00, "una lliura amb zero penics"), + (1.01, "una lliura amb un penic"), + (2.00, "dues lliures amb zero penics"), + (8.00, "vuit lliures amb zero penics"), + (12.00, "dotze lliures amb zero penics"), + (21.00, "vint-i-una lliures amb zero penics"), + (81.25, "vuitanta-una lliures amb vint-i-cinc penics"), + (350.90, "tres-centes cinquanta lliures amb noranta penics"), + (100.00, "cent lliures amb zero penics"), +) + + +class TestNum2WordsCA(TestCase): + def _test_cases(self, cases, lang="ca", to="cardinal", **kwargs): + for case in cases: + self.assertEqual(num2words(case[0], lang=lang, + to=to, **kwargs), case[1]) + + def test_cardinal(self): + self._test_cases(TEST_CASES_CARDINAL) + + def test_ordinal(self): + self._test_cases(TEST_CASES_ORDINAL, to="ordinal") + + def test_ordinal_num(self): + self._test_cases(TEST_CASES_ORDINAL_NUM, to="ordinal_num") + + def test_currency(self): + self._test_cases(TEST_CASES_TO_CURRENCY, to="currency", currency="EUR") + + def test_currency_esp(self): + self._test_cases(TEST_CASES_TO_CURRENCY_ESP, + to="currency", currency="ESP") + + def test_currency_usd(self): + self._test_cases(TEST_CASES_TO_CURRENCY_USD, + to="currency", currency="USD") + + def test_currency_gbp(self): + self._test_cases(TEST_CASES_TO_CURRENCY_GBP, + to="currency", currency="GBP") diff --git a/tests/test_ce.py b/tests/test_ce.py new file mode 100644 index 00000000..7deddfe6 --- /dev/null +++ b/tests/test_ce.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2023, Johannes Heinecke. 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 + +from unittest import TestCase + +from num2words import num2words + +TEST_CASES_CARDINAL = [ + (1, "obl", "б", "цхьана"), + (2, "comp", "в", "шиннал"), + (3, "mat", "д", "кхааннах"), + (4, "mat", "в", "веаннах"), + (5, "abs", "й", "пхиъ"), + (6, "dat", "д", "ялханна"), + (7, "erg", "в", "ворхӀамма"), + (8, "comp", "й", "бархӀаннал"), + (9, "dat", "й", "иссанна"), + (10, "erg", "б", "иттамма"), + (11, "dat", "б", "цхьайттанна"), + (12, "instr", "й", "шийттанца"), + (13, "erg", "б", "кхойттамма"), + (14, "all", "в", "вейттанга"), + (15, "dat", "б", "пхийттанна"), + (16, "dat", "й", "ялхиттанна"), + (17, "dat", "в", "вуьрхӀиттанна"), + (18, "attr", "й", "берхӀитта"), + (19, "all", "й", "ткъайеснанга"), + (20, "attr", "б", "ткъе"), + (21, "all", "в", "ткъе цхаьнга"), + (22, "obl", "в", "ткъе шина"), + (23, "attr", "б", "ткъе кхо"), + (24, "dat", "й", "ткъе йеанна"), + (25, "attr", "й", "ткъе пхи"), + (26, "abs", "б", "ткъе ялх"), + (27, "abs", "в", "ткъе ворхӀ"), + (28, "all", "б", "ткъе бархӀанга"), + (29, "mat", "д", "ткъе иссаннах"), + (30, "gen", "й", "ткъе иттаннан"), + (31, "dat", "в", "ткъе цхьайттанна"), + (32, "comp", "й", "ткъе шийттаннал"), + (33, "instr", "в", "ткъе кхойттанца"), + (34, "instr", "в", "ткъе вейттанца"), + (35, "comp", "в", "ткъе пхийттаннал"), + (36, "dat", "й", "ткъе ялхиттанна"), + (37, "obl", "в", "ткъе вуьрхӀиттан"), + (38, "dat", "й", "ткъе берхӀиттанна"), + (39, "mat", "й", "ткъе ткъайеснаннах"), + (40, "all", "д", "шовзткъанга"), + (41, "obl", "в", "шовзткъе цхьана"), + (42, "dat", "в", "шовзткъе шинна"), + (43, "erg", "й", "шовзткъе кхаамма"), + (44, "erg", "й", "шовзткъе йеамма"), + (45, "comp", "д", "шовзткъе пхеаннал"), + (46, "mat", "б", "шовзткъе ялханнах"), + (47, "erg", "б", "шовзткъе ворхӀамма"), + (48, "erg", "в", "шовзткъе бархӀамма"), + (49, "all", "б", "шовзткъе иссанга"), + (50, "mat", "й", "шовзткъе иттаннах"), + (51, "comp", "в", "шовзткъе цхьайттаннал"), + (52, "erg", "в", "шовзткъе шийттамма"), + (53, "attr", "д", "шовзткъе кхойтта"), + (54, "gen", "б", "шовзткъе бейттаннан"), + (55, "attr", "д", "шовзткъе пхийтта"), + (56, "instr", "й", "шовзткъе ялхиттанца"), + (57, "obl", "б", "шовзткъе вуьрхӀиттан"), + (58, "attr", "б", "шовзткъе берхӀитта"), + (59, "all", "й", "шовзткъе ткъайеснанга"), + (60, "all", "й", "кхузткъанга"), + (61, "gen", "й", "кхузткъе цхьаннан"), + (62, "all", "б", "кхузткъе шинга"), + (63, "instr", "б", "кхузткъе кхаанца"), + (64, "dat", "й", "кхузткъе йеанна"), + (65, "instr", "й", "кхузткъе нхеанца"), + (66, "all", "б", "кхузткъе ялханга"), + (67, "erg", "д", "кхузткъе ворхӀамма"), + (68, "instr", "д", "кхузткъе бархӀанца"), + (69, "mat", "й", "кхузткъе иссаннах"), + (70, "attr", "б", "кхузткъе итт"), + (71, "gen", "б", "кхузткъе цхьайттаннан"), + (72, "abs", "й", "кхузткъе шийтта"), + (73, "mat", "д", "кхузткъе кхойттаннах"), + (74, "instr", "й", "кхузткъе йейттанца"), + (75, "mat", "в", "кхузткъе пхийттаннах"), + (76, "instr", "б", "кхузткъе ялхиттанца"), + (77, "dat", "в", "кхузткъе вуьрхӀиттанна"), + (78, "erg", "д", "кхузткъе берхӀиттамма"), + (79, "gen", "б", "кхузткъе ткъайеснаннан"), + (80, "dat", "б", "дезткъанна"), + (81, "gen", "б", "дезткъе цхьаннан"), + (82, "dat", "б", "дезткъе шинна"), + (83, "obl", "д", "дезткъе кхона"), + (84, "erg", "в", "дезткъе веамма"), + (85, "all", "в", "дезткъе пхеанга"), + (86, "erg", "д", "дезткъе ялхамма"), + (87, "comp", "б", "дезткъе ворхӀаннал"), + (88, "dat", "д", "дезткъе бархӀанна"), + (89, "erg", "б", "дезткъе иссамма"), + (90, "obl", "й", "дезткъе иттан"), + (91, "obl", "б", "дезткъе цхьайттан"), + (92, "abs", "б", "дезткъе шийтта"), + (93, "gen", "в", "дезткъе кхойттаннан"), + (94, "comp", "б", "дезткъе бейттаннал"), + (95, "all", "б", "дезткъе пхийттанга"), + (96, "instr", "д", "дезткъе ялхиттанца"), + (97, "erg", "д", "дезткъе вуьрхӀиттамма"), + (98, "instr", "й", "дезткъе берхӀиттанца"), + (99, "instr", "б", "дезткъе ткъайеснанца"), + (0, "gen", "б", "нолан"), + (100, "mat", "б", "бӀеннах"), + (200, "attr", "д", "ши бӀе"), + (300, "obl", "в", "кхо бӀен"), + (400, "abs", "в", "ви бӀе"), + (500, "all", "й", "пхи бӀенга"), + (600, "abs", "й", "ялх бӀе"), + (700, "mat", "й", "ворхӀ бӀеннах"), + (800, "gen", "б", "бархӀ бӀеннан"), + (900, "mat", "в", "исс бӀеннах"), + (1000, "gen", "д", "эзарнан"), + (1100, "instr", "д", "эзар бӀенца"), + (1200, "instr", "д", "эзар ши бӀенца"), + (1300, "comp", "б", "эзар кхо бӀеннал"), + (1400, "instr", "д", "эзар ди бӀенца"), + (1500, "comp", "б", "эзар пхи бӀеннал"), + (1600, "erg", "б", "эзар ялх бӀемма"), + (1700, "attr", "д", "эзар ворхӀ бӀе"), + (1800, "obl", "д", "эзар бархӀ бӀен"), + (1900, "gen", "й", "эзар исс бӀеннан"), + (2000, "comp", "д", "ши эзарнал"), + (2022, "comp", "д", "ши эзар ткъе шиннал"), + (2100, "obl", "в", "ши эзар бӀен"), + (423000, "erg", "в", "ви бӀе ткъе кхо эзарно"), +] + +TEST_CASES_ORDINAL = [ + (1, "all", "б", "цхьалгӀа"), + (2, "dat", "в", "шолгӀа"), + (3, "obl", "й", "кхоалгӀа"), + (4, "dat", "б", "боьалгӀа"), + (5, "dat", "в", "пхоьалгӀа"), + (6, "abs", "в", "йолхалгӀа"), + (7, "abs", "в", "ворхӀалгӀа"), + (8, "abs", "д", "борхӀалӀа"), + (9, "comp", "д", "уьссалгӀа"), + (10, "erg", "д", "уьтталгӀа"), + (11, "all", "б", "цхьайтталгӀа"), + (12, "abs", "й", "шийтталга"), + (13, "gen", "в", "кхойтталгӀа"), + (14, "gen", "в", "вейтталгӀа"), + (15, "mat", "й", "пхийтталгӀа"), + (16, "dat", "й", "ялхитталгӀа"), + (17, "erg", "д", "вуьрхӀитталгӀа"), + (18, "erg", "й", "берхитталӀа"), + (19, "obl", "в", "ткъаесналгӀа"), + (20, "abs", "в", "ткъолгӀа"), + (21, "mat", "б", "ткъе цхьалгӀа"), + (22, "erg", "б", "ткъе шолгӀа"), + (23, "mat", "й", "ткъе кхоалгӀа"), + (24, "obl", "б", "ткъе боьалгӀа"), + (25, "abs", "д", "ткъе пхоьалгӀа"), + (26, "all", "й", "ткъе йолхалгӀа"), + (27, "mat", "в", "ткъе ворхӀалгӀа"), + (28, "instr", "д", "ткъе борхӀалӀа"), + (29, "obl", "б", "ткъе уьссалгӀа"), + (30, "dat", "б", "ткъе уьтталгӀа"), + (31, "obl", "й", "ткъе цхьайтталгӀа"), + (32, "comp", "д", "ткъе шийтталга"), + (33, "attr", "д", "ткъе кхойтталгӀа"), + (34, "gen", "в", "ткъе вейтталгӀа"), + (35, "erg", "д", "ткъе пхийтталгӀа"), + (36, "all", "в", "ткъе ялхитталгӀа"), + (37, "attr", "й", "ткъе вуьрхӀитталгӀа"), + (38, "erg", "б", "ткъе берхитталӀа"), + (39, "gen", "д", "ткъе ткъаесналгӀа"), + (40, "abs", "й", "шовзткъалгІа"), + (41, "erg", "й", "шовзткъе цхьалгӀа"), + (42, "comp", "й", "шовзткъе шолгӀа"), + (43, "obl", "д", "шовзткъе кхоалгӀа"), + (44, "all", "й", "шовзткъе йоьалгӀа"), + (45, "abs", "д", "шовзткъе пхоьалгӀа"), + (46, "comp", "д", "шовзткъе йолхалгӀа"), + (47, "comp", "й", "шовзткъе ворхӀалгӀа"), + (48, "attr", "б", "шовзткъе борхӀалӀа"), + (49, "comp", "й", "шовзткъе уьссалгӀа"), + (50, "abs", "д", "шовзткъе уьтталгӀа"), + (51, "dat", "б", "шовзткъе цхьайтталгӀа"), + (52, "comp", "в", "шовзткъе шийтталга"), + (53, "mat", "б", "шовзткъе кхойтталгӀа"), + (54, "all", "д", "шовзткъе дейтталгӀа"), + (55, "dat", "в", "шовзткъе пхийтталгӀа"), + (56, "erg", "б", "шовзткъе ялхитталгӀа"), + (57, "comp", "й", "шовзткъе вуьрхӀитталгӀа"), + (58, "instr", "в", "шовзткъе берхитталӀа"), + (59, "mat", "б", "шовзткъе ткъаесналгӀа"), + (60, "all", "в", "кхузткъалгІа"), + (61, "obl", "д", "кхузткъе цхьалгӀа"), + (62, "instr", "д", "кхузткъе шолгӀа"), + (63, "erg", "й", "кхузткъе кхоалгӀа"), + (64, "dat", "д", "кхузткъе доьалгӀа"), + (65, "gen", "д", "кхузткъе пхоьалгӀа"), + (66, "mat", "в", "кхузткъе йолхалгӀа"), + (67, "gen", "в", "кхузткъе ворхӀалгӀа"), + (68, "attr", "б", "кхузткъе борхӀалӀа"), + (69, "all", "д", "кхузткъе уьссалгӀа"), + (70, "mat", "в", "кхузткъе уьтталгӀа"), + (71, "gen", "й", "кхузткъе цхьайтталгӀа"), + (72, "obl", "й", "кхузткъе шийтталга"), + (73, "attr", "в", "кхузткъе кхойтталгӀа"), + (74, "dat", "б", "кхузткъе бейтталгӀа"), + (75, "instr", "в", "кхузткъе пхийтталгӀа"), + (76, "gen", "в", "кхузткъе ялхитталгӀа"), + (77, "erg", "д", "кхузткъе вуьрхӀитталгӀа"), + (78, "all", "й", "кхузткъе берхитталӀа"), + (79, "instr", "д", "кхузткъе ткъаесналгӀа"), + (80, "dat", "в", "дезткъалгІа"), + (81, "mat", "в", "дезткъе цхьалгӀа"), + (82, "abs", "д", "дезткъе шолгӀа"), + (83, "abs", "д", "дезткъе кхоалгӀа"), + (84, "erg", "в", "дезткъе воьалгӀа"), + (85, "obl", "й", "дезткъе пхоьалгӀа"), + (86, "instr", "д", "дезткъе йолхалгӀа"), + (87, "all", "в", "дезткъе ворхӀалгӀа"), + (88, "dat", "д", "дезткъе борхӀалӀа"), + (89, "obl", "б", "дезткъе уьссалгӀа"), + (90, "instr", "в", "дезткъе уьтталгӀа"), + (91, "abs", "й", "дезткъе цхьайтталгӀа"), + (92, "comp", "в", "дезткъе шийтталга"), + (93, "erg", "д", "дезткъе кхойтталгӀа"), + (94, "obl", "й", "дезткъе йейтталгӀа"), + (95, "comp", "б", "дезткъе пхийтталгӀа"), + (96, "obl", "б", "дезткъе ялхитталгӀа"), + (97, "gen", "й", "дезткъе вуьрхӀитталгӀа"), + (98, "dat", "б", "дезткъе берхитталӀа"), + (99, "abs", "д", "дезткъе ткъаесналгӀа"), + (100, "abs", "в", "бІолгІа"), + (200, "obl", "й", "ши бІолгІа"), + (300, "mat", "в", "кхо бІолгІа"), + (400, "gen", "б", "би бІолгІа"), + (500, "erg", "й", "пхи бІолгІа"), + (600, "gen", "д", "ялх бІолгІа"), + (700, "instr", "й", "ворхӀ бІолгІа"), + (800, "all", "б", "бархӀ бІолгІа"), + (900, "comp", "б", "исс бІолгІа"), + (1000, "dat", "д", "эзарлагІа"), + (107, "gen", "в", "бӀе ворхӀалгӀа"), + (214, "attr", "д", "ши бӀе дейтталгӀа"), + (321, "comp", "д", "кхо бӀе ткъе цхьалгӀа"), + (428, "dat", "в", "ви бӀе ткъе борхӀалӀа"), + (535, "erg", "й", "пхи бӀе ткъе пхийтталгӀа"), + (642, "all", "й", "ялх бӀе шовзткъе шолгӀа"), + (749, "mat", "в", "ворхӀ бӀе шовзткъе уьссалгӀа"), + (856, "attr", "й", "бархӀ бӀе шовзткъе ялхитталгӀа"), + (963, "mat", "б", "исс бӀе кхузткъе кхоалгӀа"), + (1070, "comp", "в", "эзар кхузткъе уьтталгӀа"), + (1177, "dat", "в", "эзар бӀе кхузткъе вуьрхӀитталгӀа"), + (1284, "abs", "д", "эзар ши бӀе дезткъе доьалгӀа"), + (1391, "dat", "в", "эзар кхо бӀе дезткъе цхьайтталгӀа"), + (1498, "abs", "в", "эзар ви бӀе дезткъе берхитталӀа"), + (1605, "obl", "б", "эзар ялх бӀе пхоьалгӀа"), + (1712, "erg", "й", "эзар ворхӀ бӀе шийтталга"), + (1819, "all", "б", "эзар бархӀ бӀе ткъаесналгӀа"), + (1926, "abs", "б", "эзар исс бӀе ткъе йолхалгӀа"), + (2033, "all", "д", "ши эзар ткъе кхойтталгӀа"), + (2140, "dat", "б", "ши эзар бӀе шовзткъалгІа"), + (423000, "dat", "д", "ди бӀе ткъе кхо эзарлагІа"), +] + +TEST_CASES_YEAR = [ + (1719, "abs", "эзар ворхӀ бӀе ткъайесна"), + (1812, "abs", "эзар бархӀ бӀе шийтта"), + (1926, "abs", "эзар исс бӀе ткъе ялх"), +] + +TEST_CASES_DECIMALS = [(123.4567, "бӀе ткъе кхоъ а диъ пхиъ ялх ворхӀ")] + +TEST_CASES_MILLIONS = [ + (200020, "ши бӀе эзар ткъа"), + (4000400, "ди миллион ди бӀе"), + (60006000, "кхузткъе миллион ялх эзар"), + (800080000, "бархӀ бӀе миллион дезткъе эзар"), + (10001000000, "итт миллиард цхьа миллион"), + (120012000000, "бӀе ткъе миллиард шийтта миллион"), + (1400140000000, "цхьа биллион ди бӀе миллиард бӀе шовзткъе миллион"), + (16001600000000, "ялхитта биллион цхьа миллиард ялх бӀе миллион"), + (180018000000000, "бӀе дезткъе биллион берхӀитта миллиард"), + (2000200000000000, "ши биллиард ши бӀе миллиард"), + (22002200000000000, "ткъе ши биллиард ши биллион ши бӀе миллиард"), + (240024000000000000, "ши бӀе шовзткъе биллиард ткъе ди биллион"), + ( + 2600260000000000000, + "ши триллион ялх бӀе биллиард ши бӀе кхузткъе биллион", + ), + ( + 28002800000000000000, + "ткъе бархӀ триллион ши биллиард бархӀ бӀе биллион", + ), + (300030000000000000000, "кхо бӀе триллион ткъе итт биллиард"), + ( + 3200320000000000000000, + "кхо триллиард ши бӀе триллион кхо бӀе ткъе биллиард", + ), + ( + 34003400000000000000000, + "ткъе дейтта триллиард кхо триллион ди бӀе биллиард", + ), + ( + 360036000000000000000000, + "кхо бӀе кхузткъе триллиард ткъе ялхитта триллион", + ), + ( + 3800380000000000000000000, + "кхо квадриллион бархӀ бӀе триллиард кхо бӀе дезткъе триллион", + ), + (40004000000000000000000000, "шовзткъе квадриллион ди триллиард"), + ( + 420042000000000000000000000, + "ди бӀе ткъе квадриллион шовзткъе ши триллиард", + ), + ( + 4400440000000000000000000000, + "ди квадриллиард ди бӀе квадриллион ди бӀе шовзткъе триллиард", + ), + ( + 46004600000000000000000000000, + "шовзткъе ялх квадриллиард ди квадриллион ялх бӀе триллиард", + ), + ( + 480048000000000000000000000000, + "ди бӀе дезткъе квадриллиард шовзткъе бархӀ квадриллион", + ), + (5000500000000000000000000000000, "пхи квинтиллион пхи бӀе квадриллион"), + ( + 52005200000000000000000000000000, + "шовзткъе шийтта квинтиллион пхи квадриллиард ши бӀе квадриллион", + ), + ( + 540054000000000000000000000000000, + "пхи бӀе шовзткъе квинтиллион шовзткъе дейтта квадриллиард", + ), + ( + 5600560000000000000000000000000000, + "пхи квинтиллиард ялх бӀе квинтиллион пхи бӀе кхузткъе квадриллиард", + ), + (10**56, "NOT IMPLEMENTED") +] + +TEST_CURRENCY = [ + (143.55, "abs", "RUB", "бӀе шовзткъе кхо Сом, шовзткъе пхийтта Кепек"), + (243.15, "dat", "RUB", "ши бӀе шовзткъе кхона Сом, пхийттан Кепек"), +] + + +class Num2WordsCETest(TestCase): + def test_number(self): + for test in TEST_CASES_CARDINAL: + self.assertEqual( + num2words(test[0], lang="ce", case=test[1], clazz=test[2]), + test[3], + ) + + def test_millions(self): + for test in TEST_CASES_MILLIONS: + self.assertEqual(num2words(test[0], lang="ce"), test[1]) + + def test_ordinal_number(self): + for test in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang="ce", to="ordinal", clazz=test[2]), + test[3], + ) + self.assertEqual(num2words(3, to="ordinal_num", lang='ce'), "3-й") + self.assertEqual(num2words(5, to="ordinal_num", lang='ce'), "5-й") + self.assertEqual(num2words(82, to="ordinal_num", lang='ce'), "82-й") + + def test_year(self): + for test in TEST_CASES_YEAR: + self.assertEqual( + num2words(test[0], lang="ce", to="year", case=test[1]), test[2] + ) + + def test_currency(self): + for test in TEST_CURRENCY: + self.assertEqual( + num2words( + test[0], + lang="ce", + to="currency", + currency=test[2], + case=test[1], + ), + test[3], + ) + + def test_currency_missing(self): + with self.assertRaises(NotImplementedError): + num2words(2.45, to="currency", lang='cy', currency="DEM") + + def test_decimals(self): + for test in TEST_CASES_DECIMALS: + self.assertEqual(num2words(test[0], lang="ce"), test[1]) diff --git a/tests/test_cli.py b/tests/test_cli.py index 484a8dcd..f4b9b4bb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -22,6 +22,7 @@ import unittest import delegator + import num2words @@ -53,17 +54,17 @@ def test_cli_help(self): self.assertTrue(output.err.startswith('Usage:')) def test_cli_list_langs(self): - """You should be able to list all availabe languages + """You should be able to list all available languages """ output = self.cli.run_cmd('--list-languages') self.assertEqual( sorted(list(num2words.CONVERTER_CLASSES.keys())), - output.out.strip().split(os.linesep) + [out for out in output.out.strip().splitlines() if out] ) output = self.cli.run_cmd('-L') self.assertEqual( sorted(list(num2words.CONVERTER_CLASSES.keys())), - output.out.strip().split(os.linesep) + [out for out in output.out.strip().splitlines() if out] ) def test_cli_list_converters(self): @@ -72,12 +73,12 @@ def test_cli_list_converters(self): output = self.cli.run_cmd('--list-converters') self.assertEqual( sorted(list(num2words.CONVERTES_TYPES)), - output.out.strip().split(os.linesep) + [out for out in output.out.strip().splitlines() if out] ) output = self.cli.run_cmd('-C') self.assertEqual( sorted(list(num2words.CONVERTES_TYPES)), - output.out.strip().split(os.linesep) + [out for out in output.out.strip().splitlines() if out] ) def test_cli_default_lang(self): @@ -87,7 +88,7 @@ def test_cli_default_lang(self): self.assertEqual(output.return_code, 0) self.assertEqual( output.out.strip(), - "one hundred and fifty point zero" + "one hundred and fifty" ) def test_cli_with_lang(self): @@ -97,15 +98,16 @@ def test_cli_with_lang(self): self.assertEqual(output.return_code, 0) self.assertEqual( output.out.strip(), - "ciento cincuenta punto cero" + "ciento cincuenta" ) def test_cli_with_lang_to(self): - """You should be able to specify a language + """You should be able to specify a language and currency """ output = self.cli.run_cmd(150.55, '--lang', 'es', '--to', 'currency') self.assertEqual(output.return_code, 0) self.assertEqual( - output.out.strip(), - "ciento cincuenta euros con cincuenta y cinco centimos" + (output.out.decode('utf-8') if hasattr(output.out, 'decode') else + output.out).strip(), + "ciento cincuenta euros con cincuenta y cinco céntimos" ) diff --git a/tests/test_cy.py b/tests/test_cy.py new file mode 100644 index 00000000..3f7ee038 --- /dev/null +++ b/tests/test_cy.py @@ -0,0 +1,475 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2023, Johannes Heinecke. 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 + +from unittest import TestCase + +from num2words import num2words + +TEST_CASES_CARDINAL = ( + (0, "dim"), + (1, "un"), + (1, "un"), + (2, "dau"), + (3, "tri"), + (4, "pedwar"), + (5, "pump"), + (6, "chwech"), + (7, "saith"), + (8, "wyth"), + (9, "naw"), + (10, "deg"), + (11, "un ar ddeg"), + (12, "deuddeg"), + (13, "tri ar ddeg"), + (14, "pedwar ar ddeg"), + (15, "pymtheg"), + (16, "un ar bymtheg"), + (17, "dau ar bymtheg"), + (18, "deunaw"), + (19, "pedwar ar bymtheg"), + (20, "ugain"), + (21, "un ar hugain"), + (22, "dau ar hugain"), + (23, "tri ar hugain"), + (24, "pedwar ar hugain"), + (25, "pump ar hugain"), + (26, "chwech ar hugain"), + (27, "saith ar hugain"), + (28, "wyth ar hugain"), + (29, "naw ar hugain"), + (30, "deg ar hugain"), + (31, "un ar ddeg ar hugain"), + (32, "deuddeg ar hugain"), + (33, "tri ar ddeg ar hugain"), + (34, "pedwar ar ddeg ar hugain"), + (35, "pymtheg ar hugain"), + (36, "un ar bymtheg ar hugain"), + (37, "dau ar bymtheg ar hugain"), + (38, "deunaw ar hugain"), + (39, "pedwar ar bymtheg ar hugain"), + (40, "deugain"), + (41, "un a deugain"), + (42, "dau a deugain"), + (43, "tri a deugain"), + (44, "pedwar a deugain"), + (45, "pump a deugain"), + (46, "chwech a deugain"), + (47, "saith a deugain"), + (48, "wyth a deugain"), + (49, "naw a deugain"), + (50, "hanner cant"), + (51, "hanner cant ac un"), + (52, "hanner cant a dau"), + (53, "hanner cant a thri"), + (54, "hanner cant a phedwar"), + (55, "hanner cant a phump"), + (56, "hanner cant a chwech"), + (57, "hanner cant a saith"), + (58, "hanner cant a wyth"), + (59, "hanner cant a naw"), + (60, "trigain"), + (61, "un a thrigain"), + (62, "dau a thrigain"), + (63, "tri a thrigain"), + (64, "pedwar a thrigain"), + (65, "pump a thrigain"), + (66, "chwech a thrigain"), + (67, "saith a thrigain"), + (68, "wyth a thrigain"), + (69, "naw a thrigain"), + (70, "deg a thrigain"), + (71, "un ar ddeg a thrigain"), + (72, "deuddeg a thrigain"), + (73, "tri ar ddeg a thrigain"), + (74, "pedwar ar ddeg a thrigain"), + (75, "pymtheg a thrigain"), + (76, "un ar bymtheg a thrigain"), + (77, "dau ar bymtheg a thrigain"), + (78, "deunaw a thrigain"), + (79, "pedwar ar bymtheg a thrigain"), + (80, "pedwar ugain"), + (81, "un a phedwar ugain"), + (82, "dau a phedwar ugain"), + (83, "tri a phedwar ugain"), + (84, "pedwar a phedwar ugain"), + (85, "pump a phedwar ugain"), + (86, "chwech a phedwar ugain"), + (87, "saith a phedwar ugain"), + (88, "wyth a phedwar ugain"), + (89, "naw a phedwar ugain"), + (90, "deg a phedwar ugain"), + (91, "un ar ddeg a phedwar ugain"), + (92, "deuddeg a phedwar ugain"), + (93, "tri ar ddeg a phedwar ugain"), + (94, "pedwar ar ddeg a phedwar ugain"), + (95, "pymtheg a phedwar ugain"), + (96, "un ar bymtheg a phedwar ugain"), + (97, "dau ar bymtheg a phedwar ugain"), + (98, "deunaw a phedwar ugain"), + (99, "pedwar ar bymtheg a phedwar ugain"), + (100, "cant"), + (101, "cant ac un"), + (102, "cant a dau"), + (103, "cant a thri"), + (104, "cant a phedwar"), + (105, "cant a phump"), + (106, "cant a chwech"), + (107, "cant a saith"), + (108, "cant ac wyth"), + (109, "cant a naw"), + (110, "cant a deg"), + (111, "cant ac un ar ddeg"), + (112, "cant a deuddeg"), + (113, "cant a thri ar ddeg"), + (114, "cant a phedwar ar ddeg"), + (115, "cant a phymtheg"), + (116, "cant ac un ar bymtheg"), + (117, "cant a dau ar bymtheg"), + (118, "cant a deunaw"), + (119, "cant a phedwar ar bymtheg"), + (120, "cant ac ugain"), + (121, "cant ac un ar hugain"), + (122, "cant a dau ar hugain"), + (100, "cant"), + (217, "dau gant a dau ar bymtheg"), + (334, "tri chant a phedwar ar ddeg ar hugain"), + (451, "pedwar cant a hanner ac un"), + (568, "pump cant ac wyth a thrigain"), + (685, "chwech chant a phump a phedwar ugain"), + (802, "wyth cant a dau"), + (919, "naw cant a phedwar ar bymtheg"), + (100, "cant"), + (150, "cant a hanner"), + (200, "dau gant"), + (300, "tri chant"), + (400, "pedwar cant"), + (500, "pump cant"), + (600, "chwech chant"), + (700, "saith cant"), + (800, "wyth cant"), + (900, "naw cant"), + (1000, "mil"), + (1000, "mil"), + (12111, "deuddeg mil cant ac un ar ddeg"), + (23222, "tair ar hugain mil dau gant a dau ar hugain"), + ( + 34333, + "pedair ar ddeg ar hugain mil tri chant a thri ar ddeg ar hugain", + ), + (45444, "pump a deugain mil pedwar cant a phedwar a deugain"), + (56555, "hanner cant a chwech mil pump cant a hanner a phump"), + (67666, "saith a thrigain mil chwech chant a chwech a thrigain"), + (78777, "deunaw a thrigain mil saith cant a dau ar bymtheg a thrigain"), + (89888, "naw a phedwar ugain mil wyth cant ac wyth a phedwar ugain"), + (100999, "cant mil naw cant a phedwar ar bymtheg a phedwar ugain"), + (112110, "cant a deuddeg mil cant a deg"), + (123221, "cant a thair ar hugain mil dau gant ac un ar hugain"), + ( + 134332, + "cant a phedair ar ddeg ar hugain mil tri chant a deuddeg ar hugain", + ), + (145443, "cant a phump a deugain mil pedwar cant a thri a deugain"), + (156554, "cant a hanner a chwech mil pump cant a hanner a phedwar"), + (123, "cant a thri ar hugain"), + (2345, "dwy fil tri chant a phump a deugain"), + (34567, "pedair ar ddeg ar hugain mil pump cant a saith a thrigain"), + (654321, "chwech chant a hanner a phedair mil tri chant ac un ar hugain"), + ( + 7654321, + "saith miliwn chwech chant a hanner a " + "phedair mil tri chant ac un ar hugain", + ), + ( + 987654321, + "naw cant a saith a phedwar ugain miliwn chwech chant a " + "hanner a phedair mil tri chant ac un ar hugain", + ), + ( + 123456789012, + "cant a thri ar hugain biliwn pedwar cant a hanner a chwech miliwn " + "saith cant a naw a phedwar ugain mil deuddeg", + ), + (2023, "dwy fil tri ar hugain"), + (-40123, "meinws deugain mil cant a thri ar hugain"), + (12340000000000000, "deuddeg cwadriliwn tri chant a deugain triliwn"), + (3000000000000000, "tri chwadriliwn"), + (2500000000000000000000000000000000, "dau ddengiliwn pump cant noniliwn"), +) + + +TEST_CASES_CARDINAL_FEM = ( + (2, "dwy"), + (3, "tair"), + (4, "pedair"), + (5, "pump"), + (6, "chwech"), + (7, "saith"), + (8, "wyth"), + (9, "naw"), + (10, "deg"), + (11, "un ar ddeg"), + (12, "deuddeg"), + (13, "tair ar ddeg"), + (14, "pedair ar ddeg"), + (15, "pymtheg"), + (16, "un ar bymtheg"), + (17, "dwy ar bymtheg"), + (18, "deunaw"), + (19, "pedair ar bymtheg"), + (20, "ugain"), + (21, "un ar hugain"), + (22, "dwy ar hugain"), + (23, "tair ar hugain"), + (24, "pedair ar hugain"), + (25, "pump ar hugain"), + (26, "chwech ar hugain"), + (27, "saith ar hugain"), + (28, "wyth ar hugain"), + (29, "naw ar hugain"), + (30, "deg ar hugain"), + (31, "un ar ddeg ar hugain"), + (32, "deuddeg ar hugain"), + (33, "tair ar ddeg ar hugain"), + (34, "pedair ar ddeg ar hugain"), + (35, "pymtheg ar hugain"), + (36, "un ar bymtheg ar hugain"), + (37, "dwy ar bymtheg ar hugain"), + (38, "deunaw ar hugain"), + (39, "pedair ar bymtheg ar hugain"), + (40, "deugain"), + (41, "un a deugain"), + (42, "dwy a deugain"), + (43, "tair a deugain"), + (44, "pedair a deugain"), + (45, "pump a deugain"), + (46, "chwech a deugain"), + (47, "saith a deugain"), + (48, "wyth a deugain"), + (49, "naw a deugain"), + (50, "hanner cant"), + (51, "hanner cant ac un"), + (52, "hanner cant a dwy"), + (53, "hanner cant a thair"), + (54, "hanner cant a phedair"), + (55, "hanner cant a phump"), + (56, "hanner cant a chwech"), + (57, "hanner cant a saith"), + (58, "hanner cant a wyth"), + (59, "hanner cant a naw"), + (60, "trigain"), + (61, "un a thrigain"), + (62, "dwy a thrigain"), +) + +TEST_CASES_ORDINAL = ( + (0, "dimfed"), + (1, "cyntaf"), + (2, "ail"), + (3, "trydydd"), + (4, "pedwerydd"), + (5, "pumed"), + (6, "chweched"), + (7, "saithfed"), + (8, "wythfed"), + (9, "nawfed"), + (10, "degfed"), + (11, "unfed ar ddeg"), + (12, "deuddegfed"), + (13, "trydydd ar ddeg"), + (14, "pedwerydd ar ddeg"), + (15, "pymthegfed"), + (16, "unfed ar bymtheg"), + (17, "ail ar bymtheg"), + (18, "deunawfed"), + (19, "pedwerydd ar bymtheg"), + (20, "ugainfed"), + (21, "cyntaf ar hugain"), + (22, "ail ar hugain"), + (23, "trydydd ar hugain"), + (24, "pedwerydd ar hugain"), + (25, "pumed ar hugain"), + (26, "chweched ar hugain"), + (27, "saithfed ar hugain"), + (28, "wythfed ar hugain"), + (29, "nawfed ar hugain"), + (30, "degfed ar hugain"), + (31, "unfed ar ddeg ar hugain"), + (32, "deuddegfed ar hugain"), + (33, "trydydd ar ddeg ar hugain"), + (34, "pedwerydd ar ddeg ar hugain"), + (35, "pymthegfed ar hugain"), + (36, "unfed ar bymtheg ar hugain"), + (37, "ail ar bymtheg ar hugain"), + (38, "deunawfed ar hugain"), + (39, "pedwerydd ar bymtheg ar hugain"), + (40, "deugainfed"), + (41, "cyntaf a deugain"), + (42, "ail a deugain"), + (43, "trydydd a deugain"), + (44, "pedwerydd a deugain"), + (45, "pumed a deugain"), + (46, "chweched a deugain"), + (47, "saithfed a deugain"), + (48, "wythfed a deugain"), + (49, "nawfed a deugain"), + (50, "degfed a deugain"), + (51, "unfed ar ddeg a deugain"), + (52, "deuddegfed a deugain"), + (53, "trydydd ar ddeg a deugain"), + (54, "pedwerydd ar ddeg a deugain"), + (55, "pymthegfed a deugain"), + (56, "unfed ar bymtheg a deugain"), + (57, "ail ar bymtheg a deugain"), + (58, "deunawfed a deugain"), + (59, "pedwerydd ar bymtheg a deugain"), + (60, "trigainfed"), + (61, "cyntaf a thrigain"), + (62, "ail a thrigain"), + (63, "trydydd a thrigain"), + (64, "pedwerydd a thrigain"), + (65, "pumed a thrigain"), + (66, "chweched a thrigain"), + (67, "saithfed a thrigain"), + (68, "wythfed a thrigain"), + (69, "nawfed a thrigain"), + (70, "degfed a thrigain"), + (71, "unfed ar ddeg a thrigain"), + (72, "deuddegfed a thrigain"), + (73, "trydydd ar ddeg a thrigain"), + (74, "pedwerydd ar ddeg a thrigain"), + (75, "pymthegfed a thrigain"), + (76, "unfed ar bymtheg a thrigain"), + (77, "ail ar bymtheg a thrigain"), + (78, "deunawfed a thrigain"), + (79, "pedwerydd ar bymtheg a thrigain"), + (80, "pedwar ugainfed"), + (81, "cyntaf a phedwar ugain"), + (82, "ail a phedwar ugain"), + (83, "trydydd a phedwar ugain"), + (84, "pedwerydd a phedwar ugain"), + (85, "pumed a phedwar ugain"), + (86, "chweched a phedwar ugain"), + (87, "saithfed a phedwar ugain"), + (88, "wythfed a phedwar ugain"), + (89, "nawfed a phedwar ugain"), + (90, "degfed a phedwar ugain"), + (91, "unfed ar ddeg a phedwar ugain"), + (92, "deuddegfed a phedwar ugain"), + (93, "trydydd ar ddeg a phedwar ugain"), + (94, "pedwerydd ar ddeg a phedwar ugain"), + (95, "pymthegfed a phedwar ugain"), + (96, "unfed ar bymtheg a phedwar ugain"), + (97, "ail ar bymtheg a phedwar ugain"), + (98, "deunawfed a phedwar ugain"), + (99, "pedwerydd ar bymtheg a phedwar ugain"), + (100, "canfed"), +) + +TEST_CASES_YEAR = [ + (1922, "mil naw dau dau"), + (1989, "mil naw wyth naw"), + (1812, "mil wyth un dau"), + (2012, "dwy fil deuddeg"), + (2023, "dwy fil tri ar hugain") + ] + +TEST_CASES_DECIMALS = [ + (123.4567, "cant a thri ar hugain pwynt pedwar pump chwech saith") +] + +TEST_CASES_TO_CURRENCY_GBP = ( + (0.00, "dim punt"), + (0.23, "tri cheiniog ar hugain"), + (2.04, "dwy bunt, pedwar ceiniog"), + (3.50, "tair punt, hanner cant ceiniog"), + (2002.15, "dwy fil dwy o bunnoedd, pymtheg ceiniog"), + (100.01, "cant punt, ceiniog"), + (50.00, "hanner cant punt"), + (51.00, "hanner cant ac un punt"), + (152.50, "cant a hanner a dwy o bunnoedd, hanner cant ceiniog"), +) + +TEST_CASES_COUNTED = [ + (2, "ci", "masc", "dau gi"), + (2, "ty", "masc", "dau dy"), + (2, "llwy", "fem", "dwy lwy"), + (2, "rhaglen", "masc", "dau raglen"), + (11, "ci", "masc", "un ci ar ddeg"), + (13, "ci", "masc", "tri chi ar ddeg"), + (26, "ci", "masc", "chwech chi ar hugain"), + (56, "ci", "masc", "hanner cant a chwech chi"), + (100, "cwn", "masc", "cant o gwn"), + (2000, "cathod", "fem", "dwy fil o gathod"), + (11, "cath", "fem", "un cath ar ddeg"), + (13, "cath", "fem", "tair cath ar ddeg"), + (26, "cath", "fem", "chwech chath ar hugain"), + (42, "cath", "fem", "dwy gath a deugain"), + (56, "cath", "fem", "hanner cant a chwech chath"), +] + + +class Num2WordsCYTest(TestCase): + def test_number(self): + for test in TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang="cy"), test[1]) + + def test_number_fem(self): + for test in TEST_CASES_CARDINAL_FEM: + self.assertEqual( + num2words(test[0], lang="cy", gender="fem"), test[1] + ) + + def test_number_not_implemented(self): + with self.assertRaises(NotImplementedError): + num2words(10**66, lang='cy') + + def test_decimals(self): + for test in TEST_CASES_DECIMALS: + self.assertEqual(num2words(test[0], lang="cy"), test[1]) + + def test_ordinals(self): + for test in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang="cy", to="ordinal"), test[1] + ) + + def test_ordinal_not_implemented(self): + with self.assertRaises(NotImplementedError): + num2words(101, lang='cy', to="ordinal") + + def test_pounds(self): + for test in TEST_CASES_TO_CURRENCY_GBP: + self.assertEqual( + num2words(test[0], lang="cy", to="currency", currency="GBP"), + test[1], + ) + + def test_other_cur(self): + with self.assertRaises(NotImplementedError): + num2words(10.23, lang="cy", to="currency", currency="DEM"), + + def test_counted(self): + for test in TEST_CASES_COUNTED: + self.assertEqual( + num2words( + test[0], lang="cy", counted=test[1], gender=test[2] + ), + test[3], + ) + +# TODO 'ordinal_num', 'year' diff --git a/tests/test_cz.py b/tests/test_cz.py index 4d237a75..1801e8f7 100644 --- a/tests/test_cz.py +++ b/tests/test_cz.py @@ -32,6 +32,14 @@ def test_cardinal(self): 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'), + "deset celá nula dva" + ) + self.assertEqual( + num2words(15.007, lang='cz'), + "patnáct celá nula nula sedm" + ) self.assertEqual( num2words(12519.85, lang='cz'), "dvanáct tisíc pětset devatenáct celá osmdesát pět" @@ -84,11 +92,11 @@ def test_currency(self): "tisíc dvěstě třicet čtyři koruny, padesát šest haléřů") self.assertEqual( num2words(101.11, lang='cz', to='currency', currency='EUR', - seperator=' a'), + separator=' a'), "sto jedna euro a jedenáct centů") self.assertEqual( num2words(101.21, lang='cz', to='currency', currency='CZK', - seperator=' a'), + separator=' a'), "sto jedna korun a dvacet jedna haléřů" ) self.assertEqual( @@ -97,7 +105,7 @@ def test_currency(self): ) self.assertEqual( num2words(123.50, lang='cz', to='currency', currency='CZK', - seperator=' a'), + separator=' a'), "sto dvacet tři koruny a padesát haléřů" ) self.assertEqual( diff --git a/tests/test_de.py b/tests/test_de.py index d20794db..119d3326 100644 --- a/tests/test_de.py +++ b/tests/test_de.py @@ -21,9 +21,52 @@ from num2words import num2words +TEST_CASES_TO_CURRENCY_EUR = ( + (1.00, 'ein Euro und null Cent'), + (2.01, 'zwei Euro und ein Cent'), + (8.10, 'acht Euro und zehn Cent'), + (12.26, 'zwölf Euro und sechsundzwanzig Cent'), + (21.29, 'einundzwanzig Euro und neunundzwanzig Cent'), + (81.25, 'einundachtzig Euro und fünfundzwanzig Cent'), + (100.00, 'einhundert Euro und null Cent'), +) + +TEST_CASES_TO_CURRENCY_USD = ( + (1.00, 'ein Dollar und null Cent'), + (2.01, 'zwei Dollar und ein Cent'), + (8.10, 'acht Dollar und zehn Cent'), + (12.26, 'zwölf Dollar und sechsundzwanzig Cent'), + (21.29, 'einundzwanzig Dollar und neunundzwanzig Cent'), + (81.25, 'einundachtzig Dollar und fünfundzwanzig Cent'), + (100.00, 'einhundert Dollar und null Cent'), +) + +TEST_CASES_TO_CURRENCY_GBP = ( + (1.00, 'ein Pfund und null Pence'), + (2.01, 'zwei Pfund und ein Penny'), + (8.10, 'acht Pfund und zehn Pence'), + (12.26, 'zwölf Pfund und sechsundzwanzig Pence'), + (21.29, 'einundzwanzig Pfund und neunundzwanzig Pence'), + (81.25, 'einundachtzig Pfund und fünfundzwanzig Pence'), + (100.00, 'einhundert Pfund und null Pence'), +) + +TEST_CASES_TO_CURRENCY_DEM = ( + (1.00, 'ein Mark und null Pfennig'), + (2.01, 'zwei Mark und ein Pfennig'), + (8.10, 'acht Mark und zehn Pfennig'), + (12.26, 'zwölf Mark und sechsundzwanzig Pfennig'), + (21.29, 'einundzwanzig Mark und neunundzwanzig Pfennig'), + (81.25, 'einundachtzig Mark und fünfundzwanzig Pfennig'), + (100.00, 'einhundert Mark und null Pfennig'), +) + class Num2WordsDETest(TestCase): + def test_ordinal_less_than_twenty(self): + self.assertEqual(num2words(0, ordinal=True, lang='de'), "nullte") + self.assertEqual(num2words(1, ordinal=True, lang='de'), "erste") self.assertEqual(num2words(7, ordinal=True, lang='de'), "siebte") self.assertEqual(num2words(8, ordinal=True, lang='de'), "achte") self.assertEqual(num2words(12, ordinal=True, lang='de'), "zwölfte") @@ -45,18 +88,28 @@ def test_ordinal_at_crucial_number(self): num2words(4000, ordinal=True, lang='de'), "viertausendste" ) self.assertEqual( - num2words(2000000, ordinal=True, lang='de'), "zwei millionste" + num2words(1000000, ordinal=True, lang='de'), "millionste" + ) + self.assertEqual( + num2words(2000000, ordinal=True, lang='de'), "zweimillionste" + ) + self.assertEqual( + num2words(1000000000, ordinal=True, lang='de'), "milliardste" ) self.assertEqual( num2words(5000000000, ordinal=True, lang='de'), - "fünf milliardste" + "fünfmilliardste" ) def test_cardinal_at_some_numbers(self): self.assertEqual(num2words(100, lang='de'), "einhundert") - self.assertEqual(num2words(2000000, lang='de'), "zwei millionen") - self.assertEqual(num2words(4000000000, lang='de'), "vier milliarden") - self.assertEqual(num2words(1000000000, lang='de'), "eine milliarde") + self.assertEqual(num2words(1000, lang='de'), "eintausend") + self.assertEqual(num2words(5000, lang='de'), "fünftausend") + self.assertEqual(num2words(10000, lang='de'), "zehntausend") + self.assertEqual(num2words(1000000, lang='de'), "eine Million") + self.assertEqual(num2words(2000000, lang='de'), "zwei Millionen") + self.assertEqual(num2words(4000000000, lang='de'), "vier Milliarden") + self.assertEqual(num2words(1000000000, lang='de'), "eine Milliarde") def test_cardinal_for_decimal_number(self): self.assertEqual( @@ -66,8 +119,8 @@ def test_cardinal_for_decimal_number(self): def test_giant_cardinal_for_merge(self): self.assertEqual( num2words(4500072900000111, lang='de'), - "vier billiarden fünfhundert billionen " + - "zweiundsiebzig milliarden neunhundert millionen einhundertelf" + "vier Billiarden fünfhundert Billionen " + + "zweiundsiebzig Milliarden neunhundert Millionen einhundertelf" ) def test_ordinal_num(self): @@ -80,29 +133,33 @@ def test_ordinal_for_negative_numbers(self): def test_ordinal_for_floating_numbers(self): self.assertRaises(TypeError, num2words, 2.453, ordinal=True, lang='de') - def test_currency(self): - self.assertEqual(num2words(1, lang='de', to='currency'), - 'ein Euro') - self.assertEqual(num2words(12, lang='de', to='currency'), - 'zwölf Euro') - self.assertEqual(num2words(12.00, lang='de', to='currency'), - 'zwölf Euro') - self.assertEqual(num2words(100.0, lang='de', to='currency'), - "einhundert Euro") - self.assertEqual(num2words(190, lang='de', to='currency'), - "einhundertneunzig Euro") - self.assertEqual(num2words(1.90, lang='de', to='currency'), - "ein Euro und neunzig Cent") - self.assertEqual(num2words(3.4, lang='de', to='currency'), - "drei Euro und vierzig Cent") - self.assertEqual(num2words(20.18, lang='de', to='currency'), - "zwanzig Euro und achtzehn Cent") - self.assertEqual(num2words(3.04, lang='de', to='currency'), - "drei Euro und vier Cent") - - def test_old_currency(self): - self.assertEqual(num2words(12.00, to='currency', lang='de', old=True), - 'zwölf Mark') + def test_currency_eur(self): + for test in TEST_CASES_TO_CURRENCY_EUR: + self.assertEqual( + num2words(test[0], lang='de', to='currency', currency='EUR'), + test[1] + ) + + def test_currency_usd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='de', to='currency', currency='USD'), + test[1] + ) + + def test_currency_dem(self): + for test in TEST_CASES_TO_CURRENCY_DEM: + self.assertEqual( + num2words(test[0], lang='de', to='currency', currency='DEM'), + test[1] + ) + + def test_currency_gbp(self): + for test in TEST_CASES_TO_CURRENCY_GBP: + self.assertEqual( + num2words(test[0], lang='de', to='currency', currency='GBP'), + test[1] + ) def test_year(self): self.assertEqual(num2words(2002, to='year', lang='de'), diff --git a/tests/test_dk.py b/tests/test_dk.py new file mode 100644 index 00000000..889e9d8e --- /dev/null +++ b/tests/test_dk.py @@ -0,0 +1,37 @@ +# 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +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") + + 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") diff --git a/tests/test_en.py b/tests/test_en.py index b477c5fc..e763841c 100644 --- a/tests/test_en.py +++ b/tests/test_en.py @@ -26,10 +26,18 @@ def test_and_join_199(self): self.assertEqual(num2words(199), "one hundred and ninety-nine") def test_ordinal(self): + self.assertEqual( + num2words(0, lang='en', to='ordinal'), + 'zeroth' + ) self.assertEqual( num2words(1, lang='en', to='ordinal'), 'first' ) + self.assertEqual( + num2words(13, lang='en', to='ordinal'), + 'thirteenth' + ) self.assertEqual( num2words(22, lang='en', to='ordinal'), 'twenty-second' @@ -71,58 +79,64 @@ def test_overflow(self): def test_to_currency(self): self.assertEqual( - num2words('38.4', lang='en', to='currency', seperator=' and', + num2words('38.4', lang='en', to='currency', separator=' and', cents=False, currency='USD'), "thirty-eight dollars and 40 cents" ) self.assertEqual( - num2words('0', lang='en', to='currency', seperator=' and', + num2words('0', lang='en', to='currency', separator=' and', cents=False, currency='USD'), "zero dollars and 00 cents" ) self.assertEqual( - num2words('1.01', lang='en', to='currency', seperator=' and', + num2words('1.01', lang='en', to='currency', separator=' and', cents=True, currency='USD'), "one dollar and one cent" ) self.assertEqual( - num2words('4778.00', lang='en', to='currency', seperator=' and', + num2words('4778.00', lang='en', to='currency', separator=' and', cents=True, currency='USD', adjective=True), 'four thousand, seven hundred and seventy-eight US dollars' ' and zero cents') self.assertEqual( - num2words('4778.00', lang='en', to='currency', seperator=' and', + num2words('4778.00', lang='en', to='currency', separator=' and', cents=True, currency='USD'), 'four thousand, seven hundred and seventy-eight dollars and' ' zero cents') self.assertEqual( - num2words('1.1', lang='en', to='currency', seperator=' and', + num2words('1.1', lang='en', to='currency', separator=' and', cents=True, currency='MXN'), "one peso and ten cents" ) self.assertEqual( - num2words('158.3', lang='en', to='currency', seperator=' and', + num2words('158.3', lang='en', to='currency', separator=' and', cents=True, currency='MXN'), "one hundred and fifty-eight pesos and thirty cents" ) self.assertEqual( - num2words('2000.00', lang='en', to='currency', seperator=' and', + num2words('2000.00', lang='en', to='currency', separator=' and', cents=True, currency='MXN'), "two thousand pesos and zero cents" ) self.assertEqual( - num2words('4.01', lang='en', to='currency', seperator=' and', + num2words('4.01', lang='en', to='currency', separator=' and', cents=True, currency='MXN'), "four pesos and one cent" ) + self.assertEqual( + num2words('2000.00', lang='en', to='currency', separator=' and', + cents=True, currency='UZS'), + "two thousand sums and zero tiyins" + ) + def test_to_year(self): # issue 141 # "e2 e2" diff --git a/tests/test_en_ng.py b/tests/test_en_ng.py new file mode 100644 index 00000000..6d7e72e5 --- /dev/null +++ b/tests/test_en_ng.py @@ -0,0 +1,143 @@ +# -*- 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 Num2WordsENNGTest(TestCase): + + # only the test for currency is writen as other + # functions in the Class remains the + # same and have been properly tested in the + # test test_en which tests the parent class + # upon which this class inherits + + def test_to_currency(self): + + language = 'en_NG' + separator = ' and' + + self.assertEqual( + num2words( + '38.4', + lang=language, + to='currency', + separator=separator, + kobo=False + ), + "thirty-eight naira and 40 kobo" + ) + self.assertEqual( + num2words( + '0', + lang=language, + to='currency', + separator=separator, + kobo=False + ), + "zero naira and 00 kobo" + ) + + self.assertEqual( + num2words( + '1.01', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + "one naira and one kobo" + ) + + self.assertEqual( + num2words( + '4778.00', + lang=language, + to='currency', + separator=separator, + kobo=True, adjective=True + ), + 'four thousand, seven hundred and seventy-eight Nigerian naira' + ' and zero kobo') + + self.assertEqual( + num2words( + '4778.00', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + 'four thousand, seven hundred and seventy-eight naira and' + ' zero kobo') + + self.assertEqual( + num2words( + '1.1', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + "one naira and ten kobo" + ) + + self.assertEqual( + num2words( + '158.3', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + "one hundred and fifty-eight naira and thirty kobo" + ) + + self.assertEqual( + num2words( + '2000.00', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + "two thousand naira and zero kobo" + ) + + self.assertEqual( + num2words( + '4.01', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + "four naira and one kobo" + ) + + self.assertEqual( + num2words( + '2000.00', + lang=language, + to='currency', + separator=separator, + kobo=True + ), + "two thousand naira and zero kobo" + ) diff --git a/tests/test_eo.py b/tests/test_eo.py new file mode 100644 index 00000000..64076cee --- /dev/null +++ b/tests/test_eo.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021, 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 + +from unittest import TestCase + +from num2words import num2words + +TEST_CASES_CARDINAL = ( + (1, "unu"), + (2, "du"), + (3, "tri"), + (5.5, "kvin komo kvin"), + (11, "dek unu"), + (12, "dek du"), + (16, "dek ses"), + (17.42, "dek sep komo kvar du"), + (19, "dek naŭ"), + (20, "dudek"), + (21, "dudek unu"), + (26, "dudek ses"), + (27.312, "dudek sep komo tri unu du"), + (28, "dudek ok"), + (30, "tridek"), + (31, "tridek unu"), + (40, "kvardek"), + (44, "kvardek kvar"), + (50, "kvindek"), + (53.486, "kvindek tri komo kvar ok ses"), + (55, "kvindek kvin"), + (60, "sesdek"), + (67, "sesdek sep"), + (70, "sepdek"), + (79, "sepdek naŭ"), + (89, "okdek naŭ"), + (95, "naŭdek kvin"), + (100, "cent"), + (101, "cent unu"), + (199, "cent naŭdek naŭ"), + (203, "ducent tri"), + (287, "ducent okdek sep"), + (300.42, "tricent komo kvar du"), + (356, "tricent kvindek ses"), + (400, "kvarcent"), + (434, "kvarcent tridek kvar"), + (578, "kvincent sepdek ok"), + (689, "sescent okdek naŭ"), + (729, "sepcent dudek naŭ"), + (894, "okcent naŭdek kvar"), + (999, "naŭcent naŭdek naŭ"), + (1000, "mil"), + (1001, "mil unu"), + (1097, "mil naŭdek sep"), + (1104, "mil cent kvar"), + (1243, "mil ducent kvardek tri"), + (2385, "du mil tricent okdek kvin"), + (3766, "tri mil sepcent sesdek ses"), + (4196, "kvar mil cent naŭdek ses"), + (4196.42, "kvar mil cent naŭdek ses komo kvar du"), + (5846, "kvin mil okcent kvardek ses"), + (6459, "ses mil kvarcent kvindek naŭ"), + (7232, "sep mil ducent tridek du"), + (8569, "ok mil kvincent sesdek naŭ"), + (9539, "naŭ mil kvincent tridek naŭ"), + (1000000, "unu miliono"), + (1000001, "unu miliono unu"), + (4000000, "kvar milionoj"), + (4000004, "kvar milionoj kvar"), + (4300000, "kvar milionoj tricent mil"), + (80000000, "okdek milionoj"), + (300000000, "tricent milionoj"), + (10000000000000, "dek bilionoj"), + (10000000000010, "dek bilionoj dek"), + (100000000000000, "cent bilionoj"), + (1000000000000000000, "unu triliono"), + (1000000000000000000000, "unu triliardo"), + (10000000000000000000000000, "dek kvarilionoj") +) + +TEST_CASES_ORDINAL = ( + (1, "unua"), + (8, "oka"), + (12, "dek dua"), + (14, "dek kvara"), + (28, "dudek oka"), + (100, "centa"), + (1000, "mila"), + (1000000, "unu miliona"), + (1000000000000000, "unu biliarda"), + (1000000000000000000, "unu triliona") +) + +TEST_CASES_ORDINAL_NUM = ( + (1, "1a"), + (8, "8a"), + (11, "11a"), + (12, "12a"), + (14, "14a"), + (21, "21a"), + (28, "28a"), + (100, "100a"), + (101, "101a"), + (1000, "1000a"), + (1000000, "1000000a") +) + +TEST_CASES_TO_CURRENCY_EUR = ( + (1.00, "unu eŭro kaj nul centimo"), + (2.01, "du eŭroj kaj unu centimo"), + (8.10, "ok eŭroj kaj dek centimoj"), + (12.26, "dek du eŭroj kaj dudek ses centimoj"), + (21.29, "dudek unu eŭroj kaj dudek naŭ centimoj"), + (81.25, "okdek unu eŭroj kaj dudek kvin centimoj"), + (100.00, "cent eŭroj kaj nul centimo"), +) + +TEST_CASES_TO_CURRENCY_FRF = ( + (1.00, "unu franko kaj nul centimo"), + (2.01, "du frankoj kaj unu centimo"), + (8.10, "ok frankoj kaj dek centimoj"), + (12.27, "dek du frankoj kaj dudek sep centimoj"), + (21.29, "dudek unu frankoj kaj dudek naŭ centimoj"), + (81.25, "okdek unu frankoj kaj dudek kvin centimoj"), + (100.00, "cent frankoj kaj nul centimo"), +) + +TEST_CASES_TO_CURRENCY_USD = ( + (1.00, "unu dolaro kaj nul cendo"), + (2.01, "du dolaroj kaj unu cendo"), + (8.10, "ok dolaroj kaj dek cendoj"), + (12.26, "dek du dolaroj kaj dudek ses cendoj"), + (21.29, "dudek unu dolaroj kaj dudek naŭ cendoj"), + (81.25, "okdek unu dolaroj kaj dudek kvin cendoj"), + (100.00, "cent dolaroj kaj nul cendo"), +) + + +class Num2WordsEOTest(TestCase): + def test_number(self): + for test in TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang="eo"), test[1]) + + def test_ordinal(self): + for test in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang="eo", ordinal=True), + test[1] + ) + + def test_ordinal_num(self): + for test in TEST_CASES_ORDINAL_NUM: + self.assertEqual( + num2words(test[0], lang="eo", to="ordinal_num"), + test[1] + ) + + def test_currency_eur(self): + for test in TEST_CASES_TO_CURRENCY_EUR: + self.assertEqual( + num2words(test[0], lang="eo", to="currency", currency="EUR"), + test[1] + ) + + def test_currency_frf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang="eo", to="currency", currency="FRF"), + test[1] + ) + + def test_currency_usd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang="eo", to="currency", currency="USD"), + test[1] + ) diff --git a/tests/test_errors.py b/tests/test_errors.py new file mode 100644 index 00000000..3b53c80a --- /dev/null +++ b/tests/test_errors.py @@ -0,0 +1,33 @@ +# -*- 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsErrorsTest(TestCase): + + def test_NotImplementedError(self): + with self.assertRaises(NotImplementedError): + num2words(100, lang="lalala") + + def test_types_NotImplementedError(self): + with self.assertRaises(NotImplementedError): + num2words(100, lang="en", to='babidibibidiboo!') diff --git a/tests/test_es.py b/tests/test_es.py index 3c576d1b..a2c1242b 100644 --- a/tests/test_es.py +++ b/tests/test_es.py @@ -28,7 +28,7 @@ (5.5, 'cinco punto cinco'), (11, 'once'), (12, 'doce'), - (16, 'dieciseis'), + (16, 'dieciséis'), (17.42, 'diecisiete punto cuatro dos'), (19, 'diecinueve'), (20, 'veinte'), @@ -95,6 +95,7 @@ (28, 'vigésimo octavo'), (100, 'centésimo'), (1000, 'milésimo'), + (12345, 'docemilésimo tricentésimo quadragésimo quinto'), (1000000, 'millonésimo'), (1000000000000000, 'cuadrillonésimo'), (1000000000000000000, 'un trillón') # over 1e18 is not supported @@ -112,47 +113,1706 @@ ) TEST_CASES_TO_CURRENCY = ( - (1.00, 'un euro con cero centimos'), - (2.00, 'dos euros con cero centimos'), - (8.00, 'ocho euros con cero centimos'), - (12.00, 'doce euros con cero centimos'), - (21.00, 'veintiun euros con cero centimos'), - (81.25, 'ochenta y un euros con veinticinco centimos'), - (350.90, 'trescientos cincuenta euros con noventa centimos'), - (100.00, 'cien euros con cero centimos'), + (1.00, 'un euro con cero céntimos'), + (1.01, 'un euro con un céntimo'), + (2.00, 'dos euros con cero céntimos'), + (8.00, 'ocho euros con cero céntimos'), + (12.00, 'doce euros con cero céntimos'), + (21.00, 'veintiún euros con cero céntimos'), + (81.25, 'ochenta y un euros con veinticinco céntimos'), + (350.90, 'trescientos cincuenta euros con noventa céntimos'), + (100.00, 'cien euros con cero céntimos'), ) TEST_CASES_TO_CURRENCY_ESP = ( - (1.00, 'un peseta con cero centimos'), - (2.00, 'dos pesetas con cero centimos'), - (8.00, 'ocho pesetas con cero centimos'), - (12.00, 'doce pesetas con cero centimos'), - (21.00, 'veintiun pesetas con cero centimos'), - (81.25, 'ochenta y un pesetas con veinticinco centimos'), - (350.90, 'trescientos cincuenta pesetas con noventa centimos'), - (100.00, 'cien pesetas con cero centimos'), + (1.00, 'una peseta con cero céntimos'), + (1.01, 'una peseta con un céntimo'), + (2.00, 'dos pesetas con cero céntimos'), + (8.00, 'ocho pesetas con cero céntimos'), + (12.00, 'doce pesetas con cero céntimos'), + (21.00, 'veintiuna pesetas con cero céntimos'), + (81.25, 'ochenta y una pesetas con veinticinco céntimos'), + (350.90, 'trescientas cincuenta pesetas con noventa céntimos'), + (100.00, 'cien pesetas con cero céntimos'), ) TEST_CASES_TO_CURRENCY_USD = ( - (1.00, 'un dolar con cero centavos'), - (2.00, 'dos dolares con cero centavos'), - (8.00, 'ocho dolares con cero centavos'), - (12.00, 'doce dolares con cero centavos'), - (21.00, 'veintiun dolares con cero centavos'), - (81.25, 'ochenta y un dolares con veinticinco centavos'), - (350.90, 'trescientos cincuenta dolares con noventa centavos'), - (100.00, 'cien dolares con cero centavos'), + (1.00, 'un dólar con cero centavos'), + (2.00, 'dos dólares con cero centavos'), + (8.00, 'ocho dólares con cero centavos'), + (12.00, 'doce dólares con cero centavos'), + (21.00, 'veintiún dólares con cero centavos'), + (81.25, 'ochenta y un dólares con veinticinco centavos'), + (350.90, 'trescientos cincuenta dólares con noventa centavos'), + (100.00, 'cien dólares con cero centavos'), ) TEST_CASES_TO_CURRENCY_PEN = ( - (1.00, 'un sol con cero centimos'), - (2.00, 'dos soles con cero centimos'), - (8.00, 'ocho soles con cero centimos'), - (12.00, 'doce soles con cero centimos'), - (21.00, 'veintiun soles con cero centimos'), - (81.25, 'ochenta y un soles con veinticinco centimos'), - (350.90, 'trescientos cincuenta soles con noventa centimos'), - (100.00, 'cien soles con cero centimos'), + (1.00, 'un sol con cero céntimos'), + (2.00, 'dos soles con cero céntimos'), + (8.00, 'ocho soles con cero céntimos'), + (12.00, 'doce soles con cero céntimos'), + (21.00, 'veintiún soles con cero céntimos'), + (81.25, 'ochenta y un soles con veinticinco céntimos'), + (350.90, 'trescientos cincuenta soles con noventa céntimos'), + (100.00, 'cien soles con cero céntimos'), +) + +TEST_CASES_TO_CURRENCY_CRC = ( + (1.00, 'un colón con cero centavos'), + (2.00, 'dos colones con cero centavos'), + (8.00, 'ocho colones con cero centavos'), + (12.00, 'doce colones con cero centavos'), + (21.00, 'veintiún colones con cero centavos'), + (81.25, 'ochenta y un colones con veinticinco centavos'), + (350.90, 'trescientos cincuenta colones con noventa centavos'), + (100.00, 'cien colones con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta colones con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_GBP = ( + (1.00, 'una libra con cero peniques'), + (1.01, 'una libra con un penique'), + (2.00, 'dos libras con cero peniques'), + (8.00, 'ocho libras con cero peniques'), + (12.00, 'doce libras con cero peniques'), + (21.00, 'veintiuna libras con cero peniques'), + (81.25, 'ochenta y una libras con veinticinco peniques'), + (350.90, 'trescientas cincuenta libras con noventa peniques'), + (100.00, 'cien libras con cero peniques'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres peniques'), +) + +TEST_CASES_TO_CURRENCY_RUB = ( + (1.00, 'un rublo con cero kopeykas'), + (2.00, 'dos rublos con cero kopeykas'), + (8.00, 'ocho rublos con cero kopeykas'), + (12.00, 'doce rublos con cero kopeykas'), + (21.00, 'veintiún rublos con cero kopeykas'), + (81.25, 'ochenta y un rublos con veinticinco kopeykas'), + (350.90, 'trescientos cincuenta rublos con noventa kopeykas'), + (100.00, 'cien rublos con cero kopeykas'), + (4150.83, + 'cuatro mil ciento cincuenta rublos con ochenta y tres kopeykas'), +) + +TEST_CASES_TO_CURRENCY_SEK = ( + (1.00, 'una corona con cero öre'), + (2.00, 'dos coronas con cero öre'), + (8.00, 'ocho coronas con cero öre'), + (12.00, 'doce coronas con cero öre'), + (21.00, 'veintiuna coronas con cero öre'), + (81.25, 'ochenta y una coronas con veinticinco öre'), + (350.90, 'trescientas cincuenta coronas con noventa öre'), + (100.00, 'cien coronas con cero öre'), + (4150.83, + 'cuatro mil ciento cincuenta coronas con ochenta y tres öre'), +) + +TEST_CASES_TO_CURRENCY_NOK = ( + (1.00, 'una corona con cero øre'), + (2.00, 'dos coronas con cero øre'), + (8.00, 'ocho coronas con cero øre'), + (12.00, 'doce coronas con cero øre'), + (21.00, 'veintiuna coronas con cero øre'), + (81.25, 'ochenta y una coronas con veinticinco øre'), + (350.90, 'trescientas cincuenta coronas con noventa øre'), + (100.00, 'cien coronas con cero øre'), + (4150.83, + 'cuatro mil ciento cincuenta coronas con ochenta y tres øre'), +) + +TEST_CASES_TO_CURRENCY_PLN = ( + (1.00, 'un zloty con cero groszy'), + (2.00, 'dos zlotys con cero groszy'), + (8.00, 'ocho zlotys con cero groszy'), + (12.00, 'doce zlotys con cero groszy'), + (21.00, 'veintiún zlotys con cero groszy'), + (81.25, 'ochenta y un zlotys con veinticinco groszy'), + (350.90, 'trescientos cincuenta zlotys con noventa groszy'), + (100.00, 'cien zlotys con cero groszy'), + (4150.83, + 'cuatro mil ciento cincuenta zlotys con ochenta y tres groszy'), +) + +TEST_CASES_TO_CURRENCY_MXN = ( + (1.00, 'un peso con cero centavos'), + (2.00, 'dos pesos con cero centavos'), + (8.00, 'ocho pesos con cero centavos'), + (12.00, 'doce pesos con cero centavos'), + (21.00, 'veintiún pesos con cero centavos'), + (81.25, 'ochenta y un pesos con veinticinco centavos'), + (350.90, 'trescientos cincuenta pesos con noventa centavos'), + (100.00, 'cien pesos con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta pesos con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_RON = ( + (1.00, 'un leu con cero bani'), + (2.00, 'dos leus con cero bani'), + (8.00, 'ocho leus con cero bani'), + (12.00, 'doce leus con cero bani'), + (21.00, 'veintiún leus con cero bani'), + (81.25, 'ochenta y un leus con veinticinco bani'), + (350.90, 'trescientos cincuenta leus con noventa bani'), + (100.00, 'cien leus con cero bani'), + (4150.83, + 'cuatro mil ciento cincuenta leus con ochenta y tres bani'), +) + +TEST_CASES_TO_CURRENCY_INR = ( + (1.00, 'una rupia con cero paisas'), + (2.00, 'dos rupias con cero paisas'), + (8.00, 'ocho rupias con cero paisas'), + (12.00, 'doce rupias con cero paisas'), + (21.00, 'veintiuna rupias con cero paisas'), + (81.25, 'ochenta y una rupias con veinticinco paisas'), + (350.90, 'trescientas cincuenta rupias con noventa paisas'), + (100.00, 'cien rupias con cero paisas'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres paisas'), +) + +TEST_CASES_TO_CURRENCY_HUF = ( + (1.00, 'un florín con cero fillér'), + (2.00, 'dos florines con cero fillér'), + (8.00, 'ocho florines con cero fillér'), + (12.00, 'doce florines con cero fillér'), + (21.00, 'veintiún florines con cero fillér'), + (81.25, 'ochenta y un florines con veinticinco fillér'), + (350.90, 'trescientos cincuenta florines con noventa fillér'), + (100.00, 'cien florines con cero fillér'), + (4150.83, + 'cuatro mil ciento cincuenta florines con ochenta y tres fillér'), +) + +TEST_CASES_TO_CURRENCY_FRF = ( + (1.00, 'un franco con cero céntimos'), + (2.00, 'dos francos con cero céntimos'), + (8.00, 'ocho francos con cero céntimos'), + (12.00, 'doce francos con cero céntimos'), + (21.00, 'veintiún francos con cero céntimos'), + (81.25, 'ochenta y un francos con veinticinco céntimos'), + (350.90, 'trescientos cincuenta francos con noventa céntimos'), + (100.00, 'cien francos con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta francos con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_CNY = ( + (1.00, 'un yuan con cero jiaos'), + (2.00, 'dos yuanes con cero jiaos'), + (8.00, 'ocho yuanes con cero jiaos'), + (12.00, 'doce yuanes con cero jiaos'), + (21.00, 'veintiún yuanes con cero jiaos'), + (81.25, 'ochenta y un yuanes con veinticinco jiaos'), + (350.90, 'trescientos cincuenta yuanes con noventa jiaos'), + (100.00, 'cien yuanes con cero jiaos'), + (4150.83, + 'cuatro mil ciento cincuenta yuanes con ochenta y tres jiaos'), +) + +TEST_CASES_TO_CURRENCY_CZK = ( + (1.00, 'una corona con cero haléř'), + (2.00, 'dos coronas con cero haléř'), + (8.00, 'ocho coronas con cero haléř'), + (12.00, 'doce coronas con cero haléř'), + (21.00, 'veintiuna coronas con cero haléř'), + (81.25, 'ochenta y una coronas con veinticinco haléř'), + (350.90, 'trescientas cincuenta coronas con noventa haléř'), + (100.00, 'cien coronas con cero haléř'), + (4150.83, + 'cuatro mil ciento cincuenta coronas con ochenta y tres haléř'), +) + +TEST_CASES_TO_CURRENCY_NIO = ( + (1.00, 'un córdoba con cero centavos'), + (2.00, 'dos córdobas con cero centavos'), + (8.00, 'ocho córdobas con cero centavos'), + (12.00, 'doce córdobas con cero centavos'), + (21.00, 'veintiún córdobas con cero centavos'), + (81.25, 'ochenta y un córdobas con veinticinco centavos'), + (350.90, 'trescientos cincuenta córdobas con noventa centavos'), + (100.00, 'cien córdobas con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta córdobas con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_VES = ( + (1.00, 'un bolívar con cero céntimos'), + (2.00, 'dos bolívares con cero céntimos'), + (8.00, 'ocho bolívares con cero céntimos'), + (12.00, 'doce bolívares con cero céntimos'), + (21.00, 'veintiún bolívares con cero céntimos'), + (81.25, 'ochenta y un bolívares con veinticinco céntimos'), + (350.90, 'trescientos cincuenta bolívares con noventa céntimos'), + (100.00, 'cien bolívares con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta bolívares con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_BRL = ( + (1.00, 'un real con cero centavos'), + (2.00, 'dos reales con cero centavos'), + (8.00, 'ocho reales con cero centavos'), + (12.00, 'doce reales con cero centavos'), + (21.00, 'veintiún reales con cero centavos'), + (81.25, 'ochenta y un reales con veinticinco centavos'), + (350.90, 'trescientos cincuenta reales con noventa centavos'), + (100.00, 'cien reales con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta reales con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_JPY = ( + (1.00, 'un yen con cero sen'), + (2.00, 'dos yenes con cero sen'), + (8.00, 'ocho yenes con cero sen'), + (12.00, 'doce yenes con cero sen'), + (21.00, 'veintiún yenes con cero sen'), + (81.25, 'ochenta y un yenes con veinticinco sen'), + (350.90, 'trescientos cincuenta yenes con noventa sen'), + (100.00, 'cien yenes con cero sen'), + (4150.83, + 'cuatro mil ciento cincuenta yenes con ochenta y tres sen'), +) + +TEST_CASES_TO_CURRENCY_KRW = ( + (1.00, 'un won con cero jeon'), + (2.00, 'dos wones con cero jeon'), + (8.00, 'ocho wones con cero jeon'), + (12.00, 'doce wones con cero jeon'), + (21.00, 'veintiún wones con cero jeon'), + (81.25, 'ochenta y un wones con veinticinco jeon'), + (350.90, 'trescientos cincuenta wones con noventa jeon'), + (100.00, 'cien wones con cero jeon'), + (4150.83, + 'cuatro mil ciento cincuenta wones con ochenta y tres jeon'), +) + +TEST_CASES_TO_CURRENCY_KPW = ( + (1.00, 'un won con cero chon'), + (2.00, 'dos wones con cero chon'), + (8.00, 'ocho wones con cero chon'), + (12.00, 'doce wones con cero chon'), + (21.00, 'veintiún wones con cero chon'), + (81.25, 'ochenta y un wones con veinticinco chon'), + (350.90, 'trescientos cincuenta wones con noventa chon'), + (100.00, 'cien wones con cero chon'), + (4150.83, + 'cuatro mil ciento cincuenta wones con ochenta y tres chon'), +) + +TEST_CASES_TO_CURRENCY_TRY = ( + (1.00, 'una lira con cero kuruş'), + (2.00, 'dos liras con cero kuruş'), + (8.00, 'ocho liras con cero kuruş'), + (12.00, 'doce liras con cero kuruş'), + (21.00, 'veintiuna liras con cero kuruş'), + (81.25, 'ochenta y una liras con veinticinco kuruş'), + (350.90, 'trescientas cincuenta liras con noventa kuruş'), + (100.00, 'cien liras con cero kuruş'), + (4150.83, + 'cuatro mil ciento cincuenta liras con ochenta y tres kuruş'), +) + +TEST_CASES_TO_CURRENCY_ZAR = ( + (1.00, 'un rand con cero céntimos'), + (2.00, 'dos rands con cero céntimos'), + (8.00, 'ocho rands con cero céntimos'), + (12.00, 'doce rands con cero céntimos'), + (21.00, 'veintiún rands con cero céntimos'), + (81.25, 'ochenta y un rands con veinticinco céntimos'), + (350.90, 'trescientos cincuenta rands con noventa céntimos'), + (100.00, 'cien rands con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta rands con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_KZT = ( + (1.00, 'un tenge con cero tïın'), + (2.00, 'dos tenges con cero tïın'), + (8.00, 'ocho tenges con cero tïın'), + (12.00, 'doce tenges con cero tïın'), + (21.00, 'veintiún tenges con cero tïın'), + (81.25, 'ochenta y un tenges con veinticinco tïın'), + (350.90, 'trescientos cincuenta tenges con noventa tïın'), + (100.00, 'cien tenges con cero tïın'), + (4150.83, + 'cuatro mil ciento cincuenta tenges con ochenta y tres tïın'), +) + +TEST_CASES_TO_CURRENCY_UAH = ( + (1.00, 'un hryvnia con cero kopiykas'), + (2.00, 'dos hryvnias con cero kopiykas'), + (8.00, 'ocho hryvnias con cero kopiykas'), + (12.00, 'doce hryvnias con cero kopiykas'), + (21.00, 'veintiún hryvnias con cero kopiykas'), + (81.25, 'ochenta y un hryvnias con veinticinco kopiykas'), + (350.90, 'trescientos cincuenta hryvnias con noventa kopiykas'), + (100.00, 'cien hryvnias con cero kopiykas'), + (4150.83, + 'cuatro mil ciento cincuenta hryvnias con ochenta y tres kopiykas'), +) + +TEST_CASES_TO_CURRENCY_THB = ( + (1.00, 'un baht con cero satang'), + (2.00, 'dos bahts con cero satang'), + (8.00, 'ocho bahts con cero satang'), + (12.00, 'doce bahts con cero satang'), + (21.00, 'veintiún bahts con cero satang'), + (81.25, 'ochenta y un bahts con veinticinco satang'), + (350.90, 'trescientos cincuenta bahts con noventa satang'), + (100.00, 'cien bahts con cero satang'), + (4150.83, + 'cuatro mil ciento cincuenta bahts con ochenta y tres satang'), +) + +TEST_CASES_TO_CURRENCY_AED = ( + (1.00, 'un dirham con cero fils'), + (2.00, 'dos dirhams con cero fils'), + (8.00, 'ocho dirhams con cero fils'), + (12.00, 'doce dirhams con cero fils'), + (21.00, 'veintiún dirhams con cero fils'), + (81.25, 'ochenta y un dirhams con veinticinco fils'), + (350.90, 'trescientos cincuenta dirhams con noventa fils'), + (100.00, 'cien dirhams con cero fils'), + (4150.83, + 'cuatro mil ciento cincuenta dirhams con ochenta y tres fils'), +) + +TEST_CASES_TO_CURRENCY_AFN = ( + (1.00, 'un afghani con cero puls'), + (2.00, 'dos afghanis con cero puls'), + (8.00, 'ocho afghanis con cero puls'), + (12.00, 'doce afghanis con cero puls'), + (21.00, 'veintiún afghanis con cero puls'), + (81.25, 'ochenta y un afghanis con veinticinco puls'), + (350.90, 'trescientos cincuenta afghanis con noventa puls'), + (100.00, 'cien afghanis con cero puls'), + (4150.83, + 'cuatro mil ciento cincuenta afghanis con ochenta y tres puls'), +) + +TEST_CASES_TO_CURRENCY_ALL = ( + (1.00, 'un lek con cero qindarka'), + (2.00, 'dos leke con cero qindarka'), + (8.00, 'ocho leke con cero qindarka'), + (12.00, 'doce leke con cero qindarka'), + (21.00, 'veintiún leke con cero qindarka'), + (81.25, 'ochenta y un leke con veinticinco qindarka'), + (350.90, 'trescientos cincuenta leke con noventa qindarka'), + (100.00, 'cien leke con cero qindarka'), + (4150.83, + 'cuatro mil ciento cincuenta leke con ochenta y tres qindarka'), +) + +TEST_CASES_TO_CURRENCY_AMD = ( + (1.00, 'un dram con cero lumas'), + (2.00, 'dos drams con cero lumas'), + (8.00, 'ocho drams con cero lumas'), + (12.00, 'doce drams con cero lumas'), + (21.00, 'veintiún drams con cero lumas'), + (81.25, 'ochenta y un drams con veinticinco lumas'), + (350.90, 'trescientos cincuenta drams con noventa lumas'), + (100.00, 'cien drams con cero lumas'), + (4150.83, + 'cuatro mil ciento cincuenta drams con ochenta y tres lumas'), +) + +TEST_CASES_TO_CURRENCY_ANG = ( + (1.00, 'un florín con cero centavos'), + (2.00, 'dos florines con cero centavos'), + (8.00, 'ocho florines con cero centavos'), + (12.00, 'doce florines con cero centavos'), + (21.00, 'veintiún florines con cero centavos'), + (81.25, 'ochenta y un florines con veinticinco centavos'), + (350.90, 'trescientos cincuenta florines con noventa centavos'), + (100.00, 'cien florines con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta florines con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_AOA = ( + (1.00, 'un kwanza con cero céntimos'), + (2.00, 'dos kwanzas con cero céntimos'), + (8.00, 'ocho kwanzas con cero céntimos'), + (12.00, 'doce kwanzas con cero céntimos'), + (21.00, 'veintiún kwanzas con cero céntimos'), + (81.25, 'ochenta y un kwanzas con veinticinco céntimos'), + (350.90, 'trescientos cincuenta kwanzas con noventa céntimos'), + (100.00, 'cien kwanzas con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta kwanzas con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_AWG = ( + (1.00, 'un florín con cero centavos'), + (2.00, 'dos florines con cero centavos'), + (8.00, 'ocho florines con cero centavos'), + (12.00, 'doce florines con cero centavos'), + (21.00, 'veintiún florines con cero centavos'), + (81.25, 'ochenta y un florines con veinticinco centavos'), + (350.90, 'trescientos cincuenta florines con noventa centavos'), + (100.00, 'cien florines con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta florines con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_AZN = ( + (1.00, 'un manat con cero qəpik'), + (2.00, 'dos manat con cero qəpik'), + (8.00, 'ocho manat con cero qəpik'), + (12.00, 'doce manat con cero qəpik'), + (21.00, 'veintiún manat con cero qəpik'), + (81.25, 'ochenta y un manat con veinticinco qəpik'), + (350.90, 'trescientos cincuenta manat con noventa qəpik'), + (100.00, 'cien manat con cero qəpik'), + (4150.83, + 'cuatro mil ciento cincuenta manat con ochenta y tres qəpik'), +) + +TEST_CASES_TO_CURRENCY_BDT = ( + (1.00, 'un taka con cero paisas'), + (2.00, 'dos takas con cero paisas'), + (8.00, 'ocho takas con cero paisas'), + (12.00, 'doce takas con cero paisas'), + (21.00, 'veintiún takas con cero paisas'), + (81.25, 'ochenta y un takas con veinticinco paisas'), + (350.90, 'trescientos cincuenta takas con noventa paisas'), + (100.00, 'cien takas con cero paisas'), + (4150.83, + 'cuatro mil ciento cincuenta takas con ochenta y tres paisas'), +) + +TEST_CASES_TO_CURRENCY_BGN = ( + (1.00, 'un lev con cero stotinki'), + (2.00, 'dos leva con cero stotinki'), + (8.00, 'ocho leva con cero stotinki'), + (12.00, 'doce leva con cero stotinki'), + (21.00, 'veintiún leva con cero stotinki'), + (81.25, 'ochenta y un leva con veinticinco stotinki'), + (350.90, 'trescientos cincuenta leva con noventa stotinki'), + (100.00, 'cien leva con cero stotinki'), + (4150.83, + 'cuatro mil ciento cincuenta leva con ochenta y tres stotinki'), +) + +TEST_CASES_TO_CURRENCY_BHD = ( + (1.00, 'un dinar con cero fils'), + (2.00, 'dos dinares con cero fils'), + (8.00, 'ocho dinares con cero fils'), + (12.00, 'doce dinares con cero fils'), + (21.00, 'veintiún dinares con cero fils'), + (81.25, 'ochenta y un dinares con veinticinco fils'), + (350.90, 'trescientos cincuenta dinares con noventa fils'), + (100.00, 'cien dinares con cero fils'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres fils'), +) + +TEST_CASES_TO_CURRENCY_BOB = ( + (1.00, 'un boliviano con cero centavos'), + (2.00, 'dos bolivianos con cero centavos'), + (8.00, 'ocho bolivianos con cero centavos'), + (12.00, 'doce bolivianos con cero centavos'), + (21.00, 'veintiún bolivianos con cero centavos'), + (81.25, 'ochenta y un bolivianos con veinticinco centavos'), + (350.90, 'trescientos cincuenta bolivianos con noventa centavos'), + (100.00, 'cien bolivianos con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta bolivianos con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_BTN = ( + (1.00, 'un ngultrum con cero chetrum'), + (2.00, 'dos ngultrum con cero chetrum'), + (8.00, 'ocho ngultrum con cero chetrum'), + (12.00, 'doce ngultrum con cero chetrum'), + (21.00, 'veintiún ngultrum con cero chetrum'), + (81.25, 'ochenta y un ngultrum con veinticinco chetrum'), + (350.90, 'trescientos cincuenta ngultrum con noventa chetrum'), + (100.00, 'cien ngultrum con cero chetrum'), + (4150.83, + 'cuatro mil ciento cincuenta ngultrum con ochenta y tres chetrum'), +) + +TEST_CASES_TO_CURRENCY_BWP = ( + (1.00, 'un pula con cero thebes'), + (2.00, 'dos pulas con cero thebes'), + (8.00, 'ocho pulas con cero thebes'), + (12.00, 'doce pulas con cero thebes'), + (21.00, 'veintiún pulas con cero thebes'), + (81.25, 'ochenta y un pulas con veinticinco thebes'), + (350.90, 'trescientos cincuenta pulas con noventa thebes'), + (100.00, 'cien pulas con cero thebes'), + (4150.83, + 'cuatro mil ciento cincuenta pulas con ochenta y tres thebes'), +) + +TEST_CASES_TO_CURRENCY_BYN = ( + (1.00, 'un rublo con cero kópeks'), + (2.00, 'dos rublos con cero kópeks'), + (8.00, 'ocho rublos con cero kópeks'), + (12.00, 'doce rublos con cero kópeks'), + (21.00, 'veintiún rublos con cero kópeks'), + (81.25, 'ochenta y un rublos con veinticinco kópeks'), + (350.90, 'trescientos cincuenta rublos con noventa kópeks'), + (100.00, 'cien rublos con cero kópeks'), + (4150.83, + 'cuatro mil ciento cincuenta rublos con ochenta y tres kópeks'), +) + +TEST_CASES_TO_CURRENCY_BYR = ( + (1.00, 'un rublo con cero kópeks'), + (2.00, 'dos rublos con cero kópeks'), + (8.00, 'ocho rublos con cero kópeks'), + (12.00, 'doce rublos con cero kópeks'), + (21.00, 'veintiún rublos con cero kópeks'), + (81.25, 'ochenta y un rublos con veinticinco kópeks'), + (350.90, 'trescientos cincuenta rublos con noventa kópeks'), + (100.00, 'cien rublos con cero kópeks'), + (4150.83, + 'cuatro mil ciento cincuenta rublos con ochenta y tres kópeks'), +) + +TEST_CASES_TO_CURRENCY_BZD = ( + (1.00, 'un dólar con cero céntimos'), + (2.00, 'dos dólares con cero céntimos'), + (8.00, 'ocho dólares con cero céntimos'), + (12.00, 'doce dólares con cero céntimos'), + (21.00, 'veintiún dólares con cero céntimos'), + (81.25, 'ochenta y un dólares con veinticinco céntimos'), + (350.90, 'trescientos cincuenta dólares con noventa céntimos'), + (100.00, 'cien dólares con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta dólares con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_CVE = ( + (1.00, 'un escudo con cero centavos'), + (2.00, 'dos escudos con cero centavos'), + (8.00, 'ocho escudos con cero centavos'), + (12.00, 'doce escudos con cero centavos'), + (21.00, 'veintiún escudos con cero centavos'), + (81.25, 'ochenta y un escudos con veinticinco centavos'), + (350.90, 'trescientos cincuenta escudos con noventa centavos'), + (100.00, 'cien escudos con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta escudos con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_CYP = ( + (1.00, 'una libra con cero céntimos'), + (2.00, 'dos libras con cero céntimos'), + (8.00, 'ocho libras con cero céntimos'), + (12.00, 'doce libras con cero céntimos'), + (21.00, 'veintiuna libras con cero céntimos'), + (81.25, 'ochenta y una libras con veinticinco céntimos'), + (350.90, 'trescientas cincuenta libras con noventa céntimos'), + (100.00, 'cien libras con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_DKK = ( + (1.00, 'una corona con cero øre'), + (2.00, 'dos coronas con cero øre'), + (8.00, 'ocho coronas con cero øre'), + (12.00, 'doce coronas con cero øre'), + (21.00, 'veintiuna coronas con cero øre'), + (81.25, 'ochenta y una coronas con veinticinco øre'), + (350.90, 'trescientas cincuenta coronas con noventa øre'), + (100.00, 'cien coronas con cero øre'), + (4150.83, + 'cuatro mil ciento cincuenta coronas con ochenta y tres øre'), +) + +TEST_CASES_TO_CURRENCY_DZD = ( + (1.00, 'un dinar con cero céntimos'), + (2.00, 'dos dinares con cero céntimos'), + (8.00, 'ocho dinares con cero céntimos'), + (12.00, 'doce dinares con cero céntimos'), + (21.00, 'veintiún dinares con cero céntimos'), + (81.25, 'ochenta y un dinares con veinticinco céntimos'), + (350.90, 'trescientos cincuenta dinares con noventa céntimos'), + (100.00, 'cien dinares con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_ECS = ( + (1.00, 'un sucre con cero centavos'), + (2.00, 'dos sucres con cero centavos'), + (8.00, 'ocho sucres con cero centavos'), + (12.00, 'doce sucres con cero centavos'), + (21.00, 'veintiún sucres con cero centavos'), + (81.25, 'ochenta y un sucres con veinticinco centavos'), + (350.90, 'trescientos cincuenta sucres con noventa centavos'), + (100.00, 'cien sucres con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta sucres con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_EGP = ( + (1.00, 'una libra con cero piastras'), + (2.00, 'dos libras con cero piastras'), + (8.00, 'ocho libras con cero piastras'), + (12.00, 'doce libras con cero piastras'), + (21.00, 'veintiuna libras con cero piastras'), + (81.21, 'ochenta y una libras con veintiuna piastras'), + (81.25, 'ochenta y una libras con veinticinco piastras'), + (350.90, 'trescientas cincuenta libras con noventa piastras'), + (100.00, 'cien libras con cero piastras'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres piastras'), +) + +TEST_CASES_TO_CURRENCY_ERN = ( + (1.00, 'un nakfa con cero céntimos'), + (2.00, 'dos nakfas con cero céntimos'), + (8.00, 'ocho nakfas con cero céntimos'), + (12.00, 'doce nakfas con cero céntimos'), + (21.00, 'veintiún nakfas con cero céntimos'), + (81.25, 'ochenta y un nakfas con veinticinco céntimos'), + (350.90, 'trescientos cincuenta nakfas con noventa céntimos'), + (100.00, 'cien nakfas con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta nakfas con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_ETB = ( + (1.00, 'un birr con cero céntimos'), + (2.00, 'dos birrs con cero céntimos'), + (8.00, 'ocho birrs con cero céntimos'), + (12.00, 'doce birrs con cero céntimos'), + (21.00, 'veintiún birrs con cero céntimos'), + (81.25, 'ochenta y un birrs con veinticinco céntimos'), + (350.90, 'trescientos cincuenta birrs con noventa céntimos'), + (100.00, 'cien birrs con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta birrs con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_FKP = ( + (1.00, 'una libra con cero peniques'), + (2.00, 'dos libras con cero peniques'), + (8.00, 'ocho libras con cero peniques'), + (12.00, 'doce libras con cero peniques'), + (21.00, 'veintiuna libras con cero peniques'), + (81.25, 'ochenta y una libras con veinticinco peniques'), + (350.90, 'trescientas cincuenta libras con noventa peniques'), + (100.00, 'cien libras con cero peniques'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres peniques'), +) + +TEST_CASES_TO_CURRENCY_GEL = ( + (1.00, 'un lari con cero tetris'), + (2.00, 'dos laris con cero tetris'), + (8.00, 'ocho laris con cero tetris'), + (12.00, 'doce laris con cero tetris'), + (21.00, 'veintiún laris con cero tetris'), + (81.25, 'ochenta y un laris con veinticinco tetris'), + (350.90, 'trescientos cincuenta laris con noventa tetris'), + (100.00, 'cien laris con cero tetris'), + (4150.83, + 'cuatro mil ciento cincuenta laris con ochenta y tres tetris'), +) + +TEST_CASES_TO_CURRENCY_GHS = ( + (1.00, 'un cedi con cero pesewas'), + (2.00, 'dos cedis con cero pesewas'), + (8.00, 'ocho cedis con cero pesewas'), + (12.00, 'doce cedis con cero pesewas'), + (21.00, 'veintiún cedis con cero pesewas'), + (81.25, 'ochenta y un cedis con veinticinco pesewas'), + (350.90, 'trescientos cincuenta cedis con noventa pesewas'), + (100.00, 'cien cedis con cero pesewas'), + (4150.83, + 'cuatro mil ciento cincuenta cedis con ochenta y tres pesewas'), +) + +TEST_CASES_TO_CURRENCY_GMD = ( + (1.00, 'un dalasi con cero bututs'), + (2.00, 'dos dalasis con cero bututs'), + (8.00, 'ocho dalasis con cero bututs'), + (12.00, 'doce dalasis con cero bututs'), + (21.00, 'veintiún dalasis con cero bututs'), + (81.25, 'ochenta y un dalasis con veinticinco bututs'), + (350.90, 'trescientos cincuenta dalasis con noventa bututs'), + (100.00, 'cien dalasis con cero bututs'), + (4150.83, + 'cuatro mil ciento cincuenta dalasis con ochenta y tres bututs'), +) + +TEST_CASES_TO_CURRENCY_GTQ = ( + (1.00, 'un quetzal con cero centavos'), + (2.00, 'dos quetzales con cero centavos'), + (8.00, 'ocho quetzales con cero centavos'), + (12.00, 'doce quetzales con cero centavos'), + (21.00, 'veintiún quetzales con cero centavos'), + (81.25, 'ochenta y un quetzales con veinticinco centavos'), + (350.90, 'trescientos cincuenta quetzales con noventa centavos'), + (100.00, 'cien quetzales con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta quetzales con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_HNL = ( + (1.00, 'un lempira con cero centavos'), + (2.00, 'dos lempiras con cero centavos'), + (8.00, 'ocho lempiras con cero centavos'), + (12.00, 'doce lempiras con cero centavos'), + (21.00, 'veintiún lempiras con cero centavos'), + (81.25, 'ochenta y un lempiras con veinticinco centavos'), + (350.90, 'trescientos cincuenta lempiras con noventa centavos'), + (100.00, 'cien lempiras con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta lempiras con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_HRK = ( + (1.00, 'un kuna con cero lipas'), + (2.00, 'dos kunas con cero lipas'), + (8.00, 'ocho kunas con cero lipas'), + (12.00, 'doce kunas con cero lipas'), + (21.00, 'veintiún kunas con cero lipas'), + (81.25, 'ochenta y un kunas con veinticinco lipas'), + (350.90, 'trescientos cincuenta kunas con noventa lipas'), + (100.00, 'cien kunas con cero lipas'), + (4150.83, + 'cuatro mil ciento cincuenta kunas con ochenta y tres lipas'), +) + +TEST_CASES_TO_CURRENCY_HTG = ( + (1.00, 'un gourde con cero céntimos'), + (2.00, 'dos gourdes con cero céntimos'), + (8.00, 'ocho gourdes con cero céntimos'), + (12.00, 'doce gourdes con cero céntimos'), + (21.00, 'veintiún gourdes con cero céntimos'), + (81.25, 'ochenta y un gourdes con veinticinco céntimos'), + (350.90, 'trescientos cincuenta gourdes con noventa céntimos'), + (100.00, 'cien gourdes con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta gourdes con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_IDR = ( + (1.00, 'una rupia con cero céntimos'), + (2.00, 'dos rupias con cero céntimos'), + (8.00, 'ocho rupias con cero céntimos'), + (12.00, 'doce rupias con cero céntimos'), + (21.00, 'veintiuna rupias con cero céntimos'), + (81.25, 'ochenta y una rupias con veinticinco céntimos'), + (350.90, 'trescientas cincuenta rupias con noventa céntimos'), + (100.00, 'cien rupias con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_ILS = ( + (1.00, 'un séquel con cero agoras'), + (2.00, 'dos séqueles con cero agoras'), + (8.00, 'ocho séqueles con cero agoras'), + (12.00, 'doce séqueles con cero agoras'), + (21.00, 'veintiún séqueles con cero agoras'), + (81.25, 'ochenta y un séqueles con veinticinco agoras'), + (350.90, 'trescientos cincuenta séqueles con noventa agoras'), + (100.00, 'cien séqueles con cero agoras'), + (4150.83, + 'cuatro mil ciento cincuenta séqueles con ochenta y tres agoras'), +) + +TEST_CASES_TO_CURRENCY_IQD = ( + (1.00, 'un dinar con cero fils'), + (2.00, 'dos dinares con cero fils'), + (8.00, 'ocho dinares con cero fils'), + (12.00, 'doce dinares con cero fils'), + (21.00, 'veintiún dinares con cero fils'), + (81.25, 'ochenta y un dinares con veinticinco fils'), + (350.90, 'trescientos cincuenta dinares con noventa fils'), + (100.00, 'cien dinares con cero fils'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres fils'), +) + +TEST_CASES_TO_CURRENCY_IRR = ( + (1.00, 'un rial con cero dinares'), + (2.00, 'dos riales con cero dinares'), + (8.00, 'ocho riales con cero dinares'), + (12.00, 'doce riales con cero dinares'), + (21.00, 'veintiún riales con cero dinares'), + (81.25, 'ochenta y un riales con veinticinco dinares'), + (350.90, 'trescientos cincuenta riales con noventa dinares'), + (100.00, 'cien riales con cero dinares'), + (4150.83, + 'cuatro mil ciento cincuenta riales con ochenta y tres dinares'), +) + +TEST_CASES_TO_CURRENCY_ISK = ( + (1.00, 'una corona con cero aurar'), + (2.00, 'dos coronas con cero aurar'), + (8.00, 'ocho coronas con cero aurar'), + (12.00, 'doce coronas con cero aurar'), + (21.00, 'veintiuna coronas con cero aurar'), + (81.25, 'ochenta y una coronas con veinticinco aurar'), + (350.90, 'trescientas cincuenta coronas con noventa aurar'), + (100.00, 'cien coronas con cero aurar'), + (4150.83, + 'cuatro mil ciento cincuenta coronas con ochenta y tres aurar'), +) + +TEST_CASES_TO_CURRENCY_ITL = ( + (1.00, 'una lira con cero céntimos'), + (2.00, 'dos liras con cero céntimos'), + (8.00, 'ocho liras con cero céntimos'), + (12.00, 'doce liras con cero céntimos'), + (21.00, 'veintiuna liras con cero céntimos'), + (81.25, 'ochenta y una liras con veinticinco céntimos'), + (350.90, 'trescientas cincuenta liras con noventa céntimos'), + (100.00, 'cien liras con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta liras con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_JOD = ( + (1.00, 'un dinar con cero piastras'), + (2.00, 'dos dinares con cero piastras'), + (8.00, 'ocho dinares con cero piastras'), + (12.00, 'doce dinares con cero piastras'), + (21.00, 'veintiún dinares con cero piastras'), + (81.25, 'ochenta y un dinares con veinticinco piastras'), + (350.90, 'trescientos cincuenta dinares con noventa piastras'), + (100.00, 'cien dinares con cero piastras'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres piastras'), +) + +TEST_CASES_TO_CURRENCY_KES = ( + (1.00, 'un chelín con cero céntimos'), + (2.00, 'dos chelines con cero céntimos'), + (8.00, 'ocho chelines con cero céntimos'), + (12.00, 'doce chelines con cero céntimos'), + (21.00, 'veintiún chelines con cero céntimos'), + (81.25, 'ochenta y un chelines con veinticinco céntimos'), + (350.90, 'trescientos cincuenta chelines con noventa céntimos'), + (100.00, 'cien chelines con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta chelines con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_KGS = ( + (1.00, 'un som con cero tyiyn'), + (2.00, 'dos som con cero tyiyn'), + (8.00, 'ocho som con cero tyiyn'), + (12.00, 'doce som con cero tyiyn'), + (21.00, 'veintiún som con cero tyiyn'), + (81.25, 'ochenta y un som con veinticinco tyiyn'), + (350.90, 'trescientos cincuenta som con noventa tyiyn'), + (100.00, 'cien som con cero tyiyn'), + (4150.83, + 'cuatro mil ciento cincuenta som con ochenta y tres tyiyn'), +) + +TEST_CASES_TO_CURRENCY_KHR = ( + (1.00, 'un riel con cero céntimos'), + (2.00, 'dos rieles con cero céntimos'), + (8.00, 'ocho rieles con cero céntimos'), + (12.00, 'doce rieles con cero céntimos'), + (21.00, 'veintiún rieles con cero céntimos'), + (81.25, 'ochenta y un rieles con veinticinco céntimos'), + (350.90, 'trescientos cincuenta rieles con noventa céntimos'), + (100.00, 'cien rieles con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta rieles con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_KWD = ( + (1.00, 'un dinar con cero fils'), + (2.00, 'dos dinares con cero fils'), + (8.00, 'ocho dinares con cero fils'), + (12.00, 'doce dinares con cero fils'), + (21.00, 'veintiún dinares con cero fils'), + (81.25, 'ochenta y un dinares con veinticinco fils'), + (350.90, 'trescientos cincuenta dinares con noventa fils'), + (100.00, 'cien dinares con cero fils'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres fils'), +) + +TEST_CASES_TO_CURRENCY_LAK = ( + (1.00, 'un kip con cero att'), + (2.00, 'dos kips con cero att'), + (8.00, 'ocho kips con cero att'), + (12.00, 'doce kips con cero att'), + (21.00, 'veintiún kips con cero att'), + (81.25, 'ochenta y un kips con veinticinco att'), + (350.90, 'trescientos cincuenta kips con noventa att'), + (100.00, 'cien kips con cero att'), + (4150.83, + 'cuatro mil ciento cincuenta kips con ochenta y tres att'), +) + +TEST_CASES_TO_CURRENCY_LKR = ( + (1.00, 'una rupia con cero céntimos'), + (2.00, 'dos rupias con cero céntimos'), + (8.00, 'ocho rupias con cero céntimos'), + (12.00, 'doce rupias con cero céntimos'), + (21.00, 'veintiuna rupias con cero céntimos'), + (81.25, 'ochenta y una rupias con veinticinco céntimos'), + (350.90, 'trescientas cincuenta rupias con noventa céntimos'), + (100.00, 'cien rupias con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_LSL = ( + (1.00, 'un loti con cero céntimos'), + (2.00, 'dos lotis con cero céntimos'), + (8.00, 'ocho lotis con cero céntimos'), + (12.00, 'doce lotis con cero céntimos'), + (21.00, 'veintiún lotis con cero céntimos'), + (81.25, 'ochenta y un lotis con veinticinco céntimos'), + (350.90, 'trescientos cincuenta lotis con noventa céntimos'), + (100.00, 'cien lotis con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta lotis con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_LTL = ( + (1.00, 'un lita con cero céntimos'), + (2.00, 'dos litas con cero céntimos'), + (8.00, 'ocho litas con cero céntimos'), + (12.00, 'doce litas con cero céntimos'), + (21.00, 'veintiún litas con cero céntimos'), + (81.25, 'ochenta y un litas con veinticinco céntimos'), + (350.90, 'trescientos cincuenta litas con noventa céntimos'), + (100.00, 'cien litas con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta litas con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_LVL = ( + (1.00, 'un lat con cero céntimos'), + (2.00, 'dos lats con cero céntimos'), + (8.00, 'ocho lats con cero céntimos'), + (12.00, 'doce lats con cero céntimos'), + (21.00, 'veintiún lats con cero céntimos'), + (81.25, 'ochenta y un lats con veinticinco céntimos'), + (350.90, 'trescientos cincuenta lats con noventa céntimos'), + (100.00, 'cien lats con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta lats con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_LYD = ( + (1.00, 'un dinar con cero dírhams'), + (2.00, 'dos dinares con cero dírhams'), + (8.00, 'ocho dinares con cero dírhams'), + (12.00, 'doce dinares con cero dírhams'), + (21.00, 'veintiún dinares con cero dírhams'), + (81.25, 'ochenta y un dinares con veinticinco dírhams'), + (350.90, 'trescientos cincuenta dinares con noventa dírhams'), + (100.00, 'cien dinares con cero dírhams'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres dírhams'), +) + +TEST_CASES_TO_CURRENCY_MAD = ( + (1.00, 'un dírham con cero céntimos'), + (2.00, 'dos dirhams con cero céntimos'), + (8.00, 'ocho dirhams con cero céntimos'), + (12.00, 'doce dirhams con cero céntimos'), + (21.00, 'veintiún dirhams con cero céntimos'), + (81.25, 'ochenta y un dirhams con veinticinco céntimos'), + (350.90, 'trescientos cincuenta dirhams con noventa céntimos'), + (100.00, 'cien dirhams con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta dirhams con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_MDL = ( + (1.00, 'un leu con cero bani'), + (2.00, 'dos lei con cero bani'), + (8.00, 'ocho lei con cero bani'), + (12.00, 'doce lei con cero bani'), + (21.00, 'veintiún lei con cero bani'), + (81.25, 'ochenta y un lei con veinticinco bani'), + (350.90, 'trescientos cincuenta lei con noventa bani'), + (100.00, 'cien lei con cero bani'), + (4150.83, + 'cuatro mil ciento cincuenta lei con ochenta y tres bani'), +) + +TEST_CASES_TO_CURRENCY_MGA = ( + (1.00, 'un ariary con cero iraimbilanja'), + (2.00, 'dos ariaris con cero iraimbilanja'), + (8.00, 'ocho ariaris con cero iraimbilanja'), + (12.00, 'doce ariaris con cero iraimbilanja'), + (21.00, 'veintiún ariaris con cero iraimbilanja'), + (81.25, 'ochenta y un ariaris con veinticinco iraimbilanja'), + (350.90, 'trescientos cincuenta ariaris con noventa iraimbilanja'), + (100.00, 'cien ariaris con cero iraimbilanja'), + (4150.83, + 'cuatro mil ciento cincuenta ariaris con ochenta y tres iraimbilanja'), +) + +TEST_CASES_TO_CURRENCY_MKD = ( + (1.00, 'un denar con cero denis'), + (2.00, 'dos denares con cero denis'), + (8.00, 'ocho denares con cero denis'), + (12.00, 'doce denares con cero denis'), + (21.00, 'veintiún denares con cero denis'), + (81.25, 'ochenta y un denares con veinticinco denis'), + (350.90, 'trescientos cincuenta denares con noventa denis'), + (100.00, 'cien denares con cero denis'), + (4150.83, + 'cuatro mil ciento cincuenta denares con ochenta y tres denis'), +) + +TEST_CASES_TO_CURRENCY_MMK = ( + (1.00, 'un kiat con cero pyas'), + (2.00, 'dos kiats con cero pyas'), + (8.00, 'ocho kiats con cero pyas'), + (12.00, 'doce kiats con cero pyas'), + (21.00, 'veintiún kiats con cero pyas'), + (81.25, 'ochenta y un kiats con veinticinco pyas'), + (350.90, 'trescientos cincuenta kiats con noventa pyas'), + (100.00, 'cien kiats con cero pyas'), + (4150.83, + 'cuatro mil ciento cincuenta kiats con ochenta y tres pyas'), +) + +TEST_CASES_TO_CURRENCY_MNT = ( + (1.00, 'un tugrik con cero möngö'), + (2.00, 'dos tugriks con cero möngö'), + (8.00, 'ocho tugriks con cero möngö'), + (12.00, 'doce tugriks con cero möngö'), + (21.00, 'veintiún tugriks con cero möngö'), + (81.25, 'ochenta y un tugriks con veinticinco möngö'), + (350.90, 'trescientos cincuenta tugriks con noventa möngö'), + (100.00, 'cien tugriks con cero möngö'), + (4150.83, + 'cuatro mil ciento cincuenta tugriks con ochenta y tres möngö'), +) + +TEST_CASES_TO_CURRENCY_MOP = ( + (1.00, 'un pataca con cero avos'), + (2.00, 'dos patacas con cero avos'), + (8.00, 'ocho patacas con cero avos'), + (12.00, 'doce patacas con cero avos'), + (21.00, 'veintiún patacas con cero avos'), + (81.25, 'ochenta y un patacas con veinticinco avos'), + (350.90, 'trescientos cincuenta patacas con noventa avos'), + (100.00, 'cien patacas con cero avos'), + (4150.83, + 'cuatro mil ciento cincuenta patacas con ochenta y tres avos'), +) + +TEST_CASES_TO_CURRENCY_MRO = ( + (1.00, 'un ouguiya con cero khoums'), + (2.00, 'dos ouguiyas con cero khoums'), + (8.00, 'ocho ouguiyas con cero khoums'), + (12.00, 'doce ouguiyas con cero khoums'), + (21.00, 'veintiún ouguiyas con cero khoums'), + (81.25, 'ochenta y un ouguiyas con veinticinco khoums'), + (350.90, 'trescientos cincuenta ouguiyas con noventa khoums'), + (100.00, 'cien ouguiyas con cero khoums'), + (4150.83, + 'cuatro mil ciento cincuenta ouguiyas con ochenta y tres khoums'), +) + +TEST_CASES_TO_CURRENCY_MRU = ( + (1.00, 'un ouguiya con cero khoums'), + (2.00, 'dos ouguiyas con cero khoums'), + (8.00, 'ocho ouguiyas con cero khoums'), + (12.00, 'doce ouguiyas con cero khoums'), + (21.00, 'veintiún ouguiyas con cero khoums'), + (81.25, 'ochenta y un ouguiyas con veinticinco khoums'), + (350.90, 'trescientos cincuenta ouguiyas con noventa khoums'), + (100.00, 'cien ouguiyas con cero khoums'), + (4150.83, + 'cuatro mil ciento cincuenta ouguiyas con ochenta y tres khoums'), +) + +TEST_CASES_TO_CURRENCY_MUR = ( + (1.00, 'una rupia con cero céntimos'), + (2.00, 'dos rupias con cero céntimos'), + (8.00, 'ocho rupias con cero céntimos'), + (12.00, 'doce rupias con cero céntimos'), + (21.00, 'veintiuna rupias con cero céntimos'), + (81.25, 'ochenta y una rupias con veinticinco céntimos'), + (350.90, 'trescientas cincuenta rupias con noventa céntimos'), + (100.00, 'cien rupias con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_MVR = ( + (1.00, 'un rufiyaa con cero laari'), + (2.00, 'dos rufiyaas con cero laari'), + (8.00, 'ocho rufiyaas con cero laari'), + (12.00, 'doce rufiyaas con cero laari'), + (21.00, 'veintiún rufiyaas con cero laari'), + (81.25, 'ochenta y un rufiyaas con veinticinco laari'), + (350.90, 'trescientos cincuenta rufiyaas con noventa laari'), + (100.00, 'cien rufiyaas con cero laari'), + (4150.83, + 'cuatro mil ciento cincuenta rufiyaas con ochenta y tres laari'), +) + +TEST_CASES_TO_CURRENCY_MWK = ( + (1.00, 'un kuacha con cero tambalas'), + (2.00, 'dos kuachas con cero tambalas'), + (8.00, 'ocho kuachas con cero tambalas'), + (12.00, 'doce kuachas con cero tambalas'), + (21.00, 'veintiún kuachas con cero tambalas'), + (81.25, 'ochenta y un kuachas con veinticinco tambalas'), + (350.90, 'trescientos cincuenta kuachas con noventa tambalas'), + (100.00, 'cien kuachas con cero tambalas'), + (4150.83, + 'cuatro mil ciento cincuenta kuachas con ochenta y tres tambalas'), +) + +TEST_CASES_TO_CURRENCY_MYR = ( + (1.00, 'un ringgit con cero céntimos'), + (2.00, 'dos ringgit con cero céntimos'), + (8.00, 'ocho ringgit con cero céntimos'), + (12.00, 'doce ringgit con cero céntimos'), + (21.00, 'veintiún ringgit con cero céntimos'), + (81.25, 'ochenta y un ringgit con veinticinco céntimos'), + (350.90, 'trescientos cincuenta ringgit con noventa céntimos'), + (100.00, 'cien ringgit con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta ringgit con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_MZN = ( + (1.00, 'un metical con cero centavos'), + (2.00, 'dos metical con cero centavos'), + (8.00, 'ocho metical con cero centavos'), + (12.00, 'doce metical con cero centavos'), + (21.00, 'veintiún metical con cero centavos'), + (81.25, 'ochenta y un metical con veinticinco centavos'), + (350.90, 'trescientos cincuenta metical con noventa centavos'), + (100.00, 'cien metical con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta metical con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_NGN = ( + (1.00, 'un naira con cero kobo'), + (2.00, 'dos nairas con cero kobo'), + (8.00, 'ocho nairas con cero kobo'), + (12.00, 'doce nairas con cero kobo'), + (21.00, 'veintiún nairas con cero kobo'), + (81.25, 'ochenta y un nairas con veinticinco kobo'), + (350.90, 'trescientos cincuenta nairas con noventa kobo'), + (100.00, 'cien nairas con cero kobo'), + (4150.83, + 'cuatro mil ciento cincuenta nairas con ochenta y tres kobo'), +) + +TEST_CASES_TO_CURRENCY_NPR = ( + (1.00, 'una rupia con cero paisas'), + (2.00, 'dos rupias con cero paisas'), + (8.00, 'ocho rupias con cero paisas'), + (12.00, 'doce rupias con cero paisas'), + (21.00, 'veintiuna rupias con cero paisas'), + (81.25, 'ochenta y una rupias con veinticinco paisas'), + (350.90, 'trescientas cincuenta rupias con noventa paisas'), + (100.00, 'cien rupias con cero paisas'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres paisas'), +) + +TEST_CASES_TO_CURRENCY_OMR = ( + (1.00, 'un rial con cero baisa'), + (2.00, 'dos riales con cero baisa'), + (8.00, 'ocho riales con cero baisa'), + (12.00, 'doce riales con cero baisa'), + (21.00, 'veintiún riales con cero baisa'), + (81.25, 'ochenta y un riales con veinticinco baisa'), + (350.90, 'trescientos cincuenta riales con noventa baisa'), + (100.00, 'cien riales con cero baisa'), + (4150.83, + 'cuatro mil ciento cincuenta riales con ochenta y tres baisa'), +) + +TEST_CASES_TO_CURRENCY_PAB = ( + (1.00, 'un balboa con cero centésimos'), + (2.00, 'dos balboas con cero centésimos'), + (8.00, 'ocho balboas con cero centésimos'), + (12.00, 'doce balboas con cero centésimos'), + (21.00, 'veintiún balboas con cero centésimos'), + (81.25, 'ochenta y un balboas con veinticinco centésimos'), + (350.90, 'trescientos cincuenta balboas con noventa centésimos'), + (100.00, 'cien balboas con cero centésimos'), + (4150.83, + 'cuatro mil ciento cincuenta balboas con ochenta y tres centésimos'), +) + +TEST_CASES_TO_CURRENCY_PGK = ( + (1.00, 'un kina con cero toea'), + (2.00, 'dos kinas con cero toea'), + (8.00, 'ocho kinas con cero toea'), + (12.00, 'doce kinas con cero toea'), + (21.00, 'veintiún kinas con cero toea'), + (81.25, 'ochenta y un kinas con veinticinco toea'), + (350.90, 'trescientos cincuenta kinas con noventa toea'), + (100.00, 'cien kinas con cero toea'), + (4150.83, + 'cuatro mil ciento cincuenta kinas con ochenta y tres toea'), +) + +TEST_CASES_TO_CURRENCY_PKR = ( + (1.00, 'una rupia con cero paisas'), + (2.00, 'dos rupias con cero paisas'), + (8.00, 'ocho rupias con cero paisas'), + (12.00, 'doce rupias con cero paisas'), + (21.00, 'veintiuna rupias con cero paisas'), + (81.25, 'ochenta y una rupias con veinticinco paisas'), + (350.90, 'trescientas cincuenta rupias con noventa paisas'), + (100.00, 'cien rupias con cero paisas'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres paisas'), +) + +TEST_CASES_TO_CURRENCY_PLZ = ( + (1.00, 'un zloty con cero groszy'), + (2.00, 'dos zlotys con cero groszy'), + (8.00, 'ocho zlotys con cero groszy'), + (12.00, 'doce zlotys con cero groszy'), + (21.00, 'veintiún zlotys con cero groszy'), + (81.25, 'ochenta y un zlotys con veinticinco groszy'), + (350.90, 'trescientos cincuenta zlotys con noventa groszy'), + (100.00, 'cien zlotys con cero groszy'), + (4150.83, + 'cuatro mil ciento cincuenta zlotys con ochenta y tres groszy'), +) + +TEST_CASES_TO_CURRENCY_PYG = ( + (1.00, 'un guaraní con cero céntimos'), + (2.00, 'dos guaranís con cero céntimos'), + (8.00, 'ocho guaranís con cero céntimos'), + (12.00, 'doce guaranís con cero céntimos'), + (21.00, 'veintiún guaranís con cero céntimos'), + (81.25, 'ochenta y un guaranís con veinticinco céntimos'), + (350.90, 'trescientos cincuenta guaranís con noventa céntimos'), + (100.00, 'cien guaranís con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta guaranís con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_QAR = ( + (1.00, 'un rial con cero dírhams'), + (2.00, 'dos riales con cero dírhams'), + (8.00, 'ocho riales con cero dírhams'), + (12.00, 'doce riales con cero dírhams'), + (21.00, 'veintiún riales con cero dírhams'), + (81.25, 'ochenta y un riales con veinticinco dírhams'), + (350.90, 'trescientos cincuenta riales con noventa dírhams'), + (100.00, 'cien riales con cero dírhams'), + (4150.83, + 'cuatro mil ciento cincuenta riales con ochenta y tres dírhams'), +) + +TEST_CASES_TO_CURRENCY_RSD = ( + (1.00, 'un dinar con cero para'), + (2.00, 'dos dinares con cero para'), + (8.00, 'ocho dinares con cero para'), + (12.00, 'doce dinares con cero para'), + (21.00, 'veintiún dinares con cero para'), + (81.25, 'ochenta y un dinares con veinticinco para'), + (350.90, 'trescientos cincuenta dinares con noventa para'), + (100.00, 'cien dinares con cero para'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres para'), +) + +TEST_CASES_TO_CURRENCY_RUR = ( + (1.00, 'un rublo con cero kopeks'), + (2.00, 'dos rublos con cero kopeks'), + (8.00, 'ocho rublos con cero kopeks'), + (12.00, 'doce rublos con cero kopeks'), + (21.00, 'veintiún rublos con cero kopeks'), + (81.25, 'ochenta y un rublos con veinticinco kopeks'), + (350.90, 'trescientos cincuenta rublos con noventa kopeks'), + (100.00, 'cien rublos con cero kopeks'), + (4150.83, + 'cuatro mil ciento cincuenta rublos con ochenta y tres kopeks'), +) + +TEST_CASES_TO_CURRENCY_SAR = ( + (1.00, 'un riyal con cero halalas'), + (2.00, 'dos riales con cero halalas'), + (8.00, 'ocho riales con cero halalas'), + (12.00, 'doce riales con cero halalas'), + (21.00, 'veintiún riales con cero halalas'), + (81.25, 'ochenta y un riales con veinticinco halalas'), + (350.90, 'trescientos cincuenta riales con noventa halalas'), + (100.00, 'cien riales con cero halalas'), + (4150.83, + 'cuatro mil ciento cincuenta riales con ochenta y tres halalas'), +) + +TEST_CASES_TO_CURRENCY_SCR = ( + (1.00, 'una rupia con cero céntimos'), + (2.00, 'dos rupias con cero céntimos'), + (8.00, 'ocho rupias con cero céntimos'), + (12.00, 'doce rupias con cero céntimos'), + (21.00, 'veintiuna rupias con cero céntimos'), + (81.25, 'ochenta y una rupias con veinticinco céntimos'), + (350.90, 'trescientas cincuenta rupias con noventa céntimos'), + (100.00, 'cien rupias con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta rupias con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_SHP = ( + (1.00, 'una libra con cero peniques'), + (2.00, 'dos libras con cero peniques'), + (8.00, 'ocho libras con cero peniques'), + (12.00, 'doce libras con cero peniques'), + (21.00, 'veintiuna libras con cero peniques'), + (81.25, 'ochenta y una libras con veinticinco peniques'), + (350.90, 'trescientas cincuenta libras con noventa peniques'), + (100.00, 'cien libras con cero peniques'), + (4150.83, + 'cuatro mil ciento cincuenta libras con ochenta y tres peniques'), +) + +TEST_CASES_TO_CURRENCY_SKK = ( + (1.00, 'una corona con cero haliers'), + (2.00, 'dos coronas con cero haliers'), + (8.00, 'ocho coronas con cero haliers'), + (12.00, 'doce coronas con cero haliers'), + (21.00, 'veintiuna coronas con cero haliers'), + (81.25, 'ochenta y una coronas con veinticinco haliers'), + (350.90, 'trescientas cincuenta coronas con noventa haliers'), + (100.00, 'cien coronas con cero haliers'), + (4150.83, + 'cuatro mil ciento cincuenta coronas con ochenta y tres haliers'), +) + +TEST_CASES_TO_CURRENCY_SLL = ( + (1.00, 'una leona con cero céntimos'), + (2.00, 'dos leonas con cero céntimos'), + (8.00, 'ocho leonas con cero céntimos'), + (12.00, 'doce leonas con cero céntimos'), + (21.00, 'veintiuna leonas con cero céntimos'), + (81.25, 'ochenta y una leonas con veinticinco céntimos'), + (350.90, 'trescientas cincuenta leonas con noventa céntimos'), + (100.00, 'cien leonas con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta leonas con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_STD = ( + (1.00, 'un dobra con cero céntimos'), + (2.00, 'dos dobras con cero céntimos'), + (8.00, 'ocho dobras con cero céntimos'), + (12.00, 'doce dobras con cero céntimos'), + (21.00, 'veintiún dobras con cero céntimos'), + (81.25, 'ochenta y un dobras con veinticinco céntimos'), + (350.90, 'trescientos cincuenta dobras con noventa céntimos'), + (100.00, 'cien dobras con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta dobras con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_SVC = ( + (1.00, 'un colón con cero centavos'), + (2.00, 'dos colones con cero centavos'), + (8.00, 'ocho colones con cero centavos'), + (12.00, 'doce colones con cero centavos'), + (21.00, 'veintiún colones con cero centavos'), + (81.25, 'ochenta y un colones con veinticinco centavos'), + (350.90, 'trescientos cincuenta colones con noventa centavos'), + (100.00, 'cien colones con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta colones con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_SZL = ( + (1.00, 'un lilangeni con cero céntimos'), + (2.00, 'dos emalangeni con cero céntimos'), + (8.00, 'ocho emalangeni con cero céntimos'), + (12.00, 'doce emalangeni con cero céntimos'), + (21.00, 'veintiún emalangeni con cero céntimos'), + (81.25, 'ochenta y un emalangeni con veinticinco céntimos'), + (350.90, 'trescientos cincuenta emalangeni con noventa céntimos'), + (100.00, 'cien emalangeni con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta emalangeni con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_TJS = ( + (1.00, 'un somoni con cero dirames'), + (2.00, 'dos somonis con cero dirames'), + (8.00, 'ocho somonis con cero dirames'), + (12.00, 'doce somonis con cero dirames'), + (21.00, 'veintiún somonis con cero dirames'), + (81.25, 'ochenta y un somonis con veinticinco dirames'), + (350.90, 'trescientos cincuenta somonis con noventa dirames'), + (100.00, 'cien somonis con cero dirames'), + (4150.83, + 'cuatro mil ciento cincuenta somonis con ochenta y tres dirames'), +) + +TEST_CASES_TO_CURRENCY_TMT = ( + (1.00, 'un manat con cero tenge'), + (2.00, 'dos manat con cero tenge'), + (8.00, 'ocho manat con cero tenge'), + (12.00, 'doce manat con cero tenge'), + (21.00, 'veintiún manat con cero tenge'), + (81.25, 'ochenta y un manat con veinticinco tenge'), + (350.90, 'trescientos cincuenta manat con noventa tenge'), + (100.00, 'cien manat con cero tenge'), + (4150.83, + 'cuatro mil ciento cincuenta manat con ochenta y tres tenge'), +) + +TEST_CASES_TO_CURRENCY_TND = ( + (1.00, 'un dinar con cero milésimos'), + (2.00, 'dos dinares con cero milésimos'), + (8.00, 'ocho dinares con cero milésimos'), + (12.00, 'doce dinares con cero milésimos'), + (21.00, 'veintiún dinares con cero milésimos'), + (81.25, 'ochenta y un dinares con veinticinco milésimos'), + (350.90, 'trescientos cincuenta dinares con noventa milésimos'), + (100.00, 'cien dinares con cero milésimos'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres milésimos'), +) + +TEST_CASES_TO_CURRENCY_TOP = ( + (1.00, 'un paanga con cero céntimos'), + (2.00, 'dos paangas con cero céntimos'), + (8.00, 'ocho paangas con cero céntimos'), + (12.00, 'doce paangas con cero céntimos'), + (21.00, 'veintiún paangas con cero céntimos'), + (81.25, 'ochenta y un paangas con veinticinco céntimos'), + (350.90, 'trescientos cincuenta paangas con noventa céntimos'), + (100.00, 'cien paangas con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta paangas con ochenta y tres céntimos'), +) + +wordamount = "{} {}".format("cuatro mil ciento cincuenta", + "nuevos dólares con ochenta y tres céntimos") + +TEST_CASES_TO_CURRENCY_TWD = ( + (1.00, 'un nuevo dólar con cero céntimos'), + (2.00, 'dos nuevos dólares con cero céntimos'), + (8.00, 'ocho nuevos dólares con cero céntimos'), + (12.00, 'doce nuevos dólares con cero céntimos'), + (21.00, 'veintiún nuevos dólares con cero céntimos'), + (81.25, 'ochenta y un nuevos dólares con veinticinco céntimos'), + (350.90, 'trescientos cincuenta nuevos dólares con noventa céntimos'), + (100.00, 'cien nuevos dólares con cero céntimos'), + (4150.83, wordamount), +) + +TEST_CASES_TO_CURRENCY_TZS = ( + (1.00, 'un chelín con cero céntimos'), + (2.00, 'dos chelines con cero céntimos'), + (8.00, 'ocho chelines con cero céntimos'), + (12.00, 'doce chelines con cero céntimos'), + (21.00, 'veintiún chelines con cero céntimos'), + (81.25, 'ochenta y un chelines con veinticinco céntimos'), + (350.90, 'trescientos cincuenta chelines con noventa céntimos'), + (100.00, 'cien chelines con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta chelines con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_UAG = ( + (1.00, 'un hryvnia con cero kopiykas'), + (2.00, 'dos hryvnias con cero kopiykas'), + (8.00, 'ocho hryvnias con cero kopiykas'), + (12.00, 'doce hryvnias con cero kopiykas'), + (21.00, 'veintiún hryvnias con cero kopiykas'), + (81.25, 'ochenta y un hryvnias con veinticinco kopiykas'), + (350.90, 'trescientos cincuenta hryvnias con noventa kopiykas'), + (100.00, 'cien hryvnias con cero kopiykas'), + (4150.83, + 'cuatro mil ciento cincuenta hryvnias con ochenta y tres kopiykas'), +) + +TEST_CASES_TO_CURRENCY_UGX = ( + (1.00, 'un chelín con cero céntimos'), + (2.00, 'dos chelines con cero céntimos'), + (8.00, 'ocho chelines con cero céntimos'), + (12.00, 'doce chelines con cero céntimos'), + (21.00, 'veintiún chelines con cero céntimos'), + (81.25, 'ochenta y un chelines con veinticinco céntimos'), + (350.90, 'trescientos cincuenta chelines con noventa céntimos'), + (100.00, 'cien chelines con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta chelines con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_UYU = ( + (1.00, 'un peso con cero centésimos'), + (2.00, 'dos pesos con cero centésimos'), + (8.00, 'ocho pesos con cero centésimos'), + (12.00, 'doce pesos con cero centésimos'), + (21.00, 'veintiún pesos con cero centésimos'), + (81.25, 'ochenta y un pesos con veinticinco centésimos'), + (350.90, 'trescientos cincuenta pesos con noventa centésimos'), + (100.00, 'cien pesos con cero centésimos'), + (4150.83, + 'cuatro mil ciento cincuenta pesos con ochenta y tres centésimos'), +) + +TEST_CASES_TO_CURRENCY_UZS = ( + (1.00, 'un sum con cero tiyin'), + (2.00, 'dos sum con cero tiyin'), + (8.00, 'ocho sum con cero tiyin'), + (12.00, 'doce sum con cero tiyin'), + (21.00, 'veintiún sum con cero tiyin'), + (81.25, 'ochenta y un sum con veinticinco tiyin'), + (350.90, 'trescientos cincuenta sum con noventa tiyin'), + (100.00, 'cien sum con cero tiyin'), + (4150.83, + 'cuatro mil ciento cincuenta sum con ochenta y tres tiyin'), +) + +wordamount = "{} {}".format("cuatro mil ciento cincuenta", + "bolívares fuertes con ochenta y tres céntimos") + +TEST_CASES_TO_CURRENCY_VEF = ( + (1.00, 'un bolívar fuerte con cero céntimos'), + (2.00, 'dos bolívares fuertes con cero céntimos'), + (8.00, 'ocho bolívares fuertes con cero céntimos'), + (12.00, 'doce bolívares fuertes con cero céntimos'), + (21.00, 'veintiún bolívares fuertes con cero céntimos'), + (81.25, 'ochenta y un bolívares fuertes con veinticinco céntimos'), + (350.90, 'trescientos cincuenta bolívares fuertes con noventa céntimos'), + (100.00, 'cien bolívares fuertes con cero céntimos'), + (4150.83, wordamount), +) + +TEST_CASES_TO_CURRENCY_VND = ( + (1.00, 'un dong con cero xu'), + (2.00, 'dos dongs con cero xu'), + (8.00, 'ocho dongs con cero xu'), + (12.00, 'doce dongs con cero xu'), + (21.00, 'veintiún dongs con cero xu'), + (81.25, 'ochenta y un dongs con veinticinco xu'), + (350.90, 'trescientos cincuenta dongs con noventa xu'), + (100.00, 'cien dongs con cero xu'), + (4150.83, + 'cuatro mil ciento cincuenta dongs con ochenta y tres xu'), +) + +TEST_CASES_TO_CURRENCY_VUV = ( + (1.00, 'un vatu con cero nenhum'), + (2.00, 'dos vatu con cero nenhum'), + (8.00, 'ocho vatu con cero nenhum'), + (12.00, 'doce vatu con cero nenhum'), + (21.00, 'veintiún vatu con cero nenhum'), + (81.25, 'ochenta y un vatu con veinticinco nenhum'), + (350.90, 'trescientos cincuenta vatu con noventa nenhum'), + (100.00, 'cien vatu con cero nenhum'), + (4150.83, + 'cuatro mil ciento cincuenta vatu con ochenta y tres nenhum'), +) + +TEST_CASES_TO_CURRENCY_WST = ( + (1.00, 'un tala con cero centavos'), + (2.00, 'dos tala con cero centavos'), + (8.00, 'ocho tala con cero centavos'), + (12.00, 'doce tala con cero centavos'), + (21.00, 'veintiún tala con cero centavos'), + (81.25, 'ochenta y un tala con veinticinco centavos'), + (350.90, 'trescientos cincuenta tala con noventa centavos'), + (100.00, 'cien tala con cero centavos'), + (4150.83, + 'cuatro mil ciento cincuenta tala con ochenta y tres centavos'), +) + +TEST_CASES_TO_CURRENCY_XAF = ( + (1.00, 'un franco CFA con cero céntimos'), + (2.00, 'dos francos CFA con cero céntimos'), + (8.00, 'ocho francos CFA con cero céntimos'), + (12.00, 'doce francos CFA con cero céntimos'), + (21.00, 'veintiún francos CFA con cero céntimos'), + (81.25, 'ochenta y un francos CFA con veinticinco céntimos'), + (350.90, 'trescientos cincuenta francos CFA con noventa céntimos'), + (100.00, 'cien francos CFA con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta francos CFA con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_XPF = ( + (1.00, 'un franco CFP con cero céntimos'), + (2.00, 'dos francos CFP con cero céntimos'), + (8.00, 'ocho francos CFP con cero céntimos'), + (12.00, 'doce francos CFP con cero céntimos'), + (21.00, 'veintiún francos CFP con cero céntimos'), + (81.25, 'ochenta y un francos CFP con veinticinco céntimos'), + (350.90, 'trescientos cincuenta francos CFP con noventa céntimos'), + (100.00, 'cien francos CFP con cero céntimos'), + (4150.83, + 'cuatro mil ciento cincuenta francos CFP con ochenta y tres céntimos'), +) + +TEST_CASES_TO_CURRENCY_YER = ( + (1.00, 'un rial con cero fils'), + (2.00, 'dos riales con cero fils'), + (8.00, 'ocho riales con cero fils'), + (12.00, 'doce riales con cero fils'), + (21.00, 'veintiún riales con cero fils'), + (81.25, 'ochenta y un riales con veinticinco fils'), + (350.90, 'trescientos cincuenta riales con noventa fils'), + (100.00, 'cien riales con cero fils'), + (4150.83, + 'cuatro mil ciento cincuenta riales con ochenta y tres fils'), +) + +TEST_CASES_TO_CURRENCY_YUM = ( + (1.00, 'un dinar con cero para'), + (2.00, 'dos dinares con cero para'), + (8.00, 'ocho dinares con cero para'), + (12.00, 'doce dinares con cero para'), + (21.00, 'veintiún dinares con cero para'), + (81.25, 'ochenta y un dinares con veinticinco para'), + (350.90, 'trescientos cincuenta dinares con noventa para'), + (100.00, 'cien dinares con cero para'), + (4150.83, + 'cuatro mil ciento cincuenta dinares con ochenta y tres para'), +) + +TEST_CASES_TO_CURRENCY_ZMW = ( + (1.00, 'un kwacha con cero ngwee'), + (2.00, 'dos kwachas con cero ngwee'), + (8.00, 'ocho kwachas con cero ngwee'), + (12.00, 'doce kwachas con cero ngwee'), + (21.00, 'veintiún kwachas con cero ngwee'), + (81.25, 'ochenta y un kwachas con veinticinco ngwee'), + (350.90, 'trescientos cincuenta kwachas con noventa ngwee'), + (100.00, 'cien kwachas con cero ngwee'), + (4150.83, + 'cuatro mil ciento cincuenta kwachas con ochenta y tres ngwee'), +) + +TEST_CASES_TO_CURRENCY_ZRZ = ( + (1.00, 'un zaire con cero makuta'), + (2.00, 'dos zaires con cero makuta'), + (8.00, 'ocho zaires con cero makuta'), + (12.00, 'doce zaires con cero makuta'), + (21.00, 'veintiún zaires con cero makuta'), + (81.25, 'ochenta y un zaires con veinticinco makuta'), + (350.90, 'trescientos cincuenta zaires con noventa makuta'), + (100.00, 'cien zaires con cero makuta'), + (4150.83, + 'cuatro mil ciento cincuenta zaires con ochenta y tres makuta'), ) @@ -203,3 +1863,1172 @@ def test_currency_pen(self): num2words(test[0], lang='es', to='currency', currency='PEN'), test[1] ) + + def test_currency_crc(self): + for test in TEST_CASES_TO_CURRENCY_CRC: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CRC'), + test[1] + ) + + def test_currency_aud(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AUD'), + test[1] + ) + + def test_currency_cad(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CAD'), + test[1] + ) + + def test_currency_gbp(self): + for test in TEST_CASES_TO_CURRENCY_GBP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GBP'), + test[1] + ) + + def test_currency_rub(self): + for test in TEST_CASES_TO_CURRENCY_RUB: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='RUB'), + test[1] + ) + + def test_currency_sek(self): + for test in TEST_CASES_TO_CURRENCY_SEK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SEK'), + test[1] + ) + + def test_currency_nok(self): + for test in TEST_CASES_TO_CURRENCY_NOK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='NOK'), + test[1] + ) + + def test_currency_pln(self): + for test in TEST_CASES_TO_CURRENCY_PLN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PLN'), + test[1] + ) + + def test_currency_mxn(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MXN'), + test[1] + ) + + def test_currency_ron(self): + for test in TEST_CASES_TO_CURRENCY_RON: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='RON'), + test[1] + ) + + def test_currency_inr(self): + for test in TEST_CASES_TO_CURRENCY_INR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='INR'), + test[1] + ) + + def test_currency_huf(self): + for test in TEST_CASES_TO_CURRENCY_HUF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='HUF'), + test[1] + ) + + def test_currency_frf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='FRF'), + test[1] + ) + + def test_currency_cny(self): + for test in TEST_CASES_TO_CURRENCY_CNY: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CNY'), + test[1] + ) + + def test_currency_czk(self): + for test in TEST_CASES_TO_CURRENCY_CZK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CZK'), + test[1] + ) + + def test_currency_nio(self): + for test in TEST_CASES_TO_CURRENCY_NIO: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='NIO'), + test[1] + ) + + def test_currency_ves(self): + for test in TEST_CASES_TO_CURRENCY_VES: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='VES'), + test[1] + ) + + def test_currency_brl(self): + for test in TEST_CASES_TO_CURRENCY_BRL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BRL'), + test[1] + ) + + def test_currency_chf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CHF'), + test[1] + ) + + def test_currency_jpy(self): + for test in TEST_CASES_TO_CURRENCY_JPY: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='JPY'), + test[1] + ) + + def test_currency_krw(self): + for test in TEST_CASES_TO_CURRENCY_KRW: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KRW'), + test[1] + ) + + def test_currency_kpw(self): + for test in TEST_CASES_TO_CURRENCY_KPW: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KPW'), + test[1] + ) + + def test_currency_try(self): + for test in TEST_CASES_TO_CURRENCY_TRY: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TRY'), + test[1] + ) + + def test_currency_zar(self): + for test in TEST_CASES_TO_CURRENCY_ZAR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ZAR'), + test[1] + ) + + def test_currency_kzt(self): + for test in TEST_CASES_TO_CURRENCY_KZT: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KZT'), + test[1] + ) + + def test_currency_uah(self): + for test in TEST_CASES_TO_CURRENCY_UAH: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='UAH'), + test[1] + ) + + def test_currency_thb(self): + for test in TEST_CASES_TO_CURRENCY_THB: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='THB'), + test[1] + ) + + def test_currency_aed(self): + for test in TEST_CASES_TO_CURRENCY_AED: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AED'), + test[1] + ) + + def test_currency_afn(self): + for test in TEST_CASES_TO_CURRENCY_AFN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AFN'), + test[1] + ) + + def test_currency_all(self): + for test in TEST_CASES_TO_CURRENCY_ALL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ALL'), + test[1] + ) + + def test_currency_amd(self): + for test in TEST_CASES_TO_CURRENCY_AMD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AMD'), + test[1] + ) + + def test_currency_ang(self): + for test in TEST_CASES_TO_CURRENCY_ANG: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ANG'), + test[1] + ) + + def test_currency_aoa(self): + for test in TEST_CASES_TO_CURRENCY_AOA: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AOA'), + test[1] + ) + + def test_currency_ars(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ARS'), + test[1] + ) + + def test_currency_awg(self): + for test in TEST_CASES_TO_CURRENCY_AWG: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AWG'), + test[1] + ) + + def test_currency_azn(self): + for test in TEST_CASES_TO_CURRENCY_AZN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='AZN'), + test[1] + ) + + def test_currency_bbd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BBD'), + test[1] + ) + + def test_currency_bdt(self): + for test in TEST_CASES_TO_CURRENCY_BDT: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BDT'), + test[1] + ) + + def test_currency_bgn(self): + for test in TEST_CASES_TO_CURRENCY_BGN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BGN'), + test[1] + ) + + def test_currency_bhd(self): + for test in TEST_CASES_TO_CURRENCY_BHD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BHD'), + test[1] + ) + + def test_currency_bif(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BIF'), + test[1] + ) + + def test_currency_bmd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BMD'), + test[1] + ) + + def test_currency_bnd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BND'), + test[1] + ) + + def test_currency_bob(self): + for test in TEST_CASES_TO_CURRENCY_BOB: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BOB'), + test[1] + ) + + def test_currency_bsd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BSD'), + test[1] + ) + + def test_currency_btn(self): + for test in TEST_CASES_TO_CURRENCY_BTN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BTN'), + test[1] + ) + + def test_currency_bwp(self): + for test in TEST_CASES_TO_CURRENCY_BWP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BWP'), + test[1] + ) + + def test_currency_byn(self): + for test in TEST_CASES_TO_CURRENCY_BYN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BYN'), + test[1] + ) + + def test_currency_byr(self): + for test in TEST_CASES_TO_CURRENCY_BYR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BYR'), + test[1] + ) + + def test_currency_bzd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='BZD'), + test[1] + ) + + def test_currency_cdf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CDF'), + test[1] + ) + + def test_currency_clp(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CLP'), + test[1] + ) + + def test_currency_cop(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='COP'), + test[1] + ) + + def test_currency_cup(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CUP'), + test[1] + ) + + def test_currency_cve(self): + for test in TEST_CASES_TO_CURRENCY_CVE: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CVE'), + test[1] + ) + + def test_currency_cyp(self): + for test in TEST_CASES_TO_CURRENCY_CYP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='CYP'), + test[1] + ) + + def test_currency_djf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='DJF'), + test[1] + ) + + def test_currency_dkk(self): + for test in TEST_CASES_TO_CURRENCY_DKK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='DKK'), + test[1] + ) + + def test_currency_dop(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='DOP'), + test[1] + ) + + def test_currency_dzd(self): + for test in TEST_CASES_TO_CURRENCY_DZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='DZD'), + test[1] + ) + + def test_currency_ecs(self): + for test in TEST_CASES_TO_CURRENCY_ECS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ECS'), + test[1] + ) + + def test_currency_egp(self): + for test in TEST_CASES_TO_CURRENCY_EGP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='EGP'), + test[1] + ) + + def test_currency_ern(self): + for test in TEST_CASES_TO_CURRENCY_ERN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ERN'), + test[1] + ) + + def test_currency_etb(self): + for test in TEST_CASES_TO_CURRENCY_ETB: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ETB'), + test[1] + ) + + def test_currency_fjd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='FJD'), + test[1] + ) + + def test_currency_fkp(self): + for test in TEST_CASES_TO_CURRENCY_FKP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='FKP'), + test[1] + ) + + def test_currency_gel(self): + for test in TEST_CASES_TO_CURRENCY_GEL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GEL'), + test[1] + ) + + def test_currency_ghs(self): + for test in TEST_CASES_TO_CURRENCY_GHS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GHS'), + test[1] + ) + + def test_currency_gip(self): + for test in TEST_CASES_TO_CURRENCY_FKP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GIP'), + test[1] + ) + + def test_currency_gmd(self): + for test in TEST_CASES_TO_CURRENCY_GMD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GMD'), + test[1] + ) + + def test_currency_gnf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GNF'), + test[1] + ) + + def test_currency_gtq(self): + for test in TEST_CASES_TO_CURRENCY_GTQ: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GTQ'), + test[1] + ) + + def test_currency_gyd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GYD'), + test[1] + ) + + def test_currency_hkd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='HKD'), + test[1] + ) + + def test_currency_hnl(self): + for test in TEST_CASES_TO_CURRENCY_HNL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='HNL'), + test[1] + ) + + def test_currency_hrk(self): + for test in TEST_CASES_TO_CURRENCY_HRK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='HRK'), + test[1] + ) + + def test_currency_htg(self): + for test in TEST_CASES_TO_CURRENCY_HTG: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='HTG'), + test[1] + ) + + def test_currency_idr(self): + for test in TEST_CASES_TO_CURRENCY_IDR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='IDR'), + test[1] + ) + + def test_currency_ils(self): + for test in TEST_CASES_TO_CURRENCY_ILS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ILS'), + test[1] + ) + + def test_currency_iqd(self): + for test in TEST_CASES_TO_CURRENCY_IQD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='IQD'), + test[1] + ) + + def test_currency_irr(self): + for test in TEST_CASES_TO_CURRENCY_IRR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='IRR'), + test[1] + ) + + def test_currency_isk(self): + for test in TEST_CASES_TO_CURRENCY_ISK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ISK'), + test[1] + ) + + def test_currency_itl(self): + for test in TEST_CASES_TO_CURRENCY_ITL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ITL'), + test[1] + ) + + def test_currency_jmd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='JMD'), + test[1] + ) + + def test_currency_jod(self): + for test in TEST_CASES_TO_CURRENCY_JOD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='JOD'), + test[1] + ) + + def test_currency_kes(self): + for test in TEST_CASES_TO_CURRENCY_KES: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KES'), + test[1] + ) + + def test_currency_kgs(self): + for test in TEST_CASES_TO_CURRENCY_KGS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KGS'), + test[1] + ) + + def test_currency_khr(self): + for test in TEST_CASES_TO_CURRENCY_KHR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KHR'), + test[1] + ) + + def test_currency_kmf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KMF'), + test[1] + ) + + def test_currency_kwd(self): + for test in TEST_CASES_TO_CURRENCY_KWD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KWD'), + test[1] + ) + + def test_currency_kyd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='KYD'), + test[1] + ) + + def test_currency_lak(self): + for test in TEST_CASES_TO_CURRENCY_LAK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LAK'), + test[1] + ) + + def test_currency_lbp(self): + for test in TEST_CASES_TO_CURRENCY_EGP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LBP'), + test[1] + ) + + def test_currency_lkr(self): + for test in TEST_CASES_TO_CURRENCY_LKR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LKR'), + test[1] + ) + + def test_currency_lrd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LRD'), + test[1] + ) + + def test_currency_lsl(self): + for test in TEST_CASES_TO_CURRENCY_LSL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LSL'), + test[1] + ) + + def test_currency_ltl(self): + for test in TEST_CASES_TO_CURRENCY_LTL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LTL'), + test[1] + ) + + def test_currency_lvl(self): + for test in TEST_CASES_TO_CURRENCY_LVL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LVL'), + test[1] + ) + + def test_currency_lyd(self): + for test in TEST_CASES_TO_CURRENCY_LYD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='LYD'), + test[1] + ) + + def test_currency_mad(self): + for test in TEST_CASES_TO_CURRENCY_MAD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MAD'), + test[1] + ) + + def test_currency_mdl(self): + for test in TEST_CASES_TO_CURRENCY_MDL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MDL'), + test[1] + ) + + def test_currency_mga(self): + for test in TEST_CASES_TO_CURRENCY_MGA: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MGA'), + test[1] + ) + + def test_currency_mkd(self): + for test in TEST_CASES_TO_CURRENCY_MKD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MKD'), + test[1] + ) + + def test_currency_mmk(self): + for test in TEST_CASES_TO_CURRENCY_MMK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MMK'), + test[1] + ) + + def test_currency_mnt(self): + for test in TEST_CASES_TO_CURRENCY_MNT: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MNT'), + test[1] + ) + + def test_currency_mop(self): + for test in TEST_CASES_TO_CURRENCY_MOP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MOP'), + test[1] + ) + + def test_currency_mro(self): + for test in TEST_CASES_TO_CURRENCY_MRO: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MRO'), + test[1] + ) + + def test_currency_mru(self): + for test in TEST_CASES_TO_CURRENCY_MRU: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MRU'), + test[1] + ) + + def test_currency_mur(self): + for test in TEST_CASES_TO_CURRENCY_MUR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MUR'), + test[1] + ) + + def test_currency_mvr(self): + for test in TEST_CASES_TO_CURRENCY_MVR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MVR'), + test[1] + ) + + def test_currency_mwk(self): + for test in TEST_CASES_TO_CURRENCY_MWK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MWK'), + test[1] + ) + + def test_currency_myr(self): + for test in TEST_CASES_TO_CURRENCY_MYR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MYR'), + test[1] + ) + + def test_currency_mzn(self): + for test in TEST_CASES_TO_CURRENCY_MZN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='MZN'), + test[1] + ) + + def test_currency_nad(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='NAD'), + test[1] + ) + + def test_currency_ngn(self): + for test in TEST_CASES_TO_CURRENCY_NGN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='NGN'), + test[1] + ) + + def test_currency_npr(self): + for test in TEST_CASES_TO_CURRENCY_NPR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='NPR'), + test[1] + ) + + def test_currency_nzd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='NZD'), + test[1] + ) + + def test_currency_omr(self): + for test in TEST_CASES_TO_CURRENCY_OMR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='OMR'), + test[1] + ) + + def test_currency_pab(self): + for test in TEST_CASES_TO_CURRENCY_PAB: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PAB'), + test[1] + ) + + def test_currency_pgk(self): + for test in TEST_CASES_TO_CURRENCY_PGK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PGK'), + test[1] + ) + + def test_currency_php(self): + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PHP'), + test[1] + ) + + def test_currency_pkr(self): + for test in TEST_CASES_TO_CURRENCY_PKR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PKR'), + test[1] + ) + + def test_currency_plz(self): + for test in TEST_CASES_TO_CURRENCY_PLZ: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PLZ'), + test[1] + ) + + def test_currency_pyg(self): + for test in TEST_CASES_TO_CURRENCY_PYG: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='PYG'), + test[1] + ) + + def test_currency_qar(self): + for test in TEST_CASES_TO_CURRENCY_QAR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='QAR'), + test[1] + ) + + def test_currency_qtq(self): + for test in TEST_CASES_TO_CURRENCY_GTQ: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='GTQ'), + test[1] + ) + + def test_currency_rsd(self): + for test in TEST_CASES_TO_CURRENCY_RSD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='RSD'), + test[1] + ) + + def test_currency_rur(self): + for test in TEST_CASES_TO_CURRENCY_RUR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='RUR'), + test[1] + ) + + def test_currency_rwf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='RWF'), + test[1] + ) + + def test_currency_sar(self): + for test in TEST_CASES_TO_CURRENCY_SAR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SAR'), + test[1] + ) + + def test_currency_sbd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SBD'), + test[1] + ) + + def test_currency_scr(self): + for test in TEST_CASES_TO_CURRENCY_SCR: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SCR'), + test[1] + ) + + def test_currency_sdg(self): + for test in TEST_CASES_TO_CURRENCY_EGP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SDG'), + test[1] + ) + + def test_currency_sgd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SGD'), + test[1] + ) + + def test_currency_shp(self): + for test in TEST_CASES_TO_CURRENCY_SHP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SHP'), + test[1] + ) + + def test_currency_skk(self): + for test in TEST_CASES_TO_CURRENCY_SKK: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SKK'), + test[1] + ) + + def test_currency_sll(self): + for test in TEST_CASES_TO_CURRENCY_SLL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SLL'), + test[1] + ) + + def test_currency_srd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SRD'), + test[1] + ) + + def test_currency_ssp(self): + for test in TEST_CASES_TO_CURRENCY_EGP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SSP'), + test[1] + ) + + def test_currency_std(self): + for test in TEST_CASES_TO_CURRENCY_STD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='STD'), + test[1] + ) + + def test_currency_svc(self): + for test in TEST_CASES_TO_CURRENCY_SVC: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SVC'), + test[1] + ) + + def test_currency_syp(self): + for test in TEST_CASES_TO_CURRENCY_EGP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SYP'), + test[1] + ) + + def test_currency_szl(self): + for test in TEST_CASES_TO_CURRENCY_SZL: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='SZL'), + test[1] + ) + + def test_currency_tjs(self): + for test in TEST_CASES_TO_CURRENCY_TJS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TJS'), + test[1] + ) + + def test_currency_tmt(self): + for test in TEST_CASES_TO_CURRENCY_TMT: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TMT'), + test[1] + ) + + def test_currency_tnd(self): + for test in TEST_CASES_TO_CURRENCY_TND: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TND'), + test[1] + ) + + def test_currency_top(self): + for test in TEST_CASES_TO_CURRENCY_TOP: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TOP'), + test[1] + ) + + def test_currency_ttd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TTD'), + test[1] + ) + + def test_currency_twd(self): + for test in TEST_CASES_TO_CURRENCY_TWD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TWD'), + test[1] + ) + + def test_currency_tzs(self): + for test in TEST_CASES_TO_CURRENCY_TZS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='TZS'), + test[1] + ) + + def test_currency_uag(self): + for test in TEST_CASES_TO_CURRENCY_UAG: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='UAG'), + test[1] + ) + + def test_currency_ugx(self): + for test in TEST_CASES_TO_CURRENCY_UGX: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='UGX'), + test[1] + ) + + def test_currency_uyu(self): + for test in TEST_CASES_TO_CURRENCY_UYU: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='UYU'), + test[1] + ) + + def test_currency_uzs(self): + for test in TEST_CASES_TO_CURRENCY_UZS: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='UZS'), + test[1] + ) + + def test_currency_vef(self): + for test in TEST_CASES_TO_CURRENCY_VEF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='VEF'), + test[1] + ) + + def test_currency_vnd(self): + for test in TEST_CASES_TO_CURRENCY_VND: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='VND'), + test[1] + ) + + def test_currency_vuv(self): + for test in TEST_CASES_TO_CURRENCY_VUV: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='VUV'), + test[1] + ) + + def test_currency_wst(self): + for test in TEST_CASES_TO_CURRENCY_WST: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='WST'), + test[1] + ) + + def test_currency_xaf(self): + for test in TEST_CASES_TO_CURRENCY_XAF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='XAF'), + test[1] + ) + + def test_currency_xcd(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='XCD'), + test[1] + ) + + def test_currency_xof(self): + for test in TEST_CASES_TO_CURRENCY_XAF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='XOF'), + test[1] + ) + + def test_currency_xpf(self): + for test in TEST_CASES_TO_CURRENCY_XPF: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='XPF'), + test[1] + ) + + def test_currency_yer(self): + for test in TEST_CASES_TO_CURRENCY_YER: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='YER'), + test[1] + ) + + def test_currency_yum(self): + for test in TEST_CASES_TO_CURRENCY_YUM: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='YUM'), + test[1] + ) + + def test_currency_zmw(self): + for test in TEST_CASES_TO_CURRENCY_ZMW: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ZMW'), + test[1] + ) + + def test_currency_zrz(self): + for test in TEST_CASES_TO_CURRENCY_ZRZ: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ZRZ'), + test[1] + ) + + def test_currency_zwl(self): + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='es', to='currency', currency='ZWL'), + test[1] + ) diff --git a/tests/test_es_cr.py b/tests/test_es_cr.py new file mode 100644 index 00000000..a6a451b8 --- /dev/null +++ b/tests/test_es_cr.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2024, Randall Castro. 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 + +from num2words import num2words + +from . import test_es + +TEST_CASES_TO_CURRENCY = ( + (1, 'un colón'), + (2, 'dos colónes'), + (8, 'ocho colónes'), + (12, 'doce colónes'), + (21, 'veintiun colónes'), + (81.25, 'ochenta y un colónes y veinticinco céntimos'), + (100, 'cien colónes'), +) + + +class Num2WordsESCOTest(test_es.Num2WordsESTest): + + def test_number(self): + for test in test_es.TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang='es_CR'), test[1]) + + def test_ordinal(self): + for test in test_es.TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang='es_CR', ordinal=True), + test[1] + ) + + def test_ordinal_num(self): + for test in test_es.TEST_CASES_ORDINAL_NUM: + self.assertEqual( + num2words(test[0], lang='es', to='ordinal_num'), + test[1] + ) + + def test_currency(self): + for test in TEST_CASES_TO_CURRENCY: + self.assertEqual( + num2words(test[0], lang='es_CR', to='currency'), + test[1] + ) diff --git a/tests/test_es_gt.py b/tests/test_es_gt.py new file mode 100644 index 00000000..b65f8d33 --- /dev/null +++ b/tests/test_es_gt.py @@ -0,0 +1,60 @@ +# -*- 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 unicode_literals + +from num2words import num2words + +from . import test_es + +TEST_CASES_TO_CURRENCY = ( + (1, 'un quetzal'), + (2, 'dos quetzales'), + (8, 'ocho quetzales'), + (12, 'doce quetzales'), + (21, 'veintiun quetzales'), + (81.25, 'ochenta y un quetzales y veinticinco centavos'), + (100, 'cien quetzales'), +) + + +class Num2WordsESGTTest(test_es.Num2WordsESTest): + + def test_number(self): + for test in test_es.TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang='es_GT'), test[1]) + + def test_ordinal(self): + for test in test_es.TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang='es_GT', ordinal=True), + test[1] + ) + + def test_ordinal_num(self): + for test in test_es.TEST_CASES_ORDINAL_NUM: + self.assertEqual( + num2words(test[0], lang='es_GT', to='ordinal_num'), + test[1] + ) + + def test_currency(self): + for test in TEST_CASES_TO_CURRENCY: + self.assertEqual( + num2words(test[0], lang='es_GT', to='currency'), + test[1] + ) diff --git a/tests/test_es_ni.py b/tests/test_es_ni.py new file mode 100644 index 00000000..619e6a15 --- /dev/null +++ b/tests/test_es_ni.py @@ -0,0 +1,42 @@ +# -*- 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 unicode_literals + +from num2words import num2words + +from . import test_es + +TEST_NIO = ( + (1.0, 'un córdoba con cero centavos'), + (2.0, 'dos córdobas con cero centavos'), + (8.0, 'ocho córdobas con cero centavos'), + (12.0, 'doce córdobas con cero centavos'), + (21.0, 'veintiun córdobas con cero centavos'), + (81.25, 'ochenta y un córdobas con veinticinco centavos'), + (100.00, 'cien córdobas con cero centavos'), +) + + +class Num2WordsESNITest(test_es.Num2WordsESTest): + + def test_currency(self): + for test in TEST_NIO: + self.assertEqual( + num2words(test[0], lang='es_NI', to='currency'), + test[1] + ) diff --git a/tests/test_fa.py b/tests/test_fa.py new file mode 100644 index 00000000..9a9c4ead --- /dev/null +++ b/tests/test_fa.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2003, Taro Ogawa. All Rights Reserved. +# Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. +# Copyright (c) 2020, Hamidreza Kalbasi. 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 Num2WordsFATest(TestCase): + def test_and_join_199(self): + self.assertEqual(num2words(199, lang='fa'), "صد و نود و نه") + + def test_ordinal(self): + self.assertEqual( + num2words(0, lang='fa', to='ordinal'), + 'صفرم' + ) + self.assertEqual( + num2words(1, lang='fa', to='ordinal'), + 'یکم' + ) + self.assertEqual( + num2words(13, lang='fa', to='ordinal'), + 'سیزدهم' + ) + self.assertEqual( + num2words(23, lang='fa', to='ordinal'), + 'بیست و سوم' + ) + self.assertEqual( + num2words(12, lang='fa', to='ordinal'), + 'دوازدهم' + ) + self.assertEqual( + num2words(113, lang='fa', to='ordinal'), + 'صد و سیزدهم' + ) + self.assertEqual( + num2words(103, lang='fa', to='ordinal'), + 'صد و سوم' + ) + + def test_cardinal(self): + self.assertEqual(num2words(130000, lang='fa'), "صد و سی هزار") + self.assertEqual(num2words(242, lang='fa'), "دویست و چهل و دو") + self.assertEqual(num2words(800, lang='fa'), "هشتصد") + self.assertEqual(num2words(-203, lang='fa'), "منفی دویست و سه") + self.assertEqual( + num2words(1234567890, lang='fa'), + "یک میلیارد و دویست و سی و چهار میلیون و" + " پانصد و شصت و هفت هزار و هشتصد و نود" + ) + + def test_year(self): + self.assertEqual(num2words(1398, lang='fa', to='year'), + "هزار و سیصد و نود و هشت") + self.assertEqual(num2words(1399, lang='fa', to='year'), + "هزار و سیصد و نود و نه") + self.assertEqual( + num2words(1400, lang='fa', to='year'), "هزار و چهارصد") + + def test_currency(self): + self.assertEqual( + num2words(1000, lang='fa', to='currency'), 'هزار تومان') + self.assertEqual( + num2words(1500000, lang='fa', to='currency'), + 'یک میلیون و پانصد هزار تومان' + ) + + def test_ordinal_num(self): + self.assertEqual(num2words(10, lang='fa', to='ordinal_num'), '10م') + self.assertEqual(num2words(21, lang='fa', to='ordinal_num'), '21م') + self.assertEqual(num2words(102, lang='fa', to='ordinal_num'), '102م') + self.assertEqual(num2words(73, lang='fa', to='ordinal_num'), '73م') + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(12.5, lang='fa'), "دوازده و نیم") + self.assertEqual(num2words(0.75, lang='fa'), "هفتاد و پنج صدم") + self.assertEqual(num2words(12.51, lang='fa'), + "دوازده و پنجاه و یک صدم") + self.assertEqual(num2words(12.53, lang='fa'), + "دوازده و پنجاه و سه صدم") + self.assertEqual(num2words(12.59, lang='fa'), + "دوازده و پنجاه و نه صدم") + self.assertEqual(num2words(0.000001, lang='fa'), "یک میلیونیم") + + def test_overflow(self): + with self.assertRaises(OverflowError): + num2words("1000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000") diff --git a/tests/test_fr.py b/tests/test_fr.py index 1299dcc1..873473ae 100644 --- a/tests/test_fr.py +++ b/tests/test_fr.py @@ -107,38 +107,49 @@ TEST_CASES_ORDINAL_NUM = ( (1, '1er'), (8, '8me'), + (11, '11me'), (12, '12me'), (14, '14me'), + (21, '21me'), (28, '28me'), (100, '100me'), + (101, '101me'), (1000, '1000me'), (1000000, '1000000me') ) -TEST_CASES_TO_CURRENCY = ( - (1, 'un euro'), - (2, 'deux euros'), - (8, 'huit euros'), - (12, 'douze euros'), - (21, 'vingt et un euros'), +TEST_CASES_TO_CURRENCY_EUR = ( + (1.00, 'un euro et zéro centimes'), + (2.01, 'deux euros et un centime'), + (8.10, 'huit euros et dix centimes'), + (12.26, 'douze euros et vingt-six centimes'), + (21.29, 'vingt et un euros et vingt-neuf centimes'), (81.25, 'quatre-vingt-un euros et vingt-cinq centimes'), - (81.2, 'quatre-vingt-un euros et vingt centimes'), - (100, 'cent euros'), + (100.00, 'cent euros et zéro centimes'), ) -TEST_CASES_TO_CURRENCY_OLD = ( - (1, 'un franc'), - (2, 'deux francs'), - (8, 'huit francs'), - (12, 'douze francs'), - (21, 'vingt et un francs'), +TEST_CASES_TO_CURRENCY_FRF = ( + (1.00, 'un franc et zéro centimes'), + (2.01, 'deux francs et un centime'), + (8.10, 'huit francs et dix centimes'), + (12.27, 'douze francs et vingt-sept centimes'), + (21.29, 'vingt et un francs et vingt-neuf centimes'), (81.25, 'quatre-vingt-un francs et vingt-cinq centimes'), - (81.2, 'quatre-vingt-un francs et vingt centimes'), - (100, 'cent francs'), + (100.00, 'cent francs et zéro centimes'), +) + +TEST_CASES_TO_CURRENCY_USD = ( + (1.00, 'un dollar et zéro cents'), + (2.01, 'deux dollars et un cent'), + (8.10, 'huit dollars et dix cents'), + (12.26, 'douze dollars et vingt-six cents'), + (21.29, 'vingt et un dollars et vingt-neuf cents'), + (81.25, 'quatre-vingt-un dollars et vingt-cinq cents'), + (100.00, 'cent dollars et zéro cents'), ) -class Num2WordsENTest(TestCase): +class Num2WordsFRTest(TestCase): def test_ordinal_special_joins(self): # ref https://github.com/savoirfairelinux/num2words/issues/18 self.assertEqual( @@ -172,16 +183,30 @@ def test_ordinal_num(self): test[1] ) - def test_currency(self): - for test in TEST_CASES_TO_CURRENCY: + def test_currency_eur(self): + for test in TEST_CASES_TO_CURRENCY_EUR: self.assertEqual( - num2words(test[0], lang='fr', to='currency'), + num2words(test[0], lang='fr', to='currency', currency='EUR'), test[1] ) - def test_currency_old(self): - for test in TEST_CASES_TO_CURRENCY_OLD: + def test_currency_frf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: self.assertEqual( - num2words(test[0], lang='fr', to='currency', old=True), + num2words(test[0], lang='fr', to='currency', currency='FRF'), test[1] ) + + def test_currency_usd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='fr', to='currency', currency='USD'), + test[1] + ) + + def test_max_numbers(self): + + with self.assertRaises(OverflowError) as context: + num2words(10 ** 700, lang='fr') + + self.assertTrue('trop grand' in str(context.exception)) diff --git a/tests/test_fr_be.py b/tests/test_fr_be.py index d084ac41..249d88b9 100644 --- a/tests/test_fr_be.py +++ b/tests/test_fr_be.py @@ -54,24 +54,24 @@ (1000000000000000000, 'un trillionsième') # over 1e18 is not supported ) -TEST_CASES_TO_CURRENCY = ( - (1, 'un euro'), - (2, 'deux euros'), - (8, 'huit euros'), - (12, 'douze euros'), - (21, 'vingt et un euros'), +TEST_CASES_TO_CURRENCY_EUR = ( + (1.00, 'un euro et zéro centimes'), + (2.01, 'deux euros et un centime'), + (8.10, 'huit euros et dix centimes'), + (12.26, 'douze euros et vingt-six centimes'), + (21.29, 'vingt et un euros et vingt-neuf centimes'), (81.25, 'quatre-vingt et un euros et vingt-cinq centimes'), - (100, 'cent euros'), + (100.00, 'cent euros et zéro centimes'), ) -TEST_CASES_TO_CURRENCY_OLD = ( - (1, 'un franc'), - (2, 'deux francs'), - (8, 'huit francs'), - (12, 'douze francs'), - (21, 'vingt et un francs'), +TEST_CASES_TO_CURRENCY_FRF = ( + (1.00, 'un franc et zéro centimes'), + (2.01, 'deux francs et un centime'), + (8.10, 'huit francs et dix centimes'), + (12.27, 'douze francs et vingt-sept centimes'), + (21.29, 'vingt et un francs et vingt-neuf centimes'), (81.25, 'quatre-vingt et un francs et vingt-cinq centimes'), - (100, 'cent francs'), + (100.00, 'cent francs et zéro centimes'), ) # Lang to execute current test @@ -114,16 +114,16 @@ def test_ordinal(self): test[1] ) - def test_currency(self): - for test in TEST_CASES_TO_CURRENCY: + def test_currency_eur(self): + for test in TEST_CASES_TO_CURRENCY_EUR: self.assertEqual( num2words(test[0], lang=LANG, to='currency'), test[1] ) - def test_currency_old(self): - for test in TEST_CASES_TO_CURRENCY_OLD: + def test_currency_frf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: self.assertEqual( - num2words(test[0], lang=LANG, to='currency', old=True), + num2words(test[0], lang=LANG, to='currency', currency='FRF'), test[1] ) diff --git a/tests/test_fr_ch.py b/tests/test_fr_ch.py index ad0f3b17..a51e957d 100644 --- a/tests/test_fr_ch.py +++ b/tests/test_fr_ch.py @@ -55,24 +55,24 @@ (1000000000000000000, 'un trillionsième') # over 1e18 is not supported ) -TEST_CASES_TO_CURRENCY = ( - (1, 'un euro'), - (2, 'deux euros'), - (8, 'huit euros'), - (12, 'douze euros'), - (21, 'vingt et un euros'), +TEST_CASES_TO_CURRENCY_EUR = ( + (1.00, 'un euro et zéro centimes'), + (2.01, 'deux euros et un centime'), + (8.10, 'huit euros et dix centimes'), + (12.26, 'douze euros et vingt-six centimes'), + (21.29, 'vingt et un euros et vingt-neuf centimes'), (81.25, 'huitante et un euros et vingt-cinq centimes'), - (100, 'cent euros'), + (100.00, 'cent euros et zéro centimes'), ) -TEST_CASES_TO_CURRENCY_OLD = ( - (1, 'un franc'), - (2, 'deux francs'), - (8, 'huit francs'), - (12, 'douze francs'), - (21, 'vingt et un francs'), +TEST_CASES_TO_CURRENCY_FRF = ( + (1.00, 'un franc et zéro centimes'), + (2.01, 'deux francs et un centime'), + (8.10, 'huit francs et dix centimes'), + (12.27, 'douze francs et vingt-sept centimes'), + (21.29, 'vingt et un francs et vingt-neuf centimes'), (81.25, 'huitante et un francs et vingt-cinq centimes'), - (100, 'cent francs'), + (100.00, 'cent francs et zéro centimes'), ) @@ -111,16 +111,17 @@ def test_ordinal(self): test[1] ) - def test_currency(self): - for test in TEST_CASES_TO_CURRENCY: + def test_currency_eur(self): + for test in TEST_CASES_TO_CURRENCY_EUR: self.assertEqual( num2words(test[0], lang='fr_CH', to='currency'), test[1] ) - def test_currency_old(self): - for test in TEST_CASES_TO_CURRENCY_OLD: + def test_currency_frf(self): + for test in TEST_CASES_TO_CURRENCY_FRF: self.assertEqual( - num2words(test[0], lang='fr_CH', to='currency', old=True), + num2words(test[0], lang='fr_CH', to='currency', + currency='FRF'), test[1] ) diff --git a/tests/test_fr_dz.py b/tests/test_fr_dz.py index 6c467cb1..8a9d44a5 100644 --- a/tests/test_fr_dz.py +++ b/tests/test_fr_dz.py @@ -29,7 +29,7 @@ (8, 'huit dinards'), (12, 'douze dinards'), (21, 'vingt et un dinards'), - (81.25, 'quatre-vingt-un dinards virgule vingt-cinq centimes'), + (81.25, 'quatre-vingt-un dinards et vingt-cinq centimes'), (100, 'cent dinards'), ) @@ -38,11 +38,11 @@ class Num2WordsPLTest(TestCase): def test_currency(self): self.assertEqual( num2words(1234.12, lang='fr_DZ', to='currency'), - "mille deux cent trente-quatre dinards virgule douze centimes" + "mille deux cent trente-quatre dinards et douze centimes" ) self.assertEqual( num2words(45689.89, lang='fr_DZ', to='currency'), - "quarante-cinq mille six cent quatre-vingt-neuf dinards virgule " + "quarante-cinq mille six cent quatre-vingt-neuf dinards et " "quatre-vingt-neuf centimes" ) diff --git a/tests/test_he.py b/tests/test_he.py new file mode 100644 index 00000000..b6643e95 --- /dev/null +++ b/tests/test_he.py @@ -0,0 +1,507 @@ +# -*- 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words +from num2words.lang_HE import Num2Word_HE, int2word + + +class Num2WordsHETest(TestCase): + maxDiff = None + + def test_negative(self): + self.assertEqual(num2words(-1, lang="he"), u'מינוס אחת') + + def test_0(self): + self.assertEqual(num2words(0, lang="he"), u'אפס') + + def test_1_to_10(self): + self.assertEqual(num2words(1, lang="he"), u'אחת') + self.assertEqual(num2words(2, lang="he"), u'שתיים') + self.assertEqual(num2words(7, lang="he"), u'שבע') + self.assertEqual(num2words(10, lang="he"), u'עשר') + self.assertEqual(num2words( + 10, lang="he", gender='m', construct=True), u'עשרת') + + def test_11_to_19(self): + self.assertEqual(num2words(11, lang="he"), u'אחת עשרה') + self.assertEqual(num2words(11, lang="he", gender='m'), u'אחד עשר') + self.assertEqual(num2words(13, lang="he"), u'שלוש עשרה') + self.assertEqual(num2words( + 13, lang="he", construct=True), u'שלוש עשרה') + self.assertEqual(num2words(15, lang="he"), u'חמש עשרה') + self.assertEqual(num2words(16, lang="he"), u'שש עשרה') + self.assertEqual(num2words(16, lang="he", gender='m'), u'שישה עשר') + self.assertEqual(num2words( + 16, lang="he", gender='m', construct=True), u'שישה עשר') + self.assertEqual(num2words(19, lang="he"), u'תשע עשרה') + + def test_20_to_99(self): + self.assertEqual(num2words(20, lang="he"), u'עשרים') + self.assertEqual(num2words(23, lang="he"), u'עשרים ושלוש') + self.assertEqual(num2words(23, lang="he", gender='m'), u'עשרים ושלושה') + self.assertEqual(num2words( + 23, lang="he", construct=True), u'עשרים ושלוש') + self.assertEqual(num2words( + 23, lang="he", gender='m', construct=True), u'עשרים ושלושה') + self.assertEqual(num2words(28, lang="he"), u'עשרים ושמונה') + self.assertEqual(num2words(31, lang="he"), u'שלושים ואחת') + self.assertEqual(num2words(40, lang="he"), u'ארבעים') + self.assertEqual(num2words(66, lang="he"), u'שישים ושש') + self.assertEqual(num2words(92, lang="he"), u'תשעים ושתיים') + + def test_100_to_999(self): + self.assertEqual(num2words(100, lang="he"), u'מאה') + self.assertEqual(num2words(100, lang="he", construct=True), u'מאת') + self.assertEqual(num2words(111, lang="he"), u'מאה ואחת עשרה') + self.assertEqual(num2words( + 111, lang="he", construct=True), u'מאה ואחת עשרה') + self.assertEqual(num2words(150, lang="he"), u'מאה וחמישים') + self.assertEqual(num2words(196, lang="he"), u'מאה תשעים ושש') + self.assertEqual(num2words( + 196, lang="he", gender='m'), u'מאה תשעים ושישה') + self.assertEqual(num2words( + 196, lang="he", gender='m', construct=True), u'מאה תשעים ושישה') + self.assertEqual(num2words(200, lang="he"), u'מאתיים') + self.assertEqual(num2words(200, lang="he", construct=True), u'מאתיים') + self.assertEqual(num2words(210, lang="he"), u'מאתיים ועשר') + self.assertEqual(num2words(701, lang="he"), u'שבע מאות ואחת') + + def test_1000_to_9999(self): + self.assertEqual(num2words(1000, lang="he"), u'אלף') + self.assertEqual(num2words(1000, lang="he", construct=True), u'אלף') + self.assertEqual(num2words(1001, lang="he"), u'אלף ואחת') + self.assertEqual(num2words(1002, lang="he"), u'אלף ושתיים') + self.assertEqual(num2words(1002, lang="he", gender='m'), u'אלף ושניים') + self.assertEqual(num2words( + 1002, lang="he", gender='m', construct=True), u'אלף ושניים') + self.assertEqual(num2words(1003, lang="he"), u'אלף ושלוש') + self.assertEqual(num2words(1003, lang="he", gender='m'), u'אלף ושלושה') + self.assertEqual(num2words( + 1003, lang="he", gender='m', construct=True), u'אלף ושלושה') + self.assertEqual(num2words(1010, lang="he"), u'אלף ועשר') + self.assertEqual(num2words(1010, lang="he", gender='m'), u'אלף ועשרה') + self.assertEqual(num2words( + 1010, lang="he", gender='m', construct=True), u'אלף ועשרה') + self.assertEqual(num2words(1500, lang="he"), u'אלף וחמש מאות') + self.assertEqual(num2words(2000, lang="he"), u'אלפיים') + self.assertEqual(num2words(2000, lang="he", construct=True), u'אלפיים') + self.assertEqual(num2words(2002, lang="he"), u'אלפיים ושתיים') + self.assertEqual(num2words( + 2002, lang="he", construct=True), u'אלפיים ושתיים') + self.assertEqual(num2words(3000, lang="he"), u'שלושת אלפים') + self.assertEqual(num2words( + 3000, lang="he", construct=True), u'שלושת אלפי') + self.assertEqual(num2words(3001, lang="he"), u'שלושת אלפים ואחת') + self.assertEqual(num2words( + 3001, lang="he", construct=True), u'שלושת אלפים ואחת') + self.assertEqual(num2words(3100, lang="he"), u'שלושת אלפים ומאה') + self.assertEqual(num2words( + 3100, lang="he", construct=True), u'שלושת אלפים ומאה') + self.assertEqual(num2words( + 6870, lang="he"), u'ששת אלפים שמונה מאות ושבעים') + self.assertEqual(num2words( + 7378, lang="he"), u'שבעת אלפים שלוש מאות שבעים ושמונה') + self.assertEqual(num2words( + 9999, lang="he"), u'תשעת אלפים תשע מאות תשעים ותשע') + + def test_10000_to_99999(self): + self.assertEqual(num2words(10000, lang="he"), u'עשרת אלפים') + self.assertEqual(num2words( + 10000, lang="he", construct=True), u'עשרת אלפי') + self.assertEqual(num2words(10001, lang="he"), u'עשרת אלפים ואחת') + self.assertEqual(num2words( + 10001, lang="he", construct=True), u'עשרת אלפים ואחת') + self.assertEqual(num2words( + 10999, lang="he"), u'עשרת אלפים תשע מאות תשעים ותשע') + self.assertEqual(num2words(11000, lang="he"), u'אחד עשר אלף') + self.assertEqual(num2words(15000, lang="he"), u'חמישה עשר אלף') + self.assertEqual(num2words( + 15000, lang="he", gender='m'), u'חמישה עשר אלף') + self.assertEqual(num2words(20000, lang="he"), u'עשרים אלף') + self.assertEqual(num2words( + 20000, lang="he", construct=True), u'עשרים אלף') + self.assertEqual(num2words(21000, lang="he"), u'עשרים ואחד אלף') + self.assertEqual(num2words(25000, lang="he"), u'עשרים וחמישה אלף') + self.assertEqual(num2words( + 25000, lang="he", construct=True), u'עשרים וחמישה אלף') + self.assertEqual(num2words( + 68700, lang="he"), u'שישים ושמונה אלף ושבע מאות') + self.assertEqual(num2words( + 73781, lang="he"), u'שבעים ושלושה אלף שבע מאות שמונים ואחת') + self.assertEqual(num2words( + 99999, lang="he"), u'תשעים ותשעה אלף תשע מאות תשעים ותשע') + + def test_100000_to_999999(self): + self.assertEqual(num2words(100000, lang="he"), u'מאה אלף') + self.assertEqual(num2words( + 100000, lang="he", construct=True), u'מאה אלף') + self.assertEqual(num2words(100001, lang="he"), u'מאה אלף ואחת') + self.assertEqual(num2words( + 199999, lang="he"), u'מאה תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words(110000, lang="he"), u'מאה ועשרה אלף') + self.assertEqual(num2words(150000, lang="he"), u'מאה וחמישים אלף') + self.assertEqual(num2words(200000, lang="he"), u'מאתיים אלף') + self.assertEqual(num2words(210000, lang="he"), u'מאתיים ועשרה אלף') + self.assertEqual(num2words( + 687000, lang="he"), u'שש מאות שמונים ושבעה אלף') + self.assertEqual(num2words( + 687000, lang="he", construct=True), u'שש מאות שמונים ושבעה אלף') + self.assertEqual(num2words(737812, lang="he"), + u'שבע מאות שלושים ושבעה אלף שמונה מאות ושתים עשרה') + self.assertEqual(num2words(999999, lang="he"), + u'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + + def test_1000000_to_999999999999999(self): + self.assertEqual(num2words(1000000, lang="he"), u'מיליון') + self.assertEqual(num2words( + 1000000, lang="he", construct=True), u'מיליון') + self.assertEqual(num2words(1000002, lang="he"), u'מיליון ושתיים') + self.assertEqual(num2words( + 1000002, lang="he", construct=True), u'מיליון ושתיים') + self.assertEqual(num2words(2000000, lang="he"), u'שני מיליון') + self.assertEqual(num2words( + 2000000, lang="he", construct=True), u'שני מיליוני') + self.assertEqual(num2words(3000000, lang="he"), u'שלושה מיליון') + self.assertEqual(num2words( + 3000000, lang="he", construct=True), u'שלושת מיליוני') + self.assertEqual(num2words(3000002, lang="he"), u'שלושה מיליון ושתיים') + self.assertEqual(num2words( + 3000002, lang="he", construct=True), u'שלושה מיליון ושתיים') + self.assertEqual(num2words(10000000, lang="he"), u'עשרה מיליון') + self.assertEqual(num2words( + 10000000, lang="he", construct=True), 'עשרת מיליוני') + self.assertEqual(num2words(11000000, lang="he"), u'אחד עשר מיליון') + self.assertEqual(num2words( + 11000000, lang="he", construct=True), 'אחד עשר מיליוני') + + self.assertEqual(num2words(1000000000, lang="he"), u'מיליארד') + self.assertEqual(num2words( + 1000000000, lang="he", construct=True), u'מיליארד') + self.assertEqual(num2words(1000000002, lang="he"), u'מיליארד ושתיים') + self.assertEqual(num2words( + 1000000002, lang="he", construct=True), u'מיליארד ושתיים') + self.assertEqual(num2words(2000000000, lang="he"), u'שני מיליארד') + self.assertEqual(num2words( + 2000000000, lang="he", construct=True), u'שני מיליארדי') + self.assertEqual(num2words(3000000000, lang="he"), u'שלושה מיליארד') + self.assertEqual(num2words( + 3000000000, lang="he", construct=True), u'שלושת מיליארדי') + self.assertEqual(num2words( + 3000000002, lang="he"), u'שלושה מיליארד ושתיים') + self.assertEqual(num2words( + 3000000002, lang="he", construct=True), u'שלושה מיליארד ושתיים') + self.assertEqual(num2words(10000000000, lang="he"), u'עשרה מיליארד') + self.assertEqual(num2words( + 10000000000, lang="he", construct=True), 'עשרת מיליארדי') + self.assertEqual(num2words( + 10000000002, lang="he"), u'עשרה מיליארד ושתיים') + self.assertEqual(num2words( + 10000000002, lang="he", construct=True), 'עשרה מיליארד ושתיים') + self.assertEqual(num2words(11000000000, lang="he"), u'אחד עשר מיליארד') + self.assertEqual(num2words( + 11000000000, lang="he", construct=True), 'אחד עשר מיליארדי') + + self.assertEqual(num2words(1000000000000, lang="he"), u'טריליון') + self.assertEqual(num2words( + 1000000000000, lang="he", construct=True), u'טריליון') + self.assertEqual(num2words( + 1000000000002, lang="he"), u'טריליון ושתיים') + self.assertEqual(num2words( + 1000000000002, lang="he", construct=True), u'טריליון ושתיים') + self.assertEqual(num2words(2000000000000, lang="he"), u'שני טריליון') + self.assertEqual(num2words( + 2000000000000, lang="he", construct=True), u'שני טריליוני') + self.assertEqual(num2words(3000000000000, lang="he"), u'שלושה טריליון') + self.assertEqual(num2words( + 3000000000000, lang="he", construct=True), u'שלושת טריליוני') + self.assertEqual(num2words( + 3000000000002, lang="he"), u'שלושה טריליון ושתיים') + self.assertEqual(num2words( + 3000000000002, lang="he", construct=True), u'שלושה טריליון ושתיים') + self.assertEqual(num2words(10000000000000, lang="he"), u'עשרה טריליון') + self.assertEqual(num2words( + 10000000000000, lang="he", construct=True), 'עשרת טריליוני') + self.assertEqual(num2words( + 10000000000002, lang="he"), u'עשרה טריליון ושתיים') + self.assertEqual(num2words( + 10000000000002, lang="he", construct=True), 'עשרה טריליון ושתיים') + self.assertEqual(num2words( + 11000000000000, lang="he"), u'אחד עשר טריליון') + self.assertEqual(num2words( + 11000000000000, lang="he", construct=True), 'אחד עשר טריליוני') + + self.assertEqual(num2words(999999999999999, lang="he"), + u'תשע מאות תשעים ותשעה טריליון ' + u'תשע מאות תשעים ותשעה מיליארד ' + u'תשע מאות תשעים ותשעה מיליון ' + u'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words(999999999999999, lang="he", gender='m'), + u'תשע מאות תשעים ותשעה טריליון ' + u'תשע מאות תשעים ותשעה מיליארד ' + u'תשע מאות תשעים ותשעה מיליון ' + u'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') + self.assertEqual(num2words(999999999999999, lang="he", construct=True), + u'תשע מאות תשעים ותשעה טריליון ' + u'תשע מאות תשעים ותשעה מיליארד ' + u'תשע מאות תשעים ותשעה מיליון ' + u'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words( + 999999999999999, lang="he", gender='m', construct=True), + u'תשע מאות תשעים ותשעה טריליון ' + u'תשע מאות תשעים ותשעה מיליארד ' + u'תשע מאות תשעים ותשעה מיליון ' + u'תשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') + + def test_pluralize(self): + n = Num2Word_HE() + cr1, cr2 = n.CURRENCY_FORMS['ILS'] + self.assertEqual(n.pluralize(1, cr1), u'שקל') + self.assertEqual(n.pluralize(2, cr1), u'שקלים') + self.assertEqual(n.pluralize(1, cr2), u'אגורה') + self.assertEqual(n.pluralize(2, cr2), u'אגורות') + + cr1, cr2 = n.CURRENCY_FORMS['USD'] + self.assertEqual(n.pluralize(1, cr1), u'דולר') + self.assertEqual(n.pluralize(2, cr1), u'דולרים') + self.assertEqual(n.pluralize(1, cr2), u'סנט') + self.assertEqual(n.pluralize(2, cr2), u'סנטים') + + def test_to_currency(self): + n = Num2Word_HE() + self.assertEqual(n.to_currency( + 20.0, currency='ILS'), u'עשרים שקלים ואפס אגורות') + self.assertEqual(n.to_currency( + 100.0, currency='ILS'), u'מאה שקלים ואפס אגורות') + self.assertEqual(n.to_currency( + 100.50, currency='ILS'), u'מאה שקלים וחמישים אגורות') + self.assertEqual(n.to_currency( + 101.51, currency='ILS'), u'מאה ואחד שקלים וחמישים ואחת אגורות') + self.assertEqual(n.to_currency( + -101.51, currency='ILS'), + u'מינוס מאה ואחד שקלים וחמישים ואחת אגורות') + self.assertEqual(n.to_currency( + -101.51, currency='ILS', prefer_singular=True), + u'מינוס מאה ואחד שקל וחמישים ואחת אגורות') + self.assertEqual(n.to_currency( + -101.51, currency='ILS', prefer_singular_cents=True), + u'מינוס מאה ואחד שקלים וחמישים ואחת אגורה') + self.assertEqual(n.to_currency( + -101.51, currency='ILS', prefer_singular=True, + prefer_singular_cents=True), + u'מינוס מאה ואחד שקל וחמישים ואחת אגורה') + self.assertEqual(n.to_currency( + 5.05, currency='ILS', prefer_singular=True, + prefer_singular_cents=True), u'חמישה שקלים וחמש אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', prefer_singular=True, + prefer_singular_cents=True), u'מינוס חמישה שקלים וחמש אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False), + u'מינוס חמישה שקלים ו-05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator='ו'), + u'מינוס חמישה שקלים ו-05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator='ו-'), + u'מינוס חמישה שקלים ו-05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator=''), + u'מינוס חמישה שקלים 05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator='ועוד '), + u'מינוס חמישה שקלים ועוד 05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator=' ו'), + u'מינוס חמישה שקלים ו-05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator=' ו-'), + u'מינוס חמישה שקלים ו-05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator=' '), + u'מינוס חמישה שקלים 05 אגורות') + self.assertEqual(n.to_currency( + -5.05, currency='ILS', cents=False, separator=' ועוד '), + u'מינוס חמישה שקלים ועוד 05 אגורות') + self.assertEqual(n.to_currency( + 1.01, currency='ILS'), u'שקל אחד ואגורה אחת') + self.assertEqual(n.to_currency( + -1.01, currency='ILS'), u'מינוס שקל אחד ואגורה אחת') + self.assertEqual(n.to_currency( + 2.02, currency='ILS'), u'שני שקלים ושתי אגורות') + self.assertEqual(n.to_currency( + 1002.02, currency='ILS'), u'אלף ושניים שקלים ושתי אגורות') + self.assertEqual(n.to_currency( + 1000002.02, currency='ILS'), u'מיליון ושניים שקלים ושתי אגורות') + self.assertEqual(n.to_currency( + 5.05, currency='USD'), u'חמישה דולרים וחמישה סנטים') + self.assertEqual(n.to_currency( + 5.05, currency='USD', prefer_singular=True), + u'חמישה דולר וחמישה סנטים') + self.assertEqual(n.to_currency( + 5.05, currency='USD', prefer_singular_cents=True), + u'חמישה דולרים וחמישה סנט') + self.assertEqual(n.to_currency( + 5.05, currency='USD', prefer_singular=True, + prefer_singular_cents=True), u'חמישה דולר וחמישה סנט') + n.CURRENCY_FORMS['pruta'] = (('פרוטה', 'פרוטות'), ('מאית', 'מאיות')) + self.assertEqual(n.to_currency( + 5.05, currency='pruta'), u'חמש פרוטות וחמש מאיות') + + def test_to_currency_errors(self): + n = Num2Word_HE() + with self.assertRaises(NotImplementedError): + n.to_currency(1, '') + + def test_to_cardinal(self): + n = Num2Word_HE() + self.assertEqual(n.to_cardinal(1500), u'אלף וחמש מאות') + self.assertEqual(n.to_cardinal(1501), u'אלף חמש מאות ואחת') + self.assertEqual(num2words(1, lang='he'), u'אחת') + self.assertEqual(num2words(1, lang='he', gender='m'), u'אחד') + + def test_to_ordinal(self): + n = Num2Word_HE() + self.assertEqual(n.to_ordinal(1001), u'האלף ואחד') + self.assertEqual(n.to_ordinal(1500), u'האלף וחמש מאות') + self.assertEqual(n.to_ordinal(1501), u'האלף חמש מאות ואחד') + self.assertEqual(n.to_ordinal( + 1501, definite=True), u'האלף חמש מאות ואחד') + self.assertEqual(n.to_ordinal(1), u'ראשון') + self.assertEqual(n.to_ordinal(1, definite=True), u'הראשון') + self.assertEqual(n.to_ordinal(1, gender='f'), u'ראשונה') + self.assertEqual(n.to_ordinal( + 1, gender='f', definite=True), u'הראשונה') + self.assertEqual(n.to_ordinal(10), u'עשירי') + self.assertEqual(n.to_ordinal(10, definite=True), u'העשירי') + self.assertEqual(n.to_ordinal(10, gender='f'), u'עשירית') + self.assertEqual(n.to_ordinal( + 10, gender='f', definite=True), u'העשירית') + self.assertEqual(n.to_ordinal(17), u'השבעה עשר') + self.assertEqual(n.to_ordinal(17, definite=True), u'השבעה עשר') + self.assertEqual(n.to_ordinal(17, gender='f'), u'השבע עשרה') + self.assertEqual(n.to_ordinal( + 17, gender='f', definite=True), u'השבע עשרה') + self.assertEqual(n.to_ordinal(0), u'האפס') + self.assertEqual(n.to_ordinal(0, definite=True), u'האפס') + self.assertEqual(n.to_ordinal(0, gender='f'), u'האפס') + self.assertEqual(n.to_ordinal(0, gender='f', definite=True), u'האפס') + self.assertEqual(n.to_ordinal( + 999999), u'התשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') + self.assertEqual(n.to_ordinal( + 999999, gender='f'), + u'התשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words(1, ordinal=True, lang='he'), u'ראשון') + self.assertEqual(num2words( + 1, ordinal=True, lang='he', gender='f'), u'ראשונה') + self.assertEqual(num2words( + 1, ordinal=True, lang='he', definite=True), u'הראשון') + self.assertEqual(num2words( + 1, ordinal=True, lang='he', gender='f', definite=True), u'הראשונה') + + def test_to_ordinal_plural(self): + n = Num2Word_HE() + self.assertEqual(n.to_ordinal(1001, plural=True), u'האלף ואחד') + self.assertEqual(n.to_ordinal(1500, plural=True), u'האלף וחמש מאות') + self.assertEqual(n.to_ordinal( + 1501, plural=True), u'האלף חמש מאות ואחד') + self.assertEqual(n.to_ordinal( + 1501, definite=True, plural=True), u'האלף חמש מאות ואחד') + self.assertEqual(n.to_ordinal(1, plural=True), u'ראשונים') + self.assertEqual(n.to_ordinal( + 1, definite=True, plural=True), u'הראשונים') + self.assertEqual(n.to_ordinal(1, gender='f', plural=True), u'ראשונות') + self.assertEqual(n.to_ordinal( + 1, gender='f', definite=True, plural=True), u'הראשונות') + self.assertEqual(n.to_ordinal(10, plural=True), u'עשיריים') + self.assertEqual(n.to_ordinal( + 10, definite=True, plural=True), u'העשיריים') + self.assertEqual(n.to_ordinal( + 10, gender='f', plural=True), u'עשיריות') + self.assertEqual(n.to_ordinal( + 10, gender='f', definite=True, plural=True), u'העשיריות') + self.assertEqual(n.to_ordinal(17, plural=True), u'השבעה עשר') + self.assertEqual(n.to_ordinal( + 17, definite=True, plural=True), u'השבעה עשר') + self.assertEqual(n.to_ordinal( + 17, gender='f', plural=True), u'השבע עשרה') + self.assertEqual(n.to_ordinal( + 17, gender='f', definite=True, plural=True), u'השבע עשרה') + self.assertEqual(n.to_ordinal(0, plural=True), u'האפס') + self.assertEqual(n.to_ordinal(0, definite=True, plural=True), u'האפס') + self.assertEqual(n.to_ordinal(0, gender='f', plural=True), u'האפס') + self.assertEqual(n.to_ordinal( + 0, gender='f', definite=True, plural=True), u'האפס') + self.assertEqual(n.to_ordinal(999999, plural=True), + u'התשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשעה') + self.assertEqual(n.to_ordinal(999999, gender='f', plural=True), + u'התשע מאות תשעים ותשעה אלף תשע מאות תשעים ותשע') + self.assertEqual(num2words( + 1, ordinal=True, lang='he', plural=True), u'ראשונים') + self.assertEqual(num2words( + 1, ordinal=True, lang='he', gender='f', plural=True), u'ראשונות') + self.assertEqual(num2words(1, ordinal=True, lang='he', + definite=True, plural=True), u'הראשונים') + self.assertEqual(num2words(1, ordinal=True, lang='he', gender='f', + definite=True, plural=True), u'הראשונות') + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(12.5, lang='he'), u'שתים עשרה נקודה חמש') + self.assertEqual(num2words( + 12.51, lang='he'), u'שתים עשרה נקודה חמש אחת') + self.assertEqual(num2words( + 12.53, lang='he'), u'שתים עשרה נקודה חמש שלוש') + self.assertEqual(num2words( + 12.59, lang='he'), u'שתים עשרה נקודה חמש תשע') + self.assertEqual(num2words( + 12.5, lang='he', gender='m'), u'שנים עשר נקודה חמש') + self.assertEqual(num2words( + 12.51, lang='he', gender='m'), u'שנים עשר נקודה חמש אחת') + self.assertEqual(num2words( + 12.53, lang='he', gender='m'), u'שנים עשר נקודה חמש שלוש') + self.assertEqual(num2words( + 12.59, lang='he', gender='m'), u'שנים עשר נקודה חמש תשע') + self.assertEqual(num2words(12.594132, lang='he', gender='m'), + u'שנים עשר נקודה חמש תשע ארבע אחת שלוש שתיים') + + def test_cardinal_float_precision(self): + n = Num2Word_HE() + self.assertEqual(n.to_cardinal_float("1.23"), 'אחת נקודה שתיים שלוש') + n.precision = 1 + self.assertEqual(n.to_cardinal_float("1.2"), 'אחת נקודה שתיים') + + def test_error_to_cardinal_float(self): + n = Num2Word_HE() + with self.assertRaises(TypeError): + n.to_cardinal_float("a") + + def test_overflow(self): + n = Num2Word_HE() + num2words(n.MAXVAL - 1, lang="he") + num2words(n.MAXVAL - 1, ordinal=True, lang="he") + + with self.assertRaises(OverflowError): + num2words(n.MAXVAL, lang="he") + + with self.assertRaises(OverflowError): + num2words(n.MAXVAL, lang="he", ordinal=True) + + with self.assertRaises(OverflowError): + int2word(n.MAXVAL) diff --git a/tests/test_hu.py b/tests/test_hu.py new file mode 100644 index 00000000..d0c159dc --- /dev/null +++ b/tests/test_hu.py @@ -0,0 +1,213 @@ +# -*- 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsHUTest(TestCase): + def test_and_join_199(self): + # ref https://github.com/savoirfairelinux/num2words/issues/8 + self.assertEqual(num2words(199), "one hundred and ninety-nine") + + def test_cardinal(self): + self.assertEqual( + num2words(-1, lang='hu'), + 'mínusz egy' + ) + self.assertEqual( + num2words(0, lang='hu'), + 'nulla' + ) + self.assertEqual( + num2words(1, lang='hu'), + 'egy' + ) + self.assertEqual( + num2words(13, lang='hu'), + 'tizenhárom' + ) + self.assertEqual( + num2words(22, lang='hu'), + 'huszonkettő' + ) + self.assertEqual( + num2words(75, lang='hu'), + 'hetvenöt' + ) + self.assertEqual( + num2words(124, lang='hu'), + 'százhuszonnégy' + ) + self.assertEqual( + num2words(651, lang='hu'), + 'hatszázötvenegy' + ) + self.assertEqual( + num2words(2232, lang='hu'), + 'kétezer-kétszázharminckettő' + ) + self.assertEqual( + num2words(16501, lang='hu'), + 'tizenhatezer-ötszázegy' + ) + self.assertEqual( + num2words(1900000000000, lang='hu'), + 'egybillió-kilencszázmilliárd' + ) + self.assertEqual( + num2words(24656451324564987566, lang='hu'), + 'huszonnégytrillió-hatszázötvenhatbilliárd-négyszázötvenegybillió' + '-háromszázhuszonnégymilliárd-ötszázhatvannégymillió-' + 'kilencszáznyolcvanhétezer-ötszázhatvanhat' + ) + + def test_ordinal(self): + self.assertEqual( + num2words(0, lang='hu', to='ordinal'), + 'nulladik' + ) + self.assertEqual( + num2words(1, lang='hu', to='ordinal'), + 'első' + ) + self.assertEqual( + num2words(2, lang='hu', to='ordinal'), + 'második' + ) + self.assertEqual( + num2words(-3, lang='hu', to='ordinal'), + 'mínusz harmadik' + ) + self.assertEqual( + num2words(13, lang='hu', to='ordinal'), + 'tizenharmadik' + ) + self.assertEqual( + num2words(22, lang='hu', to='ordinal'), + 'huszonkettedik' + ) + self.assertEqual( + num2words(75, lang='hu', to='ordinal'), + 'hetvenötödik' + ) + self.assertEqual( + num2words(124, lang='hu', to='ordinal'), + 'százhuszonnegyedik' + ) + self.assertEqual( + num2words(1532, lang='hu', to='ordinal'), + 'ezerötszázharminckettedik' + ) + self.assertEqual( + num2words(16501, lang='hu', to='ordinal'), + 'tizenhatezer-ötszázegyedik' + ) + self.assertEqual( + num2words(458755640120000, lang='hu', to='ordinal'), + 'négyszázötvennyolcbillió-hétszázötvenötmilliárd-' + 'hatszáznegyvenmillió-százhúszezredik' + ) + + def test_ordinal_num(self): + self.assertEqual(num2words(10, lang='hu', to='ordinal_num'), '10.') + self.assertEqual(num2words(21, lang='hu', to='ordinal_num'), '21.') + self.assertEqual(num2words(102, lang='hu', to='ordinal_num'), '102.') + self.assertEqual(num2words(73, lang='hu', to='ordinal_num'), '73.') + + def test_cardinal_for_float_number(self): + # issue 24 + self.assertEqual(num2words(12, lang='hu'), + "tizenkettő") + self.assertEqual(num2words(12.0, lang='hu'), + "tizenkettő") + self.assertEqual(num2words(12.5, lang='hu'), + "tizenkettő egész öt tized") + self.assertEqual(num2words(-12.5, lang='hu'), + "mínusz tizenkettő egész öt tized") + self.assertEqual(num2words(12.51, lang='hu'), + "tizenkettő egész ötvenegy század") + self.assertEqual(num2words(12.53, lang='hu'), + "tizenkettő egész ötvenhárom század") + self.assertEqual(num2words(12.590, lang='hu'), + "tizenkettő egész ötvenkilenc század") + self.assertEqual(num2words(12.005, lang='hu'), + "tizenkettő egész öt ezred") + + def test_overflow(self): + with self.assertRaises(OverflowError): + num2words("1000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000") + + def test_to_currency(self): + self.assertEqual( + num2words('38.4', lang='hu', to='currency', separator=' és', + cents=False, currency='HUF'), + "harmincnyolc forint és 40 fillér" + ) + self.assertEqual( + num2words('0', lang='hu', to='currency', separator=' és', + cents=False, currency='HUF'), + "nulla forint és 00 fillér" + ) + + self.assertEqual( + num2words('1.01', lang='hu', to='currency', separator=' és', + cents=True, currency='HUF'), + "egy forint és egy fillér" + ) + + self.assertEqual( + num2words('4778.00', lang='hu', to='currency', separator=' és', + cents=True, currency='HUF', adjective=True), + 'négyezer-hétszázhetvennyolc Hungarian forint' + ' és nulla fillér') + + self.assertEqual( + num2words('4778.00', lang='hu', to='currency', separator=' és', + cents=True, currency='HUF'), + 'négyezer-hétszázhetvennyolc forint és nulla fillér') + + def test_to_year(self): + # issue 141 + # "e2 e2" + self.assertEqual(num2words(1990, lang='hu', to='year'), + 'ezerkilencszázkilencven') + self.assertEqual(num2words(5555, lang='hu', to='year'), + 'ötezer-ötszázötvenöt') + self.assertEqual(num2words(2020, lang='hu', to='year'), + 'kétezer-húsz') + self.assertEqual(num2words(905, lang='hu', to='year'), + 'kilencszázöt') + self.assertEqual(num2words(0, lang='hu', to='year'), + 'nulla') + # suffixes + self.assertEqual(num2words(-44, lang='hu', to='year'), + 'i. e. negyvennégy') + self.assertEqual(num2words(-44, lang='hu', to='year', suffix='Kr. e.'), + 'Kr. e. negyvennégy') + self.assertEqual(num2words(1, lang='hu', to='year', suffix='Kr. u.'), + 'Kr. u. egy') + self.assertEqual(num2words(-66000000, lang='hu', to='year'), + 'i. e. hatvanhatmillió') diff --git a/tests/test_is.py b/tests/test_is.py new file mode 100644 index 00000000..2a836d51 --- /dev/null +++ b/tests/test_is.py @@ -0,0 +1,79 @@ +# 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsISTest(TestCase): + + def test_cardinal(self): + self.assertEqual(num2words(0, to="cardinal", lang="is"), + "núll") + self.assertEqual(num2words(1, to="cardinal", lang="is"), + "einn") + self.assertEqual(num2words(45, to="cardinal", lang="is"), + "fjörutíu og fimm") + self.assertEqual(num2words(145, to="cardinal", lang="is"), + "eitt hundrað fjörutíu og fimm") + self.assertEqual(num2words(-1245, to="cardinal", lang="is"), + "mínus eitt þúsund tvö hundruð fjörutíu og fimm") + self.assertEqual(num2words(2234045, to="cardinal", lang="is"), + "tvær milljónir tvö hundruð þrjátíu og fjögur þúsund " + "fjörutíu og fimm") + self.assertEqual(num2words(4002234045, to="cardinal", lang="is"), + "fjórir milljarðar tvær milljónir tvö hundruð " + "þrjátíu og fjögur þúsund fjörutíu og fimm") + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(12.5, to="cardinal", lang="is"), + "tólf komma fimm") + self.assertEqual(num2words(12.51, to="cardinal", lang="is"), + "tólf komma fimm einn") + self.assertEqual(num2words(-12.53, to="cardinal", lang="is"), + "mínus tólf komma fimm þrír") + self.assertEqual(num2words(12.59, to="cardinal", lang="is"), + "tólf komma fimm níu") + + def test_overflow(self): + with self.assertRaises(OverflowError): + num2words("1000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", lang="is") + + def test_not_implemented(self): + # Ordinals + with self.assertRaises(NotImplementedError): + num2words(1, to="ordinal", lang="is") + + # Ordinal num + with self.assertRaises(NotImplementedError): + num2words(1, to="ordinal_num", lang="is") + + # Year + with self.assertRaises(NotImplementedError): + num2words(1, to="year", lang="is") + + # Currency + with self.assertRaises(NotImplementedError): + num2words(1, to="currency", lang="is") diff --git a/tests/test_it.py b/tests/test_it.py index 23c79ce3..23c081d1 100644 --- a/tests/test_it.py +++ b/tests/test_it.py @@ -21,6 +21,36 @@ from num2words import num2words +TEST_CASES_TO_CURRENCY_EUR = ( + (1.00, 'un euro e zero centesimi'), + (2.01, 'due euro e un centesimo'), + (8.10, 'otto euro e dieci centesimi'), + (12.26, 'dodici euro e ventisei centesimi'), + (21.29, 'ventun euro e ventinove centesimi'), + (81.25, 'ottantun euro e venticinque centesimi'), + (100.00, 'cento euro e zero centesimi'), +) + +TEST_CASES_TO_CURRENCY_USD = ( + (1.00, 'un dollaro e zero centesimi'), + (2.01, 'due dollari e un centesimo'), + (8.10, 'otto dollari e dieci centesimi'), + (12.26, 'dodici dollari e ventisei centesimi'), + (21.29, 'ventun dollari e ventinove centesimi'), + (81.25, 'ottantun dollari e venticinque centesimi'), + (100.00, 'cento dollari e zero centesimi'), +) + +TEST_CASES_TO_CURRENCY_GBP = ( + (1.00, 'una sterlina e zero penny'), + (2.01, 'due sterline e un penny'), + (8.10, 'otto sterline e dieci penny'), + (12.26, 'dodici sterline e ventisei penny'), + (21.29, 'ventun sterline e ventinove penny'), + (81.25, 'ottantun sterline e venticinque penny'), + (100.00, 'cento sterline e zero penny'), +) + class Num2WordsITTest(TestCase): maxDiff = None @@ -78,6 +108,7 @@ def test_11_to_19(self): def test_20_to_99(self): self.assertEqual(num2words(20, lang="it"), "venti") + self.assertEqual(num2words(21, lang="it"), "ventuno") self.assertEqual(num2words(23, lang="it"), "ventitré") self.assertEqual(num2words(28, lang="it"), "ventotto") self.assertEqual(num2words(31, lang="it"), "trentuno") @@ -154,6 +185,9 @@ def test_big(self): def test_nth_1_to_99(self): self.assertEqual(num2words(1, lang="it", ordinal=True), "primo") self.assertEqual(num2words(8, lang="it", ordinal=True), "ottavo") + self.assertEqual( + num2words(21, lang="it", ordinal=True), "ventunesimo" + ) self.assertEqual( num2words(23, lang="it", ordinal=True), "ventitreesimo" ) @@ -172,6 +206,9 @@ def test_nth_100_to_999(self): self.assertEqual( num2words(120, lang="it", ordinal=True), "centoventesimo" ) + self.assertEqual( + num2words(121, lang="it", ordinal=True), "centoventunesimo" + ) self.assertEqual( num2words(316, lang="it", ordinal=True), "trecentosedicesimo" ) @@ -226,10 +263,54 @@ def test_nth_big(self): "cinquecentosessantasettemilaottocentonovantesimo" ) - def test_with_decimals(self): + def test_with_floats(self): self.assertAlmostEqual( num2words(1.0, lang="it"), "uno virgola zero" ) self.assertAlmostEqual( num2words(1.1, lang="it"), "uno virgola uno" ) + + def test_with_strings(self): + for i in range(2002): + # Just make sure it doesn't raise an exception + num2words(str(i), lang='it', to='cardinal') + num2words(str(i), lang='it', to='ordinal') + self.assertEqual(num2words('1', lang="it", to='ordinal'), "primo") + self.assertEqual( + num2words('100', lang="it", to='ordinal'), + "centesimo" + ) + self.assertEqual( + num2words('1000', lang="it", to='ordinal'), + "millesimo" + ) + self.assertEqual( + num2words('1234567890123456789012345678', lang="it", to='ordinal'), + "un quadriliardo, duecentotrentaquattro quadrilioni, " + "cinquecentosessantasette triliardi, ottocentonovanta trilioni, " + "centoventitré biliardi, quattrocentocinquantasei bilioni, " + "settecentottantanove miliardi, dodici milioni e " + "trecentoquarantacinquemilaseicentosettantottesimo" + ) + + def test_currency_eur(self): + for test in TEST_CASES_TO_CURRENCY_EUR: + self.assertEqual( + num2words(test[0], lang='it', to='currency', currency='EUR'), + test[1] + ) + + def test_currency_usd(self): + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='it', to='currency', currency='USD'), + test[1] + ) + + def test_currency_gbp(self): + for test in TEST_CASES_TO_CURRENCY_GBP: + self.assertEqual( + num2words(test[0], lang='it', to='currency', currency='GBP'), + test[1] + ) diff --git a/tests/test_ja.py b/tests/test_ja.py index eaac20b7..18c3482f 100644 --- a/tests/test_ja.py +++ b/tests/test_ja.py @@ -20,6 +20,7 @@ from unittest import TestCase from num2words import num2words +from num2words.lang_JA import rendaku_merge_pairs def n2j(*args, **kwargs): @@ -163,6 +164,21 @@ def test_currency(self): "はちじゅうきゅうえん") def test_year(self): + self.assertEqual(n2j(2021, to="year"), "令和三年") + self.assertEqual(n2j(2021, to="year", reading=True), + "れいわさんねん") + self.assertEqual(n2j(2021, to="year", reading="arabic"), + "令和3年") + self.assertEqual(n2j(2019, to="year"), "令和元年") + self.assertEqual(n2j(2019, to="year", reading=True), + "れいわがんねん") + self.assertEqual(n2j(2019, to="year", reading="arabic"), + "令和1年") + self.assertEqual(n2j(2018, to="year"), "平成三十年") + self.assertEqual(n2j(2018, to="year", reading=True), + "へいせいさんじゅうねん") + self.assertEqual(n2j(2018, to="year", reading="arabic"), + "平成30年") self.assertEqual(n2j(2017, to="year"), "平成二十九年") self.assertEqual(n2j(2017, to="year", reading=True), "へいせいにじゅうくねん") @@ -176,10 +192,25 @@ def test_year(self): "にせんねん") self.assertEqual(n2j(645, to="year"), "大化元年") self.assertEqual(n2j(645, to="year", reading=True), "たいかがんねん") - self.assertEqual(n2j(645, to="year"), "大化元年") - self.assertEqual(n2j(645, to="year", reading=True), "たいかがんねん") self.assertEqual(n2j(-99, to="year", era=False), "紀元前九十九年") self.assertEqual(n2j(-99, to="year", era=False, reading=True), "きげんぜんきゅうじゅうくねん") self.assertEqual(n2j(1375, to="year"), "天授元年") self.assertEqual(n2j(1375, to="year", prefer=["えいわ"]), "永和元年") + + def test_rendaku_merge_pairs(self): + self.assertEqual(rendaku_merge_pairs(("はち", 8), ("ちょう", 10**12)), + ("はっちょう", 8 * 10**12)) + self.assertEqual(rendaku_merge_pairs(("じゅう", 10), ("ちょう", 10**12)), + ("じゅっちょう", 10 * 10**12)) + + self.assertEqual(rendaku_merge_pairs(("いち", 1), ("けい", 10**16)), + ("いっけい", 1 * 10**16)) + self.assertEqual(rendaku_merge_pairs(("ろく", 6), ("けい", 10**16)), + ("ろっけい", 6 * 10**16)) + self.assertEqual(rendaku_merge_pairs(("はち", 8), ("けい", 10**16)), + ("はっけい", 8 * 10**16)) + self.assertEqual(rendaku_merge_pairs(("じゅう", 10), ("けい", 10**16)), + ("じゅっけい", 10 * 10**16)) + self.assertEqual(rendaku_merge_pairs(("ひゃく", 100), ("けい", 10**16)), + ("ひゃっけい", 100 * 10**16)) diff --git a/tests/test_kn.py b/tests/test_kn.py new file mode 100644 index 00000000..fa42cbd3 --- /dev/null +++ b/tests/test_kn.py @@ -0,0 +1,73 @@ +# -*- 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 Num2WordsKNTest(TestCase): + def test_numbers(self): + self.assertEqual(num2words(42, lang="kn"), u"ನಲವತ್ತ್ ಎರಡು") + self.assertEqual(num2words(893, lang="kn"), u"ಎಂಟು ನೂರ ತೊಂಬತ್ತ ಮೂರು") + self.assertEqual( + num2words(1729, lang="kn"), u"ಒಂದು ಸಾವಿರ ಏಳು ನೂರ ಇಪ್ಪತ್ತ್ಒಂಬತ್ತು" + ) + self.assertEqual(num2words(123, lang="kn"), u"ಒಂದು ನೂರ ಇಪ್ಪತ್ತ್ ಮೂರು") + self.assertEqual(num2words(32211, lang="kn"), + u"ಮೂವತ್ತ್ಎರಡು ಸಾವಿರ ಎರಡು ನೂರ ಹನ್ನೊಂದು") + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(3.14, lang="kn"), u"ಮೂರು ಬಿಂದು ಒಂದು ನಾಲ್ಕು") + self.assertEqual(num2words(1.61803, lang="kn"), + u"ಒಂದು ಬಿಂದು ಆರು ಒಂದು ಎಂಟು ಸೊನ್ನೆ ಮೂರು") + + def test_ordinal(self): + self.assertEqual( + num2words(1, lang='kn', to='ordinal'), + u'ಒಂದನೇ' + ) + self.assertEqual( + num2words(22, lang='kn', to='ordinal'), + u'ಇಪ್ಪತ್ತ್ ಎರಡನೇ' + ) + self.assertEqual( + num2words(12, lang='kn', to='ordinal'), + u'ಹನ್ನೆರಡನೇ' + ) + self.assertEqual( + num2words(130, lang='kn', to='ordinal'), + u'ಒಂದು ನೂರ ಮೂವತ್ತನೇ' + ) + self.assertEqual( + num2words(1003, lang='kn', to='ordinal'), + u'ಒಂದು ಸಾವಿರದ ಮೂರನೇ' + ) + self.assertEqual(num2words(2, lang="kn", ordinal=True), u"ಎರಡನೇ") + self.assertEqual(num2words(5, lang="kn", ordinal=True), u"ಐದನೇ") + self.assertEqual(num2words(16, lang="kn", ordinal=True), u"ಹದಿನಾರನೇ") + self.assertEqual(num2words(113, lang="kn", ordinal=True), + u"ಒಂದು ನೂರ ಹದಿಮೂರನೇ") + + def test_ordinal_num(self): + self.assertEqual(num2words(2, lang="kn", to='ordinal_num'), u"2ಎರಡನೇ") + self.assertEqual(num2words(5, lang="kn", to='ordinal_num'), u"5ಐದನೇ") + self.assertEqual(num2words(16, lang="kn", to='ordinal_num'), + u"16ಹದಿನಾರನೇ") + self.assertEqual(num2words(113, lang="kn", to='ordinal_num'), + u"113ಒಂದು ನೂರ ಹದಿಮೂರನೇ") diff --git a/tests/test_kz.py b/tests/test_kz.py new file mode 100644 index 00000000..83435640 --- /dev/null +++ b/tests/test_kz.py @@ -0,0 +1,81 @@ +# -*- 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsKZTest(TestCase): + def test_to_cardinal(self): + self.maxDiff = None + self.assertEqual(num2words(7, lang="kz"), "жеті") + self.assertEqual(num2words(23, lang="kz"), "жиырма үш") + self.assertEqual(num2words(145, lang="kz"), "жүз қырық бес") + self.assertEqual( + num2words(2869, lang="kz"), + "екі мың сегіз жүз алпыс тоғыз" + ) + self.assertEqual( + num2words(-789000125, lang="kz"), + "минус жеті жүз сексен тоғыз миллион жүз жиырма бес", + ) + self.assertEqual( + num2words(84932, lang="kz"), "сексен төрт мың тоғыз жүз отыз екі" + ) + + def test_to_cardinal_floats(self): + self.assertEqual(num2words(100.67, lang="kz"), "жүз бүтін алпыс жеті") + self.assertEqual(num2words(0.7, lang="kz"), "нөл бүтін жеті") + self.assertEqual(num2words(1.73, lang="kz"), "бір бүтін жетпіс үш") + self.assertEqual( + num2words(10.02, lang='kz'), + "он бүтін нөл екі" + ) + self.assertEqual( + num2words(15.007, lang='kz'), + "он бес бүтін нөл нөл жеті" + ) + + def test_to_ordinal(self): + with self.assertRaises(NotImplementedError): + num2words(1, lang="kz", to="ordinal") + + def test_to_currency(self): + self.assertEqual( + num2words(25.24, lang="kz", to="currency", currency="KZT"), + "жиырма бес теңге, жиырма төрт тиын", + ) + self.assertEqual( + num2words(1996.4, lang="kz", to="currency", currency="KZT"), + "бір мың тоғыз жүз тоқсан алты теңге, қырық тиын", + ) + self.assertEqual( + num2words(632924.51, lang="kz", to="currency", currency="KZT"), + "алты жүз отыз екі мың тоғыз жүз жиырма төрт теңге, елу бір тиын", + ) + self.assertEqual( + num2words(632924.513, lang="kz", to="currency", currency="KZT"), + "алты жүз отыз екі мың тоғыз жүз жиырма төрт теңге, елу бір тиын", + ) + self.assertEqual( + num2words(987654321.123, lang="kz", to="currency", currency="KZT"), + "тоғыз жүз сексен жеті миллион алты жүз елу төрт мың " + "үш жүз жиырма бір теңге, он екі тиын", + ) diff --git a/tests/test_lt.py b/tests/test_lt.py index 3c11e4ae..e8ddbb8b 100644 --- a/tests/test_lt.py +++ b/tests/test_lt.py @@ -68,6 +68,14 @@ def test_to_cardinal(self): num2words(-5000.22, lang='lt'), 'minus penki tūkstančiai kablelis dvidešimt du', ) + self.assertEqual( + num2words(10.02, lang='lt'), + "dešimt kablelis nulis du" + ) + self.assertEqual( + num2words(15.007, lang='lt'), + "penkiolika kablelis nulis nulis septyni" + ) def test_to_ordinal(self): # @TODO: implement to_ordinal diff --git a/tests/test_lv.py b/tests/test_lv.py index a0bffe9a..d0f69d26 100644 --- a/tests/test_lv.py +++ b/tests/test_lv.py @@ -63,6 +63,14 @@ def test_to_cardinal(self): num2words(-5000.22, lang='lv'), 'mīnus pieci tūkstoši komats divdesmit divi', ) + self.assertEqual( + num2words(10.02, lang='lv'), + "desmit komats nulle divi" + ) + self.assertEqual( + num2words(15.007, lang='lv'), + "piecpadsmit komats nulle nulle septiņi" + ) self.assertEqual(num2words(0, lang='lv'), 'nulle') self.assertEqual(num2words(5, lang='lv'), "pieci") @@ -106,12 +114,12 @@ def test_to_currency(self): ) self.assertEqual( - num2words(10111, lang='lv', to='currency', seperator=' un', + num2words(10111, lang='lv', to='currency', separator=' un', currency='EUR'), "simtu viens eiro un vienpadsmit centi" ) self.assertEqual( - num2words(10121, lang='lv', to='currency', seperator=' un', + num2words(10121, lang='lv', to='currency', separator=' un', currency='LVL'), "simtu viens lats un divdesmit viens santīms" ) @@ -122,26 +130,26 @@ def test_to_currency(self): " 85 centi" ) self.assertEqual( - num2words('38.4', lang='lv', to='currency', seperator=' un', + num2words('38.4', lang='lv', to='currency', separator=' un', cents=False, currency='EUR'), "trīsdesmit astoņi eiro un 40 centi" ) # EUR legal form self.assertEqual( - num2words('38.4', lang='lv', to='currency', seperator=' un', + num2words('38.4', lang='lv', to='currency', separator=' un', cents=False, currency='EUR_LEGAL'), "trīsdesmit astoņi euro un 40 centi" ) self.assertEqual( - num2words('38.4', lang='lv', to='currency', seperator=' un', + num2words('38.4', lang='lv', to='currency', separator=' un', cents=False, currency='USD', adjective=False), "trīsdesmit astoņi dolāri un 40 centi" ) self.assertEqual( - num2words('38.4', lang='lv', to='currency', seperator=' un', + num2words('38.4', lang='lv', to='currency', separator=' un', cents=False, currency='USD', adjective=True), "trīsdesmit astoņi ASV dolāri un 40 centi" ) diff --git a/tests/test_nl.py b/tests/test_nl.py index b3010621..95c690f4 100644 --- a/tests/test_nl.py +++ b/tests/test_nl.py @@ -36,6 +36,7 @@ def test_ordinal_more_than_twenty(self): ) def test_ordinal_at_crucial_number(self): + self.assertEqual(num2words(0, ordinal=True, lang='nl'), "nulde") self.assertEqual(num2words(100, ordinal=True, lang='nl'), "honderdste") self.assertEqual( num2words(1000, ordinal=True, lang='nl'), "duizendste" @@ -67,29 +68,52 @@ def test_ordinal_for_negative_numbers(self): def test_ordinal_for_floating_numbers(self): self.assertRaises(TypeError, num2words, 2.453, ordinal=True, lang='nl') - def test_to_currency(self): + def test_to_currency_eur(self): self.assertEqual( - num2words('38.4', lang='nl', to='currency', seperator=' en', + num2words('38.4', lang='nl', to='currency', separator=' en', cents=False, currency='EUR'), "achtendertig euro en 40 cent" ) self.assertEqual( - num2words('0', lang='nl', to='currency', seperator=' en', + num2words('0', lang='nl', to='currency', separator=' en', cents=False, currency='EUR'), "nul euro en 00 cent" ) self.assertEqual( - num2words('1.01', lang='nl', to='currency', seperator=' en', + num2words('1.01', lang='nl', to='currency', separator=' en', cents=True, currency='EUR'), "één euro en één cent" ) self.assertEqual( - num2words('4778.00', lang='nl', to='currency', seperator=' en', + num2words('4778.00', lang='nl', to='currency', separator=' en', cents=True, currency='EUR'), 'vierduizendzevenhonderdachtenzeventig euro en nul cent') + def test_to_currency_usd(self): + self.assertEqual( + num2words('38.4', lang='nl', to='currency', separator=' en', + cents=False, currency='USD'), + "achtendertig dollar en 40 cent" + ) + self.assertEqual( + num2words('0', lang='nl', to='currency', separator=' en', + cents=False, currency='USD'), + "nul dollar en 00 cent" + ) + + self.assertEqual( + num2words('1.01', lang='nl', to='currency', separator=' en', + cents=True, currency='USD'), + "één dollar en één cent" + ) + + self.assertEqual( + num2words('4778.00', lang='nl', to='currency', separator=' en', + cents=True, currency='USD'), + 'vierduizendzevenhonderdachtenzeventig dollar en nul cent') + def test_pluralize(self): n = Num2Word_NL() # euros always singular diff --git a/tests/test_no.py b/tests/test_no.py new file mode 100644 index 00000000..1b29061b --- /dev/null +++ b/tests/test_no.py @@ -0,0 +1,85 @@ +# 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsNOTest(TestCase): + def test_cardinal(self): + self.assertEqual(num2words(0, to="cardinal", lang="no"), "null") + self.assertEqual(num2words(1, to="cardinal", lang="no"), "en") + self.assertEqual(num2words(3, to="cardinal", lang="no"), "tre") + self.assertEqual(num2words(5, to="cardinal", lang="no"), "fem") + self.assertEqual(num2words(18, to="cardinal", lang="no"), "atten") + self.assertEqual(num2words(45, to="cardinal", lang="no"), "førtifem") + self.assertEqual(num2words(92, to="cardinal", lang="no"), "nittito") + self.assertEqual(num2words(1345, to="cardinal", lang="no"), + "en tusen tre hundre og førtifem") + self.assertEqual(num2words(4435, to="cardinal", lang="no"), + "fire tusen fire hundre og trettifem") + self.assertEqual(num2words(1004435, to="cardinal", lang="no"), + "en million fire tusen fire hundre og trettifem") + self.assertEqual(num2words(4335000, to="cardinal", lang="no"), + "fire million tre hundre og trettifem tusen") + self.assertEqual(num2words(14004535, to="cardinal", lang="no"), + "fjorten million fire tusen fem hundre og trettifem") + self.assertEqual(num2words(1.5, to="cardinal", lang="no"), + "en komma fem") + + def test_ordinal(self): + self.assertEqual(num2words(1, to="ordinal", lang="no"), "første") + self.assertEqual(num2words(5, to="ordinal", lang="no"), "femte") + self.assertEqual(num2words(10, to="ordinal", lang="no"), "tiende") + self.assertEqual(num2words(14, to="ordinal", lang="no"), "fjortende") + self.assertEqual(num2words(30, to="ordinal", lang="no"), "trettiende") + self.assertEqual(num2words(32, to="ordinal", lang="no"), "trettiandre") + self.assertEqual(num2words(100, to="ordinal", lang="no"), + "en hundrede") + self.assertEqual(num2words(1000, to="ordinal", lang="no"), + "en tusende") + self.assertEqual(num2words(1435, to="ordinal", lang="no"), + "en tusen fire hundre og trettifemte") + self.assertEqual(num2words(1000000, to="ordinal", lang="no"), + "en millionte") + + def test_ordinal_num(self): + self.assertEqual(num2words(1, to="ordinal_num", lang="no"), "1.") + self.assertEqual(num2words(5, to="ordinal_num", lang="no"), "5.") + self.assertEqual(num2words(10, to="ordinal_num", lang="no"), "10.") + self.assertEqual(num2words(14, to="ordinal_num", lang="no"), "14.") + self.assertEqual(num2words(32, to="ordinal_num", lang="no"), "32.") + + def test_year(self): + self.assertEqual(num2words(1835, to="year", lang="no"), + "atten hundre og trettifem") + self.assertEqual(num2words(2015, to="year", lang="no"), + "to tusen og femten") + + def test_currency(self): + self.assertEqual(num2words(1.00, to="currency", lang="no"), "en krone") + self.assertEqual(num2words(2.00, to="currency", lang="no"), + "to kroner") + self.assertEqual(num2words(2.50, to="currency", lang="no"), + "to kroner og femti øre") + self.assertEqual(num2words(135.00, to="currency", lang="no"), + "en hundre og trettifem kroner") + self.assertEqual(num2words(135.59, to="currency", lang="no"), + "en hundre og trettifem kroner og femtini øre") diff --git a/tests/test_pl.py b/tests/test_pl.py index abc34b9b..08ef0394 100644 --- a/tests/test_pl.py +++ b/tests/test_pl.py @@ -24,14 +24,24 @@ class Num2WordsPLTest(TestCase): def test_cardinal(self): + self.assertEqual(num2words(90, lang='pl'), "dziewięćdziesiąt") self.assertEqual(num2words(100, lang='pl'), "sto") self.assertEqual(num2words(101, lang='pl'), "sto jeden") self.assertEqual(num2words(110, lang='pl'), "sto dziesięć") self.assertEqual(num2words(115, lang='pl'), "sto piętnaście") self.assertEqual(num2words(123, lang='pl'), "sto dwadzieścia trzy") + self.assertEqual(num2words(400, lang='pl'), "czterysta") self.assertEqual(num2words(1000, lang='pl'), "tysiąc") self.assertEqual(num2words(1001, lang='pl'), "tysiąc jeden") self.assertEqual(num2words(2012, lang='pl'), "dwa tysiące dwanaście") + self.assertEqual( + num2words(10.02, lang='pl'), + "dziesięć przecinek zero dwa" + ) + self.assertEqual( + num2words(15.007, lang='pl'), + "piętnaście przecinek zero zero siedem" + ) self.assertEqual( num2words(12519.85, lang='pl'), "dwanaście tysięcy pięćset dziewiętnaście przecinek " @@ -44,7 +54,7 @@ def test_cardinal(self): self.assertEqual( num2words(1234567890, lang='pl'), "miliard dwieście trzydzieści cztery miliony pięćset " - "sześćdziesiąt siedem tysięcy osiemset dziewięćdzisiąt" + "sześćdziesiąt siedem tysięcy osiemset dziewięćdziesiąt" ) self.assertEqual( num2words(10000000001000000100000, lang='pl'), @@ -54,20 +64,20 @@ def test_cardinal(self): num2words(215461407892039002157189883901676, lang='pl'), "dwieście piętnaście kwintylionów czterysta sześćdziesiąt jeden " "kwadryliardów czterysta siedem kwadrylionów osiemset " - "dziewięćdzisiąt dwa tryliardy trzydzieści dziewięć trylionów " + "dziewięćdziesiąt dwa tryliardy trzydzieści dziewięć trylionów " "dwa biliardy sto pięćdziesiąt siedem bilionów sto osiemdziesiąt " "dziewięć miliardów osiemset osiemdziesiąt trzy miliony " "dziewięćset jeden tysięcy sześćset siedemdziesiąt sześć" ) self.assertEqual( num2words(719094234693663034822824384220291, lang='pl'), - "siedemset dziewiętnaście kwintylionów dziewięćdzisiąt cztery " + "siedemset dziewiętnaście kwintylionów dziewięćdziesiąt cztery " "kwadryliardy dwieście trzydzieści cztery kwadryliony sześćset " - "dziewięćdzisiąt trzy tryliardy sześćset sześćdziesiąt trzy " + "dziewięćdziesiąt trzy tryliardy sześćset sześćdziesiąt trzy " "tryliony trzydzieści cztery biliardy osiemset dwadzieścia dwa " "biliony osiemset dwadzieścia cztery miliardy trzysta " "osiemdziesiąt cztery miliony dwieście dwadzieścia " - "tysięcy dwieście dziewięćdzisiąt jeden" + "tysięcy dwieście dziewięćdziesiąt jeden" ) self.assertEqual( num2words( @@ -83,9 +93,39 @@ def test_cardinal(self): ) def test_to_ordinal(self): - # @TODO: implement to_ordinal + self.assertEqual(num2words(100, lang='pl', to='ordinal'), "setny") + self.assertEqual( + num2words(101, lang='pl', to='ordinal'), "sto pierwszy") + self.assertEqual(num2words(120, lang='pl', to='ordinal'), + "sto dwudziesty") + self.assertEqual(num2words(20, lang='pl', to='ordinal'), "dwudziesty") + self.assertEqual(num2words(121, lang='pl', to='ordinal'), + "sto dwudziesty pierwszy") + self.assertEqual( + num2words(115, lang='pl', to='ordinal'), "sto piętnasty") + self.assertEqual( + num2words(25, lang='pl', to='ordinal'), "dwudziesty piąty") + self.assertEqual(num2words(1021, lang='pl', to='ordinal'), + "tysiąc dwudziesty pierwszy") + self.assertEqual( + num2words(120, lang='pl', to='ordinal'), "sto dwudziesty") + self.assertEqual(num2words(1000021, lang='pl', + to='ordinal'), "milion dwudziesty pierwszy") + self.assertEqual(num2words(1000, lang='pl', to='ordinal'), "tysięczny") + self.assertEqual(num2words(10000, lang='pl', + to='ordinal'), "dziesięciotysięczny") + self.assertEqual(num2words(100000000, lang='pl', + to='ordinal'), "stumilionowy") + self.assertEqual(num2words(1002000, lang='pl', + to='ordinal'), "milion dwutysięczny") + self.assertEqual(num2words(1001000, lang='pl', + to='ordinal'), "milion tysięczny") + self.assertEqual(num2words(1000000, lang='pl', + to='ordinal'), "milionowy") + + def test_to_ordinal_error(self): with self.assertRaises(NotImplementedError): - num2words(1, lang='pl', to='ordinal') + num2words(1.5, lang='pl', to='ordinal') def test_currency(self): self.assertEqual( @@ -106,12 +146,12 @@ def test_currency(self): ) self.assertEqual( num2words(10111, lang='pl', to='currency', currency='EUR', - seperator=' i'), + separator=' i'), "sto jeden euro i jedenaście centów" ) self.assertEqual( num2words(10121, lang='pl', to='currency', currency='PLN', - seperator=' i'), + separator=' i'), "sto jeden złotych i dwadzieścia jeden groszy" ) self.assertEqual( @@ -120,7 +160,7 @@ def test_currency(self): ) self.assertEqual( num2words(123.50, lang='pl', to='currency', currency='PLN', - seperator=' i'), + separator=' i'), "sto dwadzieścia trzy złote i pięćdziesiąt groszy" ) self.assertEqual( diff --git a/tests/test_pt_BR.py b/tests/test_pt_BR.py index bbf9e8d6..87e231bc 100644 --- a/tests/test_pt_BR.py +++ b/tests/test_pt_BR.py @@ -80,6 +80,12 @@ def test_cardinal_integer(self): self.assertEqual( num2words(6000000, lang='pt_BR'), 'seis milhões' ) + self.assertEqual( + num2words(100000000, lang='pt_BR'), 'cem milhões' + ) + self.assertEqual( + num2words(100000000000, lang='pt_BR'), 'cem bilhões' + ) self.assertEqual( num2words(19000000000, lang='pt_BR'), 'dezenove bilhões' ) diff --git a/tests/test_ro.py b/tests/test_ro.py index b5e6c516..4089ddd0 100644 --- a/tests/test_ro.py +++ b/tests/test_ro.py @@ -103,7 +103,7 @@ def test_big_numbers(self): ) self.assertEqual( num2words(247000000000, lang="ro"), - u"două sute patruzeci și șapte miliarde" + u"două sute patruzeci și șapte de miliarde" ) def test_overflow(self): @@ -116,24 +116,46 @@ def test_overflow(self): "0000000000000000000000000000000000000") def test_to_currency(self): + self.assertEqual( + num2words(1000, lang='ro', to='currency'), + u'una mie de lei' + ) + self.assertEqual( + num2words(101, lang='ro', to='currency'), + u'una sută unu lei' + ) + self.assertEqual( + num2words(100, lang='ro', to='currency'), + u'una sută de lei' + ) self.assertEqual( num2words(38.4, lang='ro', to='currency'), - u'treizeci și opt lei și patruzeci bani' + u'treizeci și opt de lei și patruzeci de bani' ) - self.assertEqual( num2words(1.01, lang='ro', to='currency'), u'un leu și un ban' ) - self.assertEqual( num2words(4778.00, lang='ro', to='currency'), - u'patru mii șapte sute șaptezeci și opt lei') - + u'patru mii șapte sute șaptezeci și opt de lei') self.assertEqual( num2words(4778.32, lang='ro', to='currency'), - u'patru mii șapte sute șaptezeci și opt lei' - u' și treizeci și doi bani') + u'patru mii șapte sute șaptezeci și opt de lei' + u' și treizeci și doi de bani') + self.assertEqual( + num2words(1207, lang='ro', to='currency'), + u'una mie două sute șapte lei') + self.assertEqual( + num2words(22000, lang='ro', to='currency'), + u'douăzeci și două de mii de lei') + self.assertEqual( + num2words(80000, lang='ro', to='currency'), + u'optzeci de mii de lei') + self.assertEqual( + num2words(123456789, lang='ro', to='currency'), + u'una sută douăzeci și trei milioane patru sute ' + u'cincizeci și șase de mii șapte sute optzeci și nouă de lei') def test_to_year(self): self.assertEqual(num2words(1989, lang='ro', to='year'), diff --git a/tests/test_ru.py b/tests/test_ru.py index 9c35b767..206873c4 100644 --- a/tests/test_ru.py +++ b/tests/test_ru.py @@ -35,7 +35,9 @@ def test_cardinal(self): self.assertEqual(num2words(2012, lang='ru'), "две тысячи двенадцать") self.assertEqual( num2words(12519.85, lang='ru'), - "двенадцать тысяч пятьсот девятнадцать запятая восемьдесят пять") + "двенадцать тысяч пятьсот девятнадцать целых восемьдесят пять " + "сотых" + ) self.assertEqual( num2words(1234567890, lang='ru'), "один миллиард двести тридцать четыре миллиона пятьсот " @@ -73,14 +75,69 @@ def test_cardinal(self): self.assertEqual(num2words(-15, lang='ru'), "минус пятнадцать") self.assertEqual(num2words(-100, lang='ru'), "минус сто") - def test_floating_point(self): - self.assertEqual(num2words(5.2, lang='ru'), "пять запятая два") + def test_cardinal_feminine(self): + self.assertEqual(num2words(1, lang='ru', gender='f'), 'одна') + self.assertEqual(num2words(2, lang='ru', gender='f'), 'две') + self.assertEqual(num2words(3, lang='ru', gender='f'), 'три') + self.assertEqual(num2words(100, lang='ru', gender='f'), "сто") + self.assertEqual(num2words(101, lang='ru', gender='f'), "сто одна") + self.assertEqual(num2words(110, lang='ru', gender='f'), "сто десять") + self.assertEqual( + num2words(115, lang='ru', gender='f'), "сто пятнадцать" + ) + self.assertEqual( + num2words(122, lang='ru', gender='f'), "сто двадцать две" + ) + self.assertEqual( + num2words(125.1, lang='ru', gender='f'), + 'сто двадцать пять целых одна десятая' + ) + self.assertEqual(num2words(-1, lang='ru', gender='f'), "минус одна") + self.assertEqual(num2words(-100, lang='ru', gender='f'), "минус сто") + + def test_cardinal_neuter(self): + self.assertEqual(num2words(1, lang='ru', gender='n'), 'одно') + self.assertEqual(num2words(2, lang='ru', gender='n'), 'два') + self.assertEqual(num2words(3, lang='ru', gender='n'), 'три') + self.assertEqual(num2words(100, lang='ru', gender='n'), "сто") + self.assertEqual(num2words(101, lang='ru', gender='n'), "сто одно") + self.assertEqual(num2words(110, lang='ru', gender='n'), "сто десять") + self.assertEqual( + num2words(115, lang='ru', gender='n'), "сто пятнадцать" + ) self.assertEqual( - num2words(561.42, lang='ru'), - "пятьсот шестьдесят один запятая сорок два" + num2words(122, lang='ru', gender='n'), "сто двадцать два" ) + self.assertEqual( + num2words(125.1, lang='ru', gender='n'), + 'сто двадцать пять целых одна десятая') + self.assertEqual(num2words(-1, lang='ru', gender='n'), "минус одно") + self.assertEqual(num2words(-100, lang='ru', gender='n'), "минус сто") + + def test_floating_point(self): + self.assertEqual(num2words(5.2, lang='ru'), "пять целых две десятых") + self.assertEqual(num2words(5.0, lang='ru'), "пять целых ноль десятых") + self.assertEqual(num2words(5.10, lang='ru'), "пять целых одна десятая") + self.assertEqual(num2words("5.10", lang='ru'), + "пять целых десять сотых") + self.assertEqual(num2words(1.001, lang='ru'), + "одна целая одна тысячная") + self.assertEqual(num2words(1.011, lang='ru'), + "одна целая одиннадцать тысячных") + self.assertEqual(num2words(10.02, lang='ru'), + "десять целых две сотых") + self.assertEqual(num2words(15.007, lang='ru'), + "пятнадцать целых семь тысячных") + self.assertEqual(num2words(561.42, lang='ru'), + "пятьсот шестьдесят одна целая сорок две сотых") + self.assertEqual(num2words(561.00001, lang='ru'), + "пятьсот шестьдесят одна целая одна стотысячная") def test_to_ordinal(self): + self.assertEqual( + num2words(0, lang='ru', to='ordinal'), + 'нулевой' + ) self.assertEqual( num2words(1, lang='ru', to='ordinal'), 'первый' @@ -134,22 +191,187 @@ def test_to_ordinal(self): num2words(1001, lang='ru', to='ordinal'), 'тысяча первый' ) + self.assertEqual( + num2words(1060, lang='ru', to='ordinal'), + 'тысяча шестидесятый' + ) self.assertEqual( num2words(2000, lang='ru', to='ordinal'), - 'двух тысячный' + 'двухтысячный' ) self.assertEqual( num2words(10000, lang='ru', to='ordinal'), - 'десяти тысячный' + 'десятитысячный' + ) + self.assertEqual( + num2words(90000, lang='ru', to='ordinal'), + 'девяностотысячный' + ) + self.assertEqual( + num2words(21000, lang='ru', to='ordinal'), + 'двадцатиоднотысячный' + ) + self.assertEqual( + num2words(130000, lang='ru', to='ordinal'), + 'стотридцатитысячный' + ) + self.assertEqual( + num2words(135000, lang='ru', to='ordinal'), + 'стотридцатипятитысячный' + ) + self.assertEqual( + num2words(135100, lang='ru', to='ordinal'), + 'сто тридцать пять тысяч сотый' + ) + self.assertEqual( + num2words(135120, lang='ru', to='ordinal'), + 'сто тридцать пять тысяч сто двадцатый' + ) + self.assertEqual( + num2words(135121, lang='ru', to='ordinal'), + 'сто тридцать пять тысяч сто двадцать первый' + ) + self.assertEqual( + num2words(190000, lang='ru', to='ordinal'), + 'стодевяностотысячный' ) self.assertEqual( num2words(1000000, lang='ru', to='ordinal'), 'миллионный' ) + self.assertEqual( + num2words(2000000, lang='ru', to='ordinal'), + 'двухмиллионный' + ) + self.assertEqual( + num2words(5135000, lang='ru', to='ordinal'), + 'пять миллионов стотридцатипятитысячный' + ) + self.assertEqual( + num2words(21000000, lang='ru', to='ordinal'), + 'двадцатиодномиллионный' + ) self.assertEqual( num2words(1000000000, lang='ru', to='ordinal'), 'миллиардный' ) + self.assertEqual( + num2words(123456000000, lang='ru', to='ordinal'), + 'сто двадцать три миллиарда четырёхсотпятидесятишестимиллионный' + ) + + def test_to_ordinal_feminine(self): + self.assertEqual( + num2words(1, lang='ru', to='ordinal', gender='f'), 'первая' + ) + self.assertEqual( + num2words(3, lang='ru', to='ordinal', gender='f'), 'третья' + ) + self.assertEqual( + num2words(10, lang='ru', to='ordinal', gender='f'), 'десятая' + ) + self.assertEqual( + num2words(23, lang='ru', to='ordinal', gender='f'), + 'двадцать третья' + ) + self.assertEqual( + num2words(1000, lang='ru', to='ordinal', gender='f'), 'тысячная' + ) + self.assertEqual( + num2words(2000000, lang='ru', to='ordinal', gender='f'), + 'двухмиллионная' + ) + + def test_to_ordinal_neuter(self): + self.assertEqual( + num2words(1, lang='ru', to='ordinal', gender='n'), 'первое' + ) + self.assertEqual( + num2words(3, lang='ru', to='ordinal', gender='n'), 'третье' + ) + self.assertEqual( + num2words(10, lang='ru', to='ordinal', gender='n'), 'десятое' + ) + self.assertEqual( + num2words(23, lang='ru', to='ordinal', gender='n'), + 'двадцать третье' + ) + self.assertEqual( + num2words(1000, lang='ru', to='ordinal', gender='n'), 'тысячное' + ) + self.assertEqual( + num2words(2000000, lang='ru', to='ordinal', gender='n'), + 'двухмиллионное' + ) + + def test_cardinal_cases(self): + self.assertEqual( + num2words(1, lang='ru', case='nominative'), 'один') + self.assertEqual( + num2words(1, lang='ru', case='genitive'), 'одного') + self.assertEqual( + num2words(1, lang='ru', case='a', plural=True, animate=False), + 'одни') + self.assertEqual( + num2words(2, lang='ru', case='a', gender='f', animate=True), + 'двух') + self.assertEqual( + num2words(2, lang='ru', case='a', gender='f', animate=False), + 'две') + self.assertEqual( + num2words(100, lang='ru', case='g'), + 'ста') + self.assertEqual( + num2words(122, lang='ru', case='d'), + 'ста двадцати двум') + self.assertEqual( + num2words(1000, lang='ru', case='p'), + 'одной тысяче') + self.assertEqual( + num2words(1122, lang='ru', case='p'), + 'одной тысяче ста двадцати двух') + self.assertEqual( + num2words(1211, lang='ru', case='i', gender='f'), + 'одной тысячей двумястами одиннадцатью') + self.assertEqual( + num2words(5121000, lang='ru', case='i'), + 'пятью миллионами ста двадцатью одной тысячей') + + def test_ordinal_cases(self): + self.assertEqual( + num2words(1, lang='ru', to='ordinal', case='nominative'), 'первый') + self.assertEqual( + num2words(1, lang='ru', to='ordinal', case='genitive'), 'первого') + self.assertEqual( + num2words(1, lang='ru', to='ordinal', case='a', plural=True, + animate=False), + 'первые') + self.assertEqual( + num2words(2, lang='ru', to='ordinal', case='a', gender='f', + animate=True), + 'вторую') + self.assertEqual( + num2words(2, lang='ru', to='ordinal', case='a', gender='f', + animate=False), + 'вторую') + self.assertEqual( + num2words(100, lang='ru', to='ordinal', case='g'), + 'сотого') + self.assertEqual( + num2words(122, lang='ru', to='ordinal', case='d'), + 'сто двадцать второму') + self.assertEqual( + num2words(1000, lang='ru', to='ordinal', case='p'), + 'тысячном') + self.assertEqual( + num2words(1122, lang='ru', to='ordinal', case='p'), + 'тысяча сто двадцать втором') + self.assertEqual( + num2words(1211, lang='ru', to='ordinal', case='i', gender='f'), + 'тысяча двести одиннадцатой') + self.assertEqual( + num2words(5121000, lang='ru', to='ordinal', case='i'), + 'пять миллионов стодвадцатиоднотысячным') def test_to_currency(self): self.assertEqual( @@ -160,6 +382,10 @@ def test_to_currency(self): num2words(1.0, lang='ru', to='currency', currency='RUB'), 'один рубль, ноль копеек' ) + self.assertEqual( + num2words(1.0, lang='ru', to='currency', currency='UAH'), + 'одна гривна, ноль копеек' + ) self.assertEqual( num2words(1234.56, lang='ru', to='currency', currency='EUR'), 'одна тысяча двести тридцать четыре евро, пятьдесят шесть центов' @@ -168,25 +394,54 @@ def test_to_currency(self): num2words(1234.56, lang='ru', to='currency', currency='RUB'), 'одна тысяча двести тридцать четыре рубля, пятьдесят шесть копеек' ) + self.assertEqual( + num2words(1234.56, lang='ru', to='currency', currency='UAH'), + 'одна тысяча двести тридцать четыре гривны, пятьдесят шесть копеек' + ) self.assertEqual( num2words(10111, lang='ru', to='currency', currency='EUR', - seperator=' и'), + separator=' и'), 'сто один евро и одиннадцать центов' ) + self.assertEqual( + num2words(10111, lang='ru', to='currency', currency='RUB', + separator=' и'), + 'сто один рубль и одиннадцать копеек' + ) + self.assertEqual( + num2words(10111, lang='ru', to='currency', currency='UAH', + separator=' и'), + 'сто одна гривна и одиннадцать копеек' + ) + self.assertEqual( + num2words(10121, lang='ru', to='currency', currency='EUR', + separator=' и'), + 'сто один евро и двадцать один цент' + ) self.assertEqual( num2words(10121, lang='ru', to='currency', currency='RUB', - seperator=' и'), + separator=' и'), 'сто один рубль и двадцать одна копейка' ) + self.assertEqual( + num2words(10121, lang='ru', to='currency', currency='UAH', + separator=' и'), + 'сто одна гривна и двадцать одна копейка' + ) + self.assertEqual( + num2words(10122, lang='ru', to='currency', currency='EUR', + separator=' и'), + 'сто один евро и двадцать два цента' + ) self.assertEqual( num2words(10122, lang='ru', to='currency', currency='RUB', - seperator=' и'), + separator=' и'), 'сто один рубль и двадцать две копейки' ) self.assertEqual( - num2words(10121, lang='ru', to='currency', currency='EUR', - seperator=' и'), - 'сто один евро и двадцать один цент' + num2words(10122, lang='ru', to='currency', currency='UAH', + separator=' и'), + 'сто одна гривна и двадцать две копейки' ) self.assertEqual( num2words(-1251985, lang='ru', to='currency', currency='EUR', @@ -194,10 +449,30 @@ def test_to_currency(self): 'минус двенадцать тысяч пятьсот девятнадцать евро, 85 центов' ) self.assertEqual( - num2words('38.4', lang='ru', to='currency', seperator=' и', + num2words(-1251985, lang='ru', to='currency', currency='RUB', + cents=False), + 'минус двенадцать тысяч пятьсот девятнадцать рублей, 85 копеек' + ) + self.assertEqual( + num2words(-1251985, lang='ru', to='currency', currency='UAH', + cents=False), + 'минус двенадцать тысяч пятьсот девятнадцать гривен, 85 копеек' + ) + self.assertEqual( + num2words('38.4', lang='ru', to='currency', separator=' и', cents=False, currency='EUR'), "тридцать восемь евро и 40 центов" ) + self.assertEqual( + num2words('38.4', lang='ru', to='currency', separator=' и', + cents=False, currency='RUB'), + "тридцать восемь рублей и 40 копеек" + ) + self.assertEqual( + num2words('38.4', lang='ru', to='currency', separator=' и', + cents=False, currency='UAH'), + "тридцать восемь гривен и 40 копеек" + ) self.assertEqual( num2words('1230.56', lang='ru', to='currency', currency='USD'), 'одна тысяча двести тридцать долларов, пятьдесят шесть центов' @@ -211,3 +486,8 @@ def test_to_currency(self): 'одна тысяча двести тридцать четыре доллара, пятьдесят шесть ' 'центов' ) + self.assertEqual( + num2words(10122, lang='ru', to='currency', currency='UZS', + separator=' и'), + 'сто один сум и двадцать два тийина' + ) diff --git a/tests/test_sk.py b/tests/test_sk.py new file mode 100644 index 00000000..314a7c2b --- /dev/null +++ b/tests/test_sk.py @@ -0,0 +1,98 @@ + +# -*- 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsSKTest(TestCase): + def test_cardinal(self): + self.assertEqual(num2words(100, lang='sk'), "sto") + self.assertEqual(num2words(101, lang='sk'), "stojeden") + self.assertEqual(num2words(110, lang='sk'), "stodesať") + self.assertEqual(num2words(115, lang='sk'), "stopätnásť") + self.assertEqual(num2words(123, lang='sk'), "stodvadsaťtri") + self.assertEqual(num2words(1000, lang='sk'), "tisíc") + self.assertEqual(num2words(1001, lang='sk'), "tisícjeden") + self.assertEqual(num2words(2012, lang='sk'), "dvetisícdvanásť") + self.assertEqual( + num2words(10.02, lang='sk'), + "desať celých nula dva" + ) + self.assertEqual( + num2words(15.007, lang='sk'), + "pätnásť celých nula nula sedem" + ) + self.assertEqual( + num2words(12519.85, lang='sk'), + "dvanásťtisícpäťstodevätnásť celých osemdesiatpäť" + ) + self.assertEqual( + num2words(123.50, lang='sk'), + "stodvadsaťtri celých päť" + ) + self.assertEqual( + num2words(1234567890, lang='sk'), + "miliarda dvestotridsaťštyri miliónov päťstošesťdesiat" + "sedemtisícosemstodeväťdesiat" + ) + self.assertEqual( + num2words(215461407892039002157189883901676, lang='sk'), + "dvestopätnásť kvintiliónov štyristošesťdesiatjeden kvadriliárd " + "štyristosedem kvadriliónov osemstodeväťdesiatdva triliárd " + "tridsaťdeväť triliónov dve biliardy stopäťdesiatsedem biliónov " + "stoosemdesiatdeväť miliárd osemstoosemdesiattri miliónov " + "deväťstojedentisícšesťstosedemdesiatšesť" + ) + self.assertEqual( + num2words(719094234693663034822824384220291, lang='sk'), + "sedemstodevätnásť kvintiliónov deväťdesiatštyri kvadriliárd " + "dvestotridsaťštyri kvadriliónov šesťstodeväťdesiattri triliárd " + "šesťstošesťdesiattri triliónov tridsaťštyri biliárd " + "osemstodvadsaťdva biliónov osemstodvadsaťštyri miliárd " + "tristoosemdesiatštyri miliónov " + "dvestodvadsaťtisícdvestodeväťdesiatjeden" + ) + + def test_to_ordinal(self): + # @TODO: implement to_ordinal + with self.assertRaises(NotImplementedError): + num2words(1, lang='sk', to='ordinal') + + def test_currency(self): + self.assertEqual( + num2words(10.0, lang='sk', to='currency', currency='EUR'), + "desať eur, nula centov") + self.assertEqual( + num2words(1234.56, lang='sk', to='currency', currency='EUR'), + "tisícdvestotridsaťštyri eur, päťdesiatšesť centov") + self.assertEqual( + num2words(101.11, lang='sk', to='currency', currency='EUR', + separator=' a'), + "stojeden eur a jedenásť centov") + self.assertEqual( + num2words(-12519.85, lang='sk', to='currency', cents=False), + "mínus dvanásťtisícpäťstodevätnásť eur, 85 centov" + ) + self.assertEqual( + num2words(19.50, lang='sk', to='currency', cents=False), + "devätnásť eur, 50 centov" + ) diff --git a/tests/test_sl.py b/tests/test_sl.py index cc781683..77827baf 100644 --- a/tests/test_sl.py +++ b/tests/test_sl.py @@ -22,7 +22,7 @@ from num2words import num2words -class Num2WordsDETest(TestCase): +class Num2WordsSLTest(TestCase): def test_ordinal_less_than_twenty(self): self.assertEqual(num2words(2, ordinal=True, lang='sl'), "drugi") self.assertEqual(num2words(4, ordinal=True, lang='sl'), "četrti") @@ -43,17 +43,160 @@ def test_ordinal_at_crucial_number(self): num2words(4000, ordinal=True, lang='sl'), "štiritisoči" ) self.assertEqual( - num2words(2000000, ordinal=True, lang='sl'), "dvemiljonti" + num2words(2000000, ordinal=True, lang='sl'), "dvamilijonti" ) self.assertEqual( - num2words(5000000000, ordinal=True, lang='sl'), "petmiljardti" + num2words(5000000000, ordinal=True, lang='sl'), "petmilijardti" ) + def test_ordinal_numbers_from_repository_of_test_cases(self): + # Tests were compiled from cases in + # https://github.com/gregopet/zapis-slovenskih-stevil + # The male gender is used by the project so those test cases were + # copied + self.assertEqual(num2words(1, ordinal=True, lang='sl'), "prvi") + self.assertEqual(num2words(2, ordinal=True, lang='sl'), "drugi") + self.assertEqual(num2words(3, ordinal=True, lang='sl'), "tretji") + self.assertEqual(num2words(4, ordinal=True, lang='sl'), "četrti") + self.assertEqual(num2words(5, ordinal=True, lang='sl'), "peti") + self.assertEqual(num2words(6, ordinal=True, lang='sl'), "šesti") + self.assertEqual(num2words(7, ordinal=True, lang='sl'), "sedmi") + self.assertEqual(num2words(8, ordinal=True, lang='sl'), "osmi") + self.assertEqual(num2words(9, ordinal=True, lang='sl'), "deveti") + self.assertEqual(num2words(10, ordinal=True, lang='sl'), "deseti") + self.assertEqual(num2words(100, ordinal=True, lang='sl'), "stoti") + self.assertEqual(num2words(101, ordinal=True, lang='sl'), "stoprvi") + self.assertEqual(num2words(102, ordinal=True, lang='sl'), "stodrugi") + self.assertEqual(num2words(103, ordinal=True, lang='sl'), "stotretji") + self.assertEqual(num2words(104, ordinal=True, lang='sl'), "stočetrti") + self.assertEqual(num2words(105, ordinal=True, lang='sl'), "stopeti") + self.assertEqual(num2words(106, ordinal=True, lang='sl'), "stošesti") + self.assertEqual(num2words(200, ordinal=True, lang='sl'), "dvestoti") + self.assertEqual(num2words(1000, ordinal=True, lang='sl'), "tisoči") + self.assertEqual(num2words(1001, ordinal=True, lang='sl'), "tisočprvi") + self.assertEqual(num2words(1002, ordinal=True, lang='sl'), + "tisočdrugi") + self.assertEqual(num2words(1003, ordinal=True, lang='sl'), + "tisočtretji") + self.assertEqual(num2words(1004, ordinal=True, lang='sl'), + "tisoččetrti") + self.assertEqual(num2words(1005, ordinal=True, lang='sl'), + "tisočpeti") + self.assertEqual(num2words(1006, ordinal=True, lang='sl'), + "tisočšesti") + self.assertEqual(num2words(2000, ordinal=True, lang='sl'), + "dvatisoči") + self.assertEqual(num2words(20000, ordinal=True, lang='sl'), + "dvajsettisoči") + self.assertEqual(num2words(200000, ordinal=True, lang='sl'), + "dvestotisoči") + self.assertEqual(num2words(1000000, ordinal=True, lang='sl'), + "milijonti") + self.assertEqual(num2words(2000000, ordinal=True, lang='sl'), + "dvamilijonti") + self.assertEqual(num2words(3000000, ordinal=True, lang='sl'), + "trimilijonti") + self.assertEqual(num2words(101000000, ordinal=True, lang='sl'), + "stoenmilijonti") + self.assertEqual(num2words(202000000, ordinal=True, lang='sl'), + "dvestodvamilijonti") + self.assertEqual(num2words(1121, ordinal=True, lang='sl'), + "tisočstoenaindvajseti") + self.assertEqual(num2words(2405, ordinal=True, lang='sl'), + "dvatisočštiristopeti") + def test_cardinal_at_some_numbers(self): self.assertEqual(num2words(2, lang='sl'), "dve") self.assertEqual(num2words(4000, lang='sl'), "štiri tisoč") - self.assertEqual(num2words(2000000, lang='sl'), "dva miljona") - self.assertEqual(num2words(4000000000, lang='sl'), "štiri miljarde") + self.assertEqual(num2words(2000000, lang='sl'), "dva milijona") + self.assertEqual(num2words(4000000000, lang='sl'), "štiri milijarde") + + def test_cardinal_numbers_from_repository_of_test_cases(self): + # Tests were compiled from cases in + # https://github.com/gregopet/zapis-slovenskih-stevil + self.assertEqual(num2words(0, lang='sl'), "nič") + self.assertEqual(num2words(1, lang='sl'), "ena") + self.assertEqual(num2words(2, lang='sl'), "dve") + self.assertEqual(num2words(3, lang='sl'), "tri") + self.assertEqual(num2words(4, lang='sl'), "štiri") + self.assertEqual(num2words(5, lang='sl'), "pet") + self.assertEqual(num2words(6, lang='sl'), "šest") + self.assertEqual(num2words(7, lang='sl'), "sedem") + self.assertEqual(num2words(8, lang='sl'), "osem") + self.assertEqual(num2words(9, lang='sl'), "devet") + self.assertEqual(num2words(10, lang='sl'), "deset") + self.assertEqual(num2words(11, lang='sl'), "enajst") + self.assertEqual(num2words(12, lang='sl'), "dvanajst") + self.assertEqual(num2words(13, lang='sl'), "trinajst") + self.assertEqual(num2words(14, lang='sl'), "štirinajst") + self.assertEqual(num2words(15, lang='sl'), "petnajst") + self.assertEqual(num2words(16, lang='sl'), "šestnajst") + self.assertEqual(num2words(17, lang='sl'), "sedemnajst") + self.assertEqual(num2words(18, lang='sl'), "osemnajst") + self.assertEqual(num2words(19, lang='sl'), "devetnajst") + self.assertEqual(num2words(20, lang='sl'), "dvajset") + self.assertEqual(num2words(21, lang='sl'), "enaindvajset") + self.assertEqual(num2words(22, lang='sl'), "dvaindvajset") + self.assertEqual(num2words(23, lang='sl'), "triindvajset") + self.assertEqual(num2words(24, lang='sl'), "štiriindvajset") + self.assertEqual(num2words(25, lang='sl'), "petindvajset") + self.assertEqual(num2words(26, lang='sl'), "šestindvajset") + self.assertEqual(num2words(27, lang='sl'), "sedemindvajset") + self.assertEqual(num2words(28, lang='sl'), "osemindvajset") + self.assertEqual(num2words(29, lang='sl'), "devetindvajset") + self.assertEqual(num2words(30, lang='sl'), "trideset") + self.assertEqual(num2words(40, lang='sl'), "štirideset") + self.assertEqual(num2words(50, lang='sl'), "petdeset") + self.assertEqual(num2words(60, lang='sl'), "šestdeset") + self.assertEqual(num2words(70, lang='sl'), "sedemdeset") + self.assertEqual(num2words(80, lang='sl'), "osemdeset") + self.assertEqual(num2words(90, lang='sl'), "devetdeset") + self.assertEqual(num2words(100, lang='sl'), "sto") + self.assertEqual(num2words(101, lang='sl'), "sto ena") + self.assertEqual(num2words(102, lang='sl'), "sto dve") + self.assertEqual(num2words(103, lang='sl'), "sto tri") + self.assertEqual(num2words(104, lang='sl'), "sto štiri") + self.assertEqual(num2words(105, lang='sl'), "sto pet") + self.assertEqual(num2words(106, lang='sl'), "sto šest") + self.assertEqual(num2words(200, lang='sl'), "dvesto") + self.assertEqual(num2words(300, lang='sl'), "tristo") + self.assertEqual(num2words(400, lang='sl'), "štiristo") + self.assertEqual(num2words(500, lang='sl'), "petsto") + self.assertEqual(num2words(600, lang='sl'), "šeststo") + self.assertEqual(num2words(700, lang='sl'), "sedemsto") + self.assertEqual(num2words(800, lang='sl'), "osemsto") + self.assertEqual(num2words(900, lang='sl'), "devetsto") + self.assertEqual(num2words(1000, lang='sl'), "tisoč") + self.assertEqual(num2words(1001, lang='sl'), "tisoč ena") + self.assertEqual(num2words(1002, lang='sl'), "tisoč dve") + self.assertEqual(num2words(1003, lang='sl'), "tisoč tri") + self.assertEqual(num2words(1004, lang='sl'), "tisoč štiri") + self.assertEqual(num2words(1005, lang='sl'), "tisoč pet") + self.assertEqual(num2words(1006, lang='sl'), "tisoč šest") + self.assertEqual(num2words(2000, lang='sl'), "dva tisoč") + self.assertEqual(num2words(20000, lang='sl'), "dvajset tisoč") + self.assertEqual(num2words(100000, lang='sl'), "sto tisoč") + self.assertEqual(num2words(101000, lang='sl'), "sto en tisoč") + self.assertEqual(num2words(200000, lang='sl'), "dvesto tisoč") + self.assertEqual(num2words(1000000, lang='sl'), "milijon") + self.assertEqual(num2words(2000000, lang='sl'), "dva milijona") + self.assertEqual(num2words(3000000, lang='sl'), "trije milijoni") + self.assertEqual(num2words(101000000, lang='sl'), "sto en milijon") + self.assertEqual(num2words(202000000, lang='sl'), + "dvesto dva milijona") + self.assertEqual(num2words(303000000, lang='sl'), + "tristo trije milijoni") + self.assertEqual(num2words(304000000, lang='sl'), + "tristo štirje milijoni") + self.assertEqual(num2words(1000000000, lang='sl'), "milijarda") + self.assertEqual(num2words(2000000000, lang='sl'), "dve milijardi") + self.assertEqual(num2words(1121, lang='sl'), "tisoč sto enaindvajset") + self.assertEqual(num2words(2401, lang='sl'), "dva tisoč štiristo ena") + self.assertEqual(num2words(201001004, lang='sl'), + "dvesto en milijon tisoč štiri") + self.assertEqual( + num2words(1803603801, lang='sl'), + "milijarda osemsto trije milijoni šeststo tri tisoč osemsto ena") def test_cardinal_for_decimal_number(self): self.assertEqual(num2words(3.48, lang='sl'), "tri celih štiri osem") diff --git a/tests/test_sr.py b/tests/test_sr.py index 8547325b..50f379b8 100644 --- a/tests/test_sr.py +++ b/tests/test_sr.py @@ -86,6 +86,14 @@ def test_cardinal(self): def test_floating_point(self): self.assertEqual("pet zapeta dva", num2words(5.2, lang='sr')) + self.assertEqual( + num2words(10.02, lang='sr'), + "deset zapeta nula dva" + ) + self.assertEqual( + num2words(15.007, lang='sr'), + "petnaest zapeta nula nula sedam" + ) self.assertEqual( "petsto šezdeset jedan zapeta četrdeset dva", num2words(561.42, lang='sr') @@ -203,7 +211,7 @@ def test_to_currency(self): lang='sr', to='currency', currency='EUR', - seperator=' i' + separator=' i' ) ) self.assertEqual( @@ -213,18 +221,18 @@ def test_to_currency(self): lang='sr', to='currency', currency='RUB', - seperator=' i' + separator=' i' ) ) self.assertEqual( 'sto jedna rublja i dvadeset dve kopejke', num2words(10122, lang='sr', to='currency', currency='RUB', - seperator=' i') + separator=' i') ) self.assertEqual( 'sto jedan evro i dvadeset jedan cent', num2words(10121, lang='sr', to='currency', currency='EUR', - seperator=' i'), + separator=' i'), ) self.assertEqual( 'minus dvanaest hiljada petsto devetnaest evra, 85 centi', @@ -238,6 +246,6 @@ def test_to_currency(self): ) self.assertEqual( "trideset osam evra i 40 centi", - num2words('38.4', lang='sr', to='currency', seperator=' i', + num2words('38.4', lang='sr', to='currency', separator=' i', cents=False, currency='EUR'), ) diff --git a/tests/test_sv.py b/tests/test_sv.py new file mode 100644 index 00000000..a780dae2 --- /dev/null +++ b/tests/test_sv.py @@ -0,0 +1,70 @@ +# 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsSVTest(TestCase): + def test_ordinal(self): + self.assertEqual(num2words(14, to="ordinal", lang="sv"), "fjortonde") + self.assertEqual(num2words(1435, to="ordinal", lang="sv"), + "etttusen fyrahundratrettiofemte") + self.assertEqual(num2words(32, to="ordinal", lang="sv"), + "trettioandra") + self.assertEqual(num2words(1, to="ordinal", lang="sv"), "första") + self.assertEqual(num2words(5, to="ordinal", lang="sv"), "femte") + self.assertEqual(num2words(10, to="ordinal", lang="sv"), "tionde") + + def test_cardinal(self): + self.assertEqual(num2words(0, to="cardinal", lang="sv"), "noll") + self.assertEqual(num2words(1, to="cardinal", lang="sv"), "ett") + self.assertEqual(num2words(3, to="cardinal", lang="sv"), "tre") + self.assertEqual(num2words(5, to="cardinal", lang="sv"), "fem") + self.assertEqual(num2words(18, to="cardinal", lang="sv"), "arton") + self.assertEqual(num2words(45, to="cardinal", lang="sv"), "förtiofem") + self.assertEqual(num2words(1345, to="cardinal", lang="sv"), + "etttusen trehundraförtiofem") + self.assertEqual(num2words(4435, to="cardinal", lang="sv"), + "fyratusen fyrahundratrettiofem") + self.assertEqual(num2words(1004135, to="cardinal", lang="sv"), + "en miljon fyratusen etthundratrettiofem") + self.assertEqual(num2words(4335000, to="cardinal", lang="sv"), + "fyra miljoner trehundratrettiofemtusen") + self.assertEqual(num2words(14004535, to="cardinal", lang="sv"), + "fjorton miljoner fyratusen femhundratrettiofem") + self.assertEqual(num2words(1.5, to="cardinal", lang="sv"), + "ett komma fem") + + def test_not_implemented_options(self): + with self.assertRaises(NotImplementedError) as context: + num2words(1235, to="year", lang="sv") + self.assertTrue("'year' is not implemented for swedish language" + in str(context.exception)) + + with self.assertRaises(NotImplementedError) as context: + num2words(1235, to="currency", lang="sv") + self.assertTrue("'currency' is not implemented for swedish language" + in str(context.exception)) + + with self.assertRaises(NotImplementedError) as context: + num2words(1235, to="ordinal_num", lang="sv") + self.assertTrue("'ordinal_num' is not implemented for swedish language" + in str(context.exception)) diff --git a/tests/test_te.py b/tests/test_te.py new file mode 100644 index 00000000..63143109 --- /dev/null +++ b/tests/test_te.py @@ -0,0 +1,70 @@ +# -*- 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 Num2WordsTETest(TestCase): + def test_numbers(self): + self.assertEqual(num2words(66, lang="te"), u"అరవై ఆరు") + self.assertEqual(num2words(1734, lang="te"), + u"ఒకటి వేయి ఏడు వందల ముప్పై నాలుగు") + self.assertEqual(num2words(134, lang="te"), + u"ఒకటి వందల ముప్పై నాలుగు") + self.assertEqual(num2words(54411, lang="te"), + u"యాభై నాలుగు వేయి నాలుగు వందల పదకొండు") + self.assertEqual(num2words(42, lang="te"), u"నలభై రెండు") + self.assertEqual(num2words(893, lang="te"), + u"ఎనిమిది వందల తొంభై మూడు") + self.assertEqual( + num2words(1729, lang="te"), u"ఒకటి వేయి ఏడు వందల ఇరవై తొమ్మిది" + ) + self.assertEqual(num2words(123, lang="te"), u"ఒకటి వందల ఇరవై మూడు") + self.assertEqual(num2words(32211, lang="te"), + u"ముప్పై రెండు వేయి రెండు వందల పదకొండు") + + def test_cardinal_for_float_number(self): + self.assertEqual(num2words(1.61803, lang="te"), + u"ఒకటి బిందువు ఆరు ఒకటి ఎనిమిది సున్న మూడు") + self.assertEqual(num2words(34.876, lang="te"), + u"ముప్పై నాలుగు బిందువు ఎనిమిది ఏడు ఆరు") + self.assertEqual(num2words(3.14, lang="te"), + u"మూడు బిందువు ఒకటి నాలుగు") + + def test_ordinal(self): + self.assertEqual(num2words(1, lang='te', to='ordinal'), u"ఒకటివ") + self.assertEqual(num2words(22, lang='te', to='ordinal'), + u"ఇరవై రెండువ") + self.assertEqual(num2words(23, lang='te', to='ordinal'), + u"ఇరవై మూడువ") + self.assertEqual(num2words(12, lang='te', to='ordinal'), u"పన్నెండువ") + self.assertEqual(num2words(130, lang='te', to='ordinal'), + u"ఒకటి వందల ముప్పైవ") + self.assertEqual(num2words(1003, lang='te', to='ordinal'), + u"ఒకటి వేయిల మూడువ") + self.assertEqual(num2words(4, lang='te', to='ordinal'), + u"నాలుగువ") + + def test_ordinal_num(self): + self.assertEqual(num2words(2, lang="te", to='ordinal_num'), u"2వ") + self.assertEqual(num2words(3, lang="te", to='ordinal_num'), u"3వ") + self.assertEqual(num2words(5, lang="te", to='ordinal_num'), u"5వ") + self.assertEqual(num2words(16, lang="te", to='ordinal_num'), u"16వ") + self.assertEqual(num2words(113, lang="te", to='ordinal_num'), + u"113వ") diff --git a/tests/test_tet.py b/tests/test_tet.py new file mode 100644 index 00000000..7f005fd5 --- /dev/null +++ b/tests/test_tet.py @@ -0,0 +1,541 @@ +# -*- 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 + +import decimal +from decimal import Decimal +from unittest import TestCase + +from num2words import num2words +from num2words.lang_TET import Num2Word_TET + + +class Num2WordsTETTest(TestCase): + def setUp(self): + super().setUp() + self.n2w = Num2Word_TET() + + def test_cardinal_integer(self): + self.assertEqual(num2words(1, lang='tet'), 'ida') + self.assertEqual(num2words(2, lang='tet'), 'rua') + self.assertEqual(num2words(3, lang='tet'), 'tolu') + self.assertEqual(num2words(4, lang='tet'), 'haat') + self.assertEqual(num2words(5, lang='tet'), 'lima') + self.assertEqual(num2words(6, lang='tet'), 'neen') + self.assertEqual(num2words(7, lang='tet'), 'hitu') + self.assertEqual(num2words(8, lang='tet'), 'ualu') + self.assertEqual(num2words(9, lang='tet'), 'sia') + self.assertEqual(num2words(10, lang='tet'), 'sanulu') + self.assertEqual(num2words(11, lang='tet'), 'sanulu resin ida') + self.assertEqual(num2words(12, lang='tet'), 'sanulu resin rua') + self.assertEqual(num2words(13, lang='tet'), 'sanulu resin tolu') + self.assertEqual(num2words(14, lang='tet'), 'sanulu resin haat') + self.assertEqual(num2words(15, lang='tet'), 'sanulu resin lima') + self.assertEqual(num2words(16, lang='tet'), 'sanulu resin neen') + self.assertEqual(num2words(17, lang='tet'), 'sanulu resin hitu') + self.assertEqual(num2words(18, lang='tet'), 'sanulu resin ualu') + self.assertEqual(num2words(19, lang='tet'), 'sanulu resin sia') + self.assertEqual(num2words(20, lang='tet'), 'ruanulu') + + self.assertEqual(num2words(21, lang='tet'), 'ruanulu resin ida') + self.assertEqual(num2words(22, lang='tet'), 'ruanulu resin rua') + self.assertEqual(num2words(35, lang='tet'), 'tolunulu resin lima') + self.assertEqual(num2words(99, lang='tet'), 'sianulu resin sia') + + self.assertEqual(num2words(100, lang='tet'), 'atus ida') + self.assertEqual(num2words(101, lang='tet'), 'atus ida ida') + self.assertEqual(num2words(107, lang='tet'), 'atus ida hitu') + self.assertEqual(num2words(110, lang='tet'), 'atus ida sanulu') + self.assertEqual( + num2words(114, lang='tet'), + 'atus ida sanulu resin haat' + ) + self.assertEqual( + num2words(128, lang='tet'), + 'atus ida ruanulu resin ualu' + ) + self.assertEqual( + num2words(151, lang='tet'), + 'atus ida limanulu resin ida' + ) + self.assertEqual( + num2words(713, lang='tet'), + 'atus hitu sanulu resin tolu' + ) + self.assertEqual( + num2words(999, lang='tet'), + 'atus sia sianulu resin sia' + ) + + self.assertEqual(num2words(1000, lang='tet'), 'rihun ida') + self.assertEqual(num2words(1001, lang='tet'), 'rihun ida ida') + self.assertEqual( + num2words(1011, lang='tet'), + 'rihun ida sanulu resin ida' + ) + self.assertEqual( + num2words(1111, lang='tet'), + 'rihun ida atus ida sanulu resin ida' + ) + self.assertEqual( + num2words(2357, lang='tet'), + 'rihun rua atus tolu limanulu resin hitu' + ) + self.assertEqual( + num2words(2200, lang='tet'), + 'rihun rua atus rua' + ) + self.assertEqual( + num2words(2230, lang='tet'), + 'rihun rua atus rua tolunulu' + ) + self.assertEqual( + num2words(73400, lang='tet'), + 'rihun hitunulu resin tolu atus haat' + ) + self.assertEqual( + num2words(73421, lang='tet'), + 'rihun hitunulu resin tolu atus haat ruanulu resin ida' + ) + self.assertEqual(num2words(100000, lang='tet'), 'rihun atus ida') + self.assertEqual( + num2words(250050, lang='tet'), + 'rihun atus rua limanulu limanulu' + ) + self.assertEqual( + num2words(6000000, lang='tet'), 'miliaun neen' + ) + self.assertEqual( + num2words(100000000, lang='tet'), 'miliaun atus ida' + ) + self.assertEqual( + num2words(19000000000, lang='tet'), + 'miliaun rihun sanulu resin sia' + ) + self.assertEqual( + num2words(145000000002, lang='tet'), + 'miliaun rihun atus ida haatnulu resin lima resin rua' + ) + self.assertEqual( + num2words(4635102, lang='tet'), + 'miliaun haat rihun atus neen tolunulu resin lima atus ida rua' + ) + self.assertEqual( + num2words(145254635102, lang='tet'), + "miliaun rihun atus ida haatnulu resin lima atus rua limanulu \ +resin haat rihun atus neen tolunulu resin lima atus ida rua" + ) + self.assertEqual( + num2words(1000000000000, lang='tet'), + 'biliaun ida' + ) + self.assertEqual( + num2words(2000000000000, lang='tet'), + 'biliaun rua' + ) + self.assertEqual( + num2words(1000000000000000, lang='tet'), + 'biliaun rihun ida' + ) + self.assertEqual( + num2words(2000000000000000, lang='tet'), + 'biliaun rihun rua' + ) + self.assertEqual( + num2words(1000000000000000000, lang='tet'), + 'triliaun ida' + ) + self.assertEqual( + num2words(2000000000000000000, lang='tet'), + 'triliaun rua' + ) + + def test_cardinal_integer_negative(self): + self.assertEqual(num2words(-1, lang='tet'), 'menus ida') + self.assertEqual( + num2words(-256, lang='tet'), 'menus atus rua limanulu resin neen' + ) + self.assertEqual(num2words(-1000, lang='tet'), 'menus rihun ida') + self.assertEqual(num2words(-1000000, lang='tet'), 'menus miliaun ida') + self.assertEqual( + num2words(-1234567, lang='tet'), + 'menus miliaun ida rihun atus rua tolunulu resin \ +haat atus lima neenulu resin hitu' + ) + + def test_cardinal_float(self): + self.assertEqual(num2words(Decimal('1.00'), lang='tet'), 'ida') + self.assertEqual(num2words( + Decimal('1.01'), lang='tet'), 'ida vírgula mamuk ida') + self.assertEqual(num2words( + Decimal('1.035'), lang='tet'), 'ida vírgula mamuk tolu lima' + ) + self.assertEqual(num2words( + Decimal('1.35'), lang='tet'), 'ida vírgula tolu lima' + ) + self.assertEqual( + num2words(Decimal('3.14159'), lang='tet'), + 'tolu vírgula ida haat ida lima sia' + ) + self.assertEqual( + num2words(Decimal('101.22'), lang='tet'), + 'atus ida ida vírgula rua rua' + ) + self.assertEqual( + num2words(Decimal('2345.75'), lang='tet'), + 'rihun rua atus tolu haatnulu resin lima vírgula hitu lima' + ) + + def test_cardinal_float_negative(self): + self.assertEqual( + num2words(Decimal('-2.34'), lang='tet'), + 'menus rua vírgula tolu haat' + ) + self.assertEqual( + num2words(Decimal('-9.99'), lang='tet'), + 'menus sia vírgula sia sia' + ) + self.assertEqual( + num2words(Decimal('-7.01'), lang='tet'), + 'menus hitu vírgula mamuk ida' + ) + self.assertEqual( + num2words(Decimal('-222.22'), lang='tet'), + 'menus atus rua ruanulu resin rua vírgula rua rua' + ) + + def test_ordinal(self): + with self.assertRaises(decimal.InvalidOperation): + num2words("hello", lang='tet', ordinal=True) + with self.assertRaises(TypeError): + num2words(5.1, lang='tet', ordinal=True) + self.assertEqual(num2words(1, lang='tet', ordinal=True), 'dahuluk') + self.assertEqual(num2words(2, lang='tet', ordinal=True), 'daruak') + self.assertEqual(num2words(3, lang='tet', ordinal=True), 'datoluk') + self.assertEqual(num2words(4, lang='tet', ordinal=True), 'dahaat') + self.assertEqual(num2words(5, lang='tet', ordinal=True), 'dalimak') + self.assertEqual(num2words(6, lang='tet', ordinal=True), 'daneen') + self.assertEqual(num2words(7, lang='tet', ordinal=True), 'dahituk') + self.assertEqual(num2words(8, lang='tet', ordinal=True), 'daualuk') + self.assertEqual(num2words(9, lang='tet', ordinal=True), 'dasiak') + self.assertEqual(num2words(10, lang='tet', ordinal=True), 'dasanuluk') + self.assertEqual( + num2words(11, lang='tet', ordinal=True), 'dasanulu resin idak' + ) + self.assertEqual( + num2words(12, lang='tet', ordinal=True), 'dasanulu resin ruak' + ) + self.assertEqual( + num2words(13, lang='tet', ordinal=True), 'dasanulu resin toluk' + ) + self.assertEqual( + num2words(14, lang='tet', ordinal=True), 'dasanulu resin haat' + ) + self.assertEqual( + num2words(15, lang='tet', ordinal=True), 'dasanulu resin limak' + ) + self.assertEqual( + num2words(16, lang='tet', ordinal=True), 'dasanulu resin neen' + ) + self.assertEqual( + num2words(17, lang='tet', ordinal=True), 'dasanulu resin hituk' + ) + self.assertEqual( + num2words(18, lang='tet', ordinal=True), 'dasanulu resin ualuk' + ) + self.assertEqual( + num2words(19, lang='tet', ordinal=True), 'dasanulu resin siak' + ) + self.assertEqual( + num2words(20, lang='tet', ordinal=True), 'daruanuluk' + ) + + self.assertEqual( + num2words(21, lang='tet', ordinal=True), 'daruanulu resin idak' + ) + self.assertEqual( + num2words(22, lang='tet', ordinal=True), 'daruanulu resin ruak' + ) + self.assertEqual( + num2words(35, lang='tet', ordinal=True), 'datolunulu resin limak' + ) + self.assertEqual( + num2words(99, lang='tet', ordinal=True), 'dasianulu resin siak' + ) + + self.assertEqual( + num2words(100, lang='tet', ordinal=True), 'dahatus idak' + ) + self.assertEqual( + num2words(101, lang='tet', ordinal=True), 'dahatus ida idak' + ) + self.assertEqual( + num2words(106, lang='tet', ordinal=True), 'dahatus ida neen' + ) + self.assertEqual( + num2words(128, lang='tet', ordinal=True), + 'dahatus ida ruanulu resin ualuk' + ) + self.assertEqual( + num2words(600, lang='tet', ordinal=True), + 'dahatus neen' + ) + self.assertEqual( + num2words(713, lang='tet', ordinal=True), + 'dahatus hitu sanulu resin toluk' + ) + + self.assertEqual( + num2words(1000, lang='tet', ordinal=True), 'darihun idak' + ) + self.assertEqual( + num2words(1001, lang='tet', ordinal=True), 'darihun ida idak' + ) + self.assertEqual( + num2words(1111, lang='tet', ordinal=True), + 'darihun ida atus ida sanulu resin idak' + ) + self.assertEqual( + num2words(2114, lang='tet', ordinal=True), + 'darihun rua atus ida sanulu resin haat' + ) + self.assertEqual( + num2words(73421, lang='tet', ordinal=True), + 'darihun hitunulu resin tolu atus haat ruanulu resin idak' + ) + + self.assertEqual( + num2words(100000, lang='tet', ordinal=True), + 'darihun atus idak' + ) + self.assertEqual( + num2words(250050, lang='tet', ordinal=True), + 'darihun atus rua limanulu limanuluk' + ) + self.assertEqual( + num2words(6000000, lang='tet', ordinal=True), 'damiliaun neen' + ) + self.assertEqual( + num2words(19000000000, lang='tet', ordinal=True), + 'damiliaun rihun sanulu resin siak' + ) + self.assertEqual( + num2words(145000000002, lang='tet', ordinal=True), + 'damiliaun rihun atus ida haatnulu resin lima resin ruak' + ) + + def test_currency_integer(self): + self.assertEqual(self.n2w.to_currency(1.00), 'dolar ida') + self.assertEqual(self.n2w.to_currency(2.00), 'dolar rua') + self.assertEqual(self.n2w.to_currency(3.00), 'dolar tolu') + self.assertEqual(self.n2w.to_currency(4.00), 'dolar haat') + self.assertEqual(self.n2w.to_currency(5.00), 'dolar lima') + self.assertEqual(self.n2w.to_currency(6.00), 'dolar neen') + self.assertEqual(self.n2w.to_currency(7.00), 'dolar hitu') + self.assertEqual(self.n2w.to_currency(8.00), 'dolar ualu') + self.assertEqual(self.n2w.to_currency(9.00), 'dolar sia') + self.assertEqual(self.n2w.to_currency(10.00), 'dolar sanulu') + self.assertEqual(self.n2w.to_currency(11.00), 'dolar sanulu resin ida') + self.assertEqual(self.n2w.to_currency(12.00), 'dolar sanulu resin rua') + self.assertEqual( + self.n2w.to_currency(13.00), + 'dolar sanulu resin tolu' + ) + self.assertEqual( + self.n2w.to_currency(14.00), + 'dolar sanulu resin haat' + ) + self.assertEqual( + self.n2w.to_currency(15.00), + 'dolar sanulu resin lima' + ) + self.assertEqual( + self.n2w.to_currency(16.00), + 'dolar sanulu resin neen' + ) + self.assertEqual( + self.n2w.to_currency(17.00), + 'dolar sanulu resin hitu' + ) + self.assertEqual( + self.n2w.to_currency(18.00), + 'dolar sanulu resin ualu' + ) + self.assertEqual( + self.n2w.to_currency(19.00), + 'dolar sanulu resin sia' + ) + self.assertEqual(self.n2w.to_currency(20.00), 'dolar ruanulu') + + self.assertEqual( + self.n2w.to_currency(21.00), + 'dolar ruanulu resin ida' + ) + self.assertEqual( + self.n2w.to_currency(22.00), + 'dolar ruanulu resin rua' + ) + self.assertEqual( + self.n2w.to_currency(35.00), + 'dolar tolunulu resin lima' + ) + self.assertEqual( + self.n2w.to_currency(99.00), + 'dolar sianulu resin sia' + ) + + self.assertEqual(self.n2w.to_currency(100.00), 'dolar atus ida') + self.assertEqual(self.n2w.to_currency(101.00), 'dolar atus ida ida') + self.assertEqual( + self.n2w.to_currency(128.00), 'dolar atus ida ruanulu resin ualu' + ) + self.assertEqual( + self.n2w.to_currency(713.00), 'dolar atus hitu sanulu resin tolu') + + self.assertEqual(self.n2w.to_currency(1000.00), 'dolar rihun ida') + self.assertEqual(self.n2w.to_currency(1001.00), 'dolar rihun ida ida') + self.assertEqual( + self.n2w.to_currency(1111.00), + 'dolar rihun ida atus ida sanulu resin ida' + ) + self.assertEqual( + self.n2w.to_currency(2114.00), + 'dolar rihun rua atus ida sanulu resin haat' + ) + self.assertEqual( + self.n2w.to_currency(73421.00), + 'dolar rihun hitunulu resin tolu atus haat ruanulu resin ida' + ) + + self.assertEqual( + self.n2w.to_currency(100000.00), + 'dolar rihun atus ida' + ) + self.assertEqual( + self.n2w.to_currency(250050.00), + 'dolar rihun atus rua limanulu limanulu' + ) + self.assertEqual( + self.n2w.to_currency(6000000.00), + 'dolar miliaun neen' + ) + self.assertEqual( + self.n2w.to_currency(19000000000.00), + 'dolar miliaun rihun sanulu resin sia' + ) + self.assertEqual( + self.n2w.to_currency(145000000002.00), + 'dolar miliaun rihun atus ida haatnulu resin lima resin rua' + ) + self.assertEqual(self.n2w.to_currency(1.00, currency='USD'), + 'dolar ida') + self.assertEqual(self.n2w.to_currency(1.50, currency='USD'), + 'dolar ida sentavu limanulu') + with self.assertRaises(NotImplementedError): + self.n2w.to_currency(1.00, currency='CHF') + + def test_currency_integer_negative(self): + self.assertEqual(self.n2w.to_currency(-1.00), 'menus dolar ida') + self.assertEqual( + self.n2w.to_currency(-256.00), + 'menus dolar atus rua limanulu resin neen' + ) + self.assertEqual( + self.n2w.to_currency(-1000.00), + 'menus dolar rihun ida' + ) + self.assertEqual( + self.n2w.to_currency(-1000000.00), 'menus dolar miliaun ida' + ) + self.assertEqual( + self.n2w.to_currency(-1234567.00), + 'menus dolar miliaun ida rihun atus rua tolunulu \ +resin haat atus lima neenulu resin hitu' + ) + + def test_currency_float(self): + self.assertEqual(self.n2w.to_currency(Decimal('1.00')), 'dolar ida') + self.assertEqual( + self.n2w.to_currency(Decimal('1.01')), 'dolar ida sentavu ida' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('1.03')), 'dolar ida sentavu tolu' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('1.35')), + 'dolar ida sentavu tolunulu resin lima' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('3.14')), + 'dolar tolu sentavu sanulu resin haat' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('101.22')), + 'dolar atus ida ida sentavu ruanulu resin rua' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('2345.75')), + 'dolar rihun rua atus tolu haatnulu resin \ +lima sentavu hitunulu resin lima' + ) + + def test_currency_float_negative(self): + self.assertEqual( + self.n2w.to_currency(Decimal('-2.34')), + 'menus dolar rua sentavu tolunulu resin haat' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('-9.99')), + 'menus dolar sia sentavu sianulu resin sia' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('-7.01')), + 'menus dolar hitu sentavu ida' + ) + self.assertEqual( + self.n2w.to_currency(Decimal('-222.22')), + 'menus dolar atus rua ruanulu resin rua sentavu ruanulu resin rua' + ) + + def test_year(self): + self.assertEqual(self.n2w.to_year(1001), 'rihun ida ida') + self.assertEqual( + self.n2w.to_year(1789), 'rihun ida atus hitu ualunulu resin sia' + ) + self.assertEqual( + self.n2w.to_year(1942), 'rihun ida atus sia haatnulu resin rua' + ) + self.assertEqual( + self.n2w.to_year(1984), 'rihun ida atus sia ualunulu resin haat' + ) + self.assertEqual(self.n2w.to_year(2000), 'rihun rua') + self.assertEqual(self.n2w.to_year(2001), 'rihun rua ida') + self.assertEqual(self.n2w.to_year(2016), 'rihun rua sanulu resin neen') + + def test_year_negative(self): + self.assertEqual(self.n2w.to_year(-30), 'tolunulu antes Kristu') + self.assertEqual( + self.n2w.to_year(-744), + 'atus hitu haatnulu resin haat antes Kristu' + ) + self.assertEqual( + self.n2w.to_year(-10000), + 'rihun sanulu antes Kristu' + ) + + def test_to_ordinal_num(self): + self.assertEqual(self.n2w.to_ordinal_num(1), '1º') + self.assertEqual(self.n2w.to_ordinal_num(100), '100º') diff --git a/tests/test_tg.py b/tests/test_tg.py new file mode 100644 index 00000000..53a49e4f --- /dev/null +++ b/tests/test_tg.py @@ -0,0 +1,118 @@ +# -*- 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 unicode_literals + +from unittest import TestCase + +from num2words import num2words + + +class Num2WordsTGTest(TestCase): + def test_cardinal(self): + with self.assertRaises(OverflowError): + num2words(1000000000000000000000000, lang="tg") + self.assertEqual(num2words(100, lang="tg"), "сад") + self.assertEqual(num2words(100000, lang="tg"), "сад ҳазор") + self.assertEqual(num2words(101, lang="tg"), "яксаду як") + self.assertEqual(num2words(110, lang="tg"), "яксаду даҳ") + self.assertEqual(num2words(115, lang="tg"), "яксаду понздаҳ") + self.assertEqual(num2words(123, lang="tg"), "яксаду бисту се") + self.assertEqual(num2words(1000, lang="tg"), "як ҳазор") + self.assertEqual(num2words(1001, lang="tg"), "як ҳазору як") + self.assertEqual(num2words(2012, lang="tg"), "ду ҳазору дувоздаҳ") + self.assertEqual( + num2words(12519.85, lang="tg"), + "дувоздаҳ ҳазору панҷсаду нуздаҳ нуқта ҳашт панҷ", + ) + + self.assertEqual( + num2words(1234567890, lang="tg"), + "як миллиарду дусаду сию чор миллиону панҷсаду шасту ҳафт ҳазору " + "ҳаштсаду навад", + ) + self.assertEqual(num2words(1000000, lang="tg"), "як миллион") + self.assertEqual(num2words(1000000000, lang="tg"), "як миллиард") + self.assertEqual(num2words(1000000000000, lang="tg"), "як триллион") + self.assertEqual(num2words(5, lang="tg"), "панҷ") + self.assertEqual(num2words(-1, lang="tg"), "минус як") + self.assertEqual(num2words(-15, lang="tg"), "минус понздаҳ") + self.assertEqual(num2words(-100, lang="tg"), "минус сад") + + def test_to_ordinal(self): + self.assertEqual(num2words(1, lang="tg", to="ordinal"), "якум") + self.assertEqual(num2words(2, lang="tg", to="ordinal"), "дуюм") + self.assertEqual(num2words(3, lang="tg", to="ordinal"), "сеюм") + self.assertEqual(num2words(30, lang="tg", to="ordinal"), "сиюм") + + self.assertEqual(num2words(13, lang="tg", to="ordinal"), "сенздаҳум") + self.assertEqual(num2words(20, lang="tg", to="ordinal"), "бистум") + self.assertEqual(num2words(23, lang="tg", to="ordinal"), "бисту сеюм") + self.assertEqual(num2words(100, lang="tg", to="ordinal"), "садум") + self.assertEqual( + num2words(136, lang="tg", to="ordinal"), "яксаду сию шашум" + ) + self.assertEqual(num2words(500, lang="tg", to="ordinal"), "панҷсадум") + self.assertEqual( + num2words(1000, lang="tg", to="ordinal"), "як ҳазорум" + ) + self.assertEqual( + num2words(1001, lang="tg", to="ordinal"), "як ҳазору якум" + ) + self.assertEqual( + num2words(2000, lang="tg", to="ordinal"), "ду ҳазорум" + ) + self.assertEqual( + num2words(1000000, lang="tg", to="ordinal"), "як миллионум" + ) + self.assertEqual( + num2words(1000000000, lang="tg", to="ordinal"), "як миллиардум" + ) + + def test_to_currency(self): + self.assertEqual( + num2words(1.0, lang="tg", to="currency", currency="EUR"), + "як евро, сифр сент", + ) + self.assertEqual( + num2words(1.0, lang="tg", to="currency", currency="TJS"), + "як сомонӣ, сифр дирам", + ) + self.assertEqual( + num2words(1234.56, lang="tg", to="currency", currency="TJS"), + "як ҳазору дусаду сию чор сомонӣ, панҷову шаш дирам", + ) + self.assertEqual( + num2words(1234.56, lang="tg", to="currency", currency="RUB"), + "як ҳазору дусаду сию чор рубл, панҷову шаш копейк", + ) + self.assertEqual( + num2words( + 12519.85, lang="tg", to="currency", currency="TJS", cents=False + ), + "дувоздаҳ ҳазору панҷсаду нуздаҳ сомонӣ, 85 дирам", + ) + self.assertEqual( + num2words("1230.56", lang="tg", to="currency", currency="USD"), + "як ҳазору дусаду си доллар, панҷову шаш сент", + ) + + def test_to_ordinal_num(self): + self.assertEqual( + num2words("100", lang="tg", to="ordinal_num"), + "100ум", + ) diff --git a/tests/test_tr.py b/tests/test_tr.py index 02073e07..4a341af1 100644 --- a/tests/test_tr.py +++ b/tests/test_tr.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# Copyright (c) 2017, Tufan Kaynak, Framras. All Rights Reserved. # Copyright (c) 2003, Taro Ogawa. All Rights Reserved. # Copyright (c) 2013, Savoir-faire Linux inc. All Rights Reserved. @@ -23,171 +24,179 @@ class Num2WordsTRTest(TestCase): def test_tr(self): # ref https://github.com/savoirfairelinux/num2words/issues/8 + testlang = "tr" + testcases = [ + {"test": 0, "to": "currency", "expected": u"bedelsiz"}, + {"test": 1.1, "to": "currency", "expected": u"birliraonkuruş"}, + {"test": 2000, "to": "currency", "expected": u"ikibinlira"}, + {"test": 110000, "to": "currency", "expected": u"yüzonbinlira"}, + {"test": 1002000, "to": "currency", + "expected": u"birmilyonikibinlira"}, + {"test": 1002001, "to": "currency", + "expected": u"birmilyonikibinbirlira"}, + {"test": 1100000, "to": "currency", + "expected": u"birmilyonyüzbinlira"}, + {"test": 0, "to": "ordinal", "expected": u"sıfırıncı"}, + {"test": 1, "to": "ordinal", "expected": u"birinci"}, + {"test": 2, "to": "ordinal", "expected": u"ikinci"}, + {"test": 9, "to": "ordinal", "expected": u"dokuzuncu"}, + {"test": 10, "to": "ordinal", "expected": u"onuncu"}, + {"test": 11, "to": "ordinal", "expected": u"onbirinci"}, + {"test": 44, "to": "ordinal", "expected": u"kırkdördüncü"}, + {"test": 100, "to": "ordinal", "expected": u"yüzüncü"}, + {"test": 101, "to": "ordinal", "expected": u"yüzbirinci"}, + {"test": 103, "to": "ordinal", "expected": u"yüzüçüncü"}, + {"test": 110, "to": "ordinal", "expected": u"yüzonuncu"}, + {"test": 111, "to": "ordinal", "expected": u"yüzonbirinci"}, + {"test": 1000, "to": "ordinal", "expected": u"bininci"}, + {"test": 1001, "to": "ordinal", "expected": u"binbirinci"}, + {"test": 1010, "to": "ordinal", "expected": u"binonuncu"}, + {"test": 1011, "to": "ordinal", "expected": u"binonbirinci"}, + {"test": 1100, "to": "ordinal", "expected": u"binyüzüncü"}, + {"test": 1110, "to": "ordinal", "expected": u"binyüzonuncu"}, + {"test": 2341, "to": "ordinal", + "expected": u"ikibinüçyüzkırkbirinci"}, + {"test": 10000, "to": "ordinal", "expected": u"onbininci"}, + {"test": 10010, "to": "ordinal", "expected": u"onbinonuncu"}, + {"test": 10100, "to": "ordinal", "expected": u"onbinyüzüncü"}, + {"test": 10110, "to": "ordinal", "expected": u"onbinyüzonuncu"}, + {"test": 11000, "to": "ordinal", "expected": u"onbirbininci"}, + {"test": 35000, "to": "ordinal", "expected": u"otuzbeşbininci"}, + {"test": 116331, "to": "ordinal", + "expected": u"yüzonaltıbinüçyüzotuzbirinci"}, + {"test": 116330, "to": "ordinal", + "expected": u"yüzonaltıbinüçyüzotuzuncu"}, + {"test": 100000, "to": "ordinal", "expected": u"yüzbininci"}, + {"test": 501000, "to": "ordinal", + "expected": u"beşyüzbirbininci"}, + {"test": 1000111, "to": "ordinal", + "expected": u"birmilyonyüzonbirinci"}, + {"test": 111000111, "to": "ordinal", + "expected": u"yüzonbirmilyonyüzonbirinci"}, + {"test": 111001111, "to": "ordinal", + "expected": u"yüzonbirmilyonbinyüzonbirinci"}, + {"test": 111111111, "to": "ordinal", + "expected": u"yüzonbirmilyonyüzonbirbinyüzonbirinci"}, + {"test": 100001000, "to": "ordinal", + "expected": u"yüzmilyonbininci"}, + {"test": 100001001, "to": "ordinal", + "expected": u"yüzmilyonbinbirinci"}, + {"test": 100010000, "to": "ordinal", + "expected": u"yüzmilyononbininci"}, + {"test": 100010001, "to": "ordinal", + "expected": u"yüzmilyononbinbirinci"}, + {"test": 100011000, "to": "ordinal", + "expected": u"yüzmilyononbirbininci"}, + {"test": 100011001, "to": "ordinal", + "expected": u"yüzmilyononbirbinbirinci"}, + {"test": 101011001, "to": "ordinal", + "expected": u"yüzbirmilyononbirbinbirinci"}, + {"test": 101011010, "to": "ordinal", + "expected": u"yüzbirmilyononbirbinonuncu"}, + {"test": 1101011010, "to": "ordinal", + "expected": u"birmilyaryüzbirmilyononbirbinonuncu"}, + {"test": 101101011010, "to": "ordinal", + "expected": u"yüzbirmilyaryüzbirmilyononbirbinonuncu"}, + {"test": 1000000000001, "to": "ordinal", + "expected": u"birtrilyonbirinci"}, + {"test": 1.2, "to": "ordinal", "expected": u""}, + {"test": 1.3, "to": "ordinal", "expected": u""}, + {"test": 3000, "to": "ordinal", "expected": u"üçbininci"}, + {"test": 120000, "to": "ordinal", "expected": u"yüzyirmibininci"}, + {"test": 1002002, "to": "ordinal", + "expected": u"birmilyonikibinikinci"}, + {"test": 1003000, "to": "ordinal", + "expected": u"birmilyonüçbininci"}, + {"test": 1200000, "to": "ordinal", + "expected": u"birmilyonikiyüzbininci"}, + {"test": 0, "to": "cardinal", "expected": u"sıfır"}, + {"test": 1, "to": "cardinal", "expected": u"bir"}, + {"test": 2, "to": "cardinal", "expected": u"iki"}, + {"test": 9, "to": "cardinal", "expected": u"dokuz"}, + {"test": 10, "to": "cardinal", "expected": u"on"}, + {"test": 11, "to": "cardinal", "expected": u"onbir"}, + {"test": 44, "to": "cardinal", "expected": u"kırkdört"}, + {"test": 100, "to": "cardinal", "expected": u"yüz"}, + {"test": 101, "to": "cardinal", "expected": u"yüzbir"}, + {"test": 103, "to": "cardinal", "expected": u"yüzüç"}, + {"test": 110, "to": "cardinal", "expected": u"yüzon"}, + {"test": 111, "to": "cardinal", "expected": u"yüzonbir"}, + {"test": 1000, "to": "cardinal", "expected": u"bin"}, + {"test": 1001, "to": "cardinal", "expected": u"binbir"}, + {"test": 1010, "to": "cardinal", "expected": u"binon"}, + {"test": 1011, "to": "cardinal", "expected": u"binonbir"}, + {"test": 1100, "to": "cardinal", "expected": u"binyüz"}, + {"test": 1110, "to": "cardinal", "expected": u"binyüzon"}, + {"test": 2341, "to": "cardinal", + "expected": u"ikibinüçyüzkırkbir"}, + {"test": 10000, "to": "cardinal", "expected": u"onbin"}, + {"test": 10010, "to": "cardinal", "expected": u"onbinon"}, + {"test": 10100, "to": "cardinal", "expected": u"onbinyüz"}, + {"test": 10110, "to": "cardinal", "expected": u"onbinyüzon"}, + {"test": 11000, "to": "cardinal", "expected": u"onbirbin"}, + {"test": 35000, "to": "cardinal", "expected": u"otuzbeşbin"}, + {"test": 116331, "to": "cardinal", + "expected": u"yüzonaltıbinüçyüzotuzbir"}, + {"test": 116330, "to": "cardinal", + "expected": u"yüzonaltıbinüçyüzotuz"}, + {"test": 500000, "to": "cardinal", "expected": u"beşyüzbin"}, + {"test": 501000, "to": "cardinal", "expected": u"beşyüzbirbin"}, + {"test": 1000111, "to": "cardinal", + "expected": u"birmilyonyüzonbir"}, + {"test": 111000111, "to": "cardinal", + "expected": u"yüzonbirmilyonyüzonbir"}, + {"test": 111001111, "to": "cardinal", + "expected": u"yüzonbirmilyonbinyüzonbir"}, + {"test": 111111111, "to": "cardinal", + "expected": u"yüzonbirmilyonyüzonbirbinyüzonbir"}, + {"test": 100001000, "to": "cardinal", + "expected": u"yüzmilyonbin"}, + {"test": 100001001, "to": "cardinal", + "expected": u"yüzmilyonbinbir"}, + {"test": 100010000, "to": "cardinal", + "expected": u"yüzmilyononbin"}, + {"test": 100010001, "to": "cardinal", + "expected": u"yüzmilyononbinbir"}, + {"test": 100011000, "to": "cardinal", + "expected": u"yüzmilyononbirbin"}, + {"test": 100011001, "to": "cardinal", + "expected": u"yüzmilyononbirbinbir"}, + {"test": 101011001, "to": "cardinal", + "expected": u"yüzbirmilyononbirbinbir"}, + {"test": 101011010, "to": "cardinal", + "expected": u"yüzbirmilyononbirbinon"}, + {"test": 1101011010, "to": "cardinal", + "expected": u"birmilyaryüzbirmilyononbirbinon"}, + {"test": 101101011010, "to": "cardinal", + "expected": u"yüzbirmilyaryüzbirmilyononbirbinon"}, + {"test": 1000000000001, "to": "cardinal", + "expected": u"birtrilyonbir"}, + {"test": 0.01, "to": "cardinal", "expected": u"sıfırvirgülbir"}, + {"test": 0.21, "to": "cardinal", + "expected": u"sıfırvirgülyirmibir"}, + {"test": 0.1, "to": "cardinal", "expected": u"sıfırvirgülon"}, + {"test": 1.01, "to": "cardinal", "expected": u"birvirgülbir"}, + {"test": 1.1, "to": "cardinal", "expected": u"birvirgülon"}, + {"test": 1.21, "to": "cardinal", + "expected": u"birvirgülyirmibir"}, + {"test": 101101011010.02, "to": "cardinal", + "expected": u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki"}, + {"test": 101101011010.2, "to": "cardinal", + "expected": u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi"}, + {"test": 10, "to": "ordinal_num", "expected": u"10uncu"}, + {"test": 1, "to": "ordinal_num", "expected": u"1inci"}, + {"test": 3, "to": "ordinal_num", "expected": u"3üncü"}, + {"test": 6, "to": "ordinal_num", "expected": u"6ıncı"}, + {"test": -5, "to": "cardinal", "expected": u"eksibeş"}, + {"test": -55, "to": "cardinal", "expected": u"eksiellibeş"}, + {"test": -576, "to": "cardinal", + "expected": u"eksibeşyüzyetmişaltı"}, + {"test": -3, "to": "currency", "expected": u"eksiüçlira"}, + ] - self.assertEqual(num2words(1, True, "tr"), u"birinci") - self.assertEqual(num2words(2, True, "tr"), u"ikinci") - self.assertEqual(num2words(9, True, "tr"), u"dokuzuncu") - self.assertEqual(num2words(10, True, "tr"), u"onuncu") - self.assertEqual(num2words(11, True, "tr"), u"onbirinci") - self.assertEqual(num2words(44, True, "tr"), u"kırkdördüncü") - self.assertEqual(num2words(100, True, "tr"), u"yüzüncü") - self.assertEqual(num2words(101, True, "tr"), u"yüzbirinci") - self.assertEqual(num2words(103, True, "tr"), u"yüzüçüncü") - self.assertEqual(num2words(110, True, "tr"), u"yüzonuncu") - self.assertEqual(num2words(111, True, "tr"), u"yüzonbirinci") - self.assertEqual(num2words(1000, True, "tr"), u"bininci") - self.assertEqual(num2words(1001, True, "tr"), u"binbirinci") - self.assertEqual(num2words(1010, True, "tr"), u"binonuncu") - self.assertEqual(num2words(1011, True, "tr"), u"binonbirinci") - self.assertEqual(num2words(1100, True, "tr"), u"binyüzüncü") - self.assertEqual(num2words(1110, True, "tr"), u"binyüzonuncu") - self.assertEqual( - num2words(2341, True, "tr"), u"ikibinüçyüzkırkbirinci" - ) - self.assertEqual(num2words(10000, True, "tr"), u"onbininci") - self.assertEqual(num2words(10010, True, "tr"), u"onbinonuncu") - self.assertEqual(num2words(10100, True, "tr"), u"onbinyüzüncü") - self.assertEqual(num2words(10110, True, "tr"), u"onbinyüzonuncu") - self.assertEqual(num2words(11000, True, "tr"), u"onbirbininci") - self.assertEqual(num2words(35000, True, "tr"), u"otuzbeşbininci") - self.assertEqual( - num2words(116331, True, "tr"), u"yüzonaltıbinüçyüzotuzbirinci" - ) - self.assertEqual( - num2words(116330, True, "tr"), u"yüzonaltıbinüçyüzotuzuncu" - ) - self.assertEqual(num2words(100000, True, "tr"), u"yüzbininci") - self.assertEqual(num2words(501000, True, "tr"), u"beşyüzbirbininci") - self.assertEqual( - num2words(1000111, True, "tr"), u"birmilyonyüzonbirinci" - ) - self.assertEqual( - num2words(111000111, True, "tr"), u"yüzonbirmilyonyüzonbirinci" - ) - self.assertEqual( - num2words(111001111, True, "tr"), u"yüzonbirmilyonbinyüzonbirinci" - ) - self.assertEqual( - num2words(111111111, True, "tr"), - u"yüzonbirmilyonyüzonbirbinyüzonbirinci" - ) - self.assertEqual(num2words(100001000, True, "tr"), u"yüzmilyonbininci") - self.assertEqual( - num2words(100001001, True, "tr"), u"yüzmilyonbinbirinci" - ) - self.assertEqual( - num2words(100010000, True, "tr"), u"yüzmilyononbininci" - ) - self.assertEqual( - num2words(100010001, True, "tr"), u"yüzmilyononbinbirinci" - ) - self.assertEqual( - num2words(100011000, True, "tr"), u"yüzmilyononbirbininci" - ) - self.assertEqual( - num2words(100011001, True, "tr"), u"yüzmilyononbirbinbirinci" - ) - self.assertEqual( - num2words(101011001, True, "tr"), u"yüzbirmilyononbirbinbirinci" - ) - self.assertEqual( - num2words(101011010, True, "tr"), u"yüzbirmilyononbirbinonuncu" - ) - self.assertEqual( - num2words(1101011010, True, "tr"), - u"birmilyaryüzbirmilyononbirbinonuncu" - ) - self.assertEqual( - num2words(101101011010, True, "tr"), - u"yüzbirmilyaryüzbirmilyononbirbinonuncu" - ) - self.assertEqual( - num2words(1000000000001, True, "tr"), u"birtrilyonbirinci" - ) - - self.assertEqual(num2words(1, False, "tr"), u"bir") - self.assertEqual(num2words(2, False, "tr"), u"iki") - self.assertEqual(num2words(9, False, "tr"), u"dokuz") - self.assertEqual(num2words(10, False, "tr"), u"on") - self.assertEqual(num2words(11, False, "tr"), u"onbir") - self.assertEqual(num2words(44, False, "tr"), u"kırkdört") - self.assertEqual(num2words(100, False, "tr"), u"yüz") - self.assertEqual(num2words(101, False, "tr"), u"yüzbir") - self.assertEqual(num2words(103, False, "tr"), u"yüzüç") - self.assertEqual(num2words(110, False, "tr"), u"yüzon") - self.assertEqual(num2words(111, False, "tr"), u"yüzonbir") - self.assertEqual(num2words(1000, False, "tr"), u"bin") - self.assertEqual(num2words(1001, False, "tr"), u"binbir") - self.assertEqual(num2words(1010, False, "tr"), u"binon") - self.assertEqual(num2words(1011, False, "tr"), u"binonbir") - self.assertEqual(num2words(1100, False, "tr"), u"binyüz") - self.assertEqual(num2words(1110, False, "tr"), u"binyüzon") - self.assertEqual(num2words(2341, False, "tr"), u"ikibinüçyüzkırkbir") - self.assertEqual(num2words(10000, False, "tr"), u"onbin") - self.assertEqual(num2words(10010, False, "tr"), u"onbinon") - self.assertEqual(num2words(10100, False, "tr"), u"onbinyüz") - self.assertEqual(num2words(10110, False, "tr"), u"onbinyüzon") - self.assertEqual(num2words(11000, False, "tr"), u"onbirbin") - self.assertEqual(num2words(35000, False, "tr"), u"otuzbeşbin") - self.assertEqual( - num2words(116331, False, "tr"), u"yüzonaltıbinüçyüzotuzbir" - ) - self.assertEqual( - num2words(116330, False, "tr"), u"yüzonaltıbinüçyüzotuz" - ) - self.assertEqual(num2words(500000, False, "tr"), u"beşyüzbin") - self.assertEqual(num2words(501000, False, "tr"), u"beşyüzbirbin") - self.assertEqual(num2words(1000111, False, "tr"), u"birmilyonyüzonbir") - self.assertEqual( - num2words(111000111, False, "tr"), u"yüzonbirmilyonyüzonbir" - ) - self.assertEqual( - num2words(111001111, False, "tr"), u"yüzonbirmilyonbinyüzonbir" - ) - self.assertEqual( - num2words(111111111, False, "tr"), - u"yüzonbirmilyonyüzonbirbinyüzonbir" - ) - self.assertEqual(num2words(100001000, False, "tr"), u"yüzmilyonbin") - self.assertEqual(num2words(100001001, False, "tr"), u"yüzmilyonbinbir") - self.assertEqual(num2words(100010000, False, "tr"), u"yüzmilyononbin") - self.assertEqual( - num2words(100010001, False, "tr"), u"yüzmilyononbinbir" - ) - self.assertEqual( - num2words(100011000, False, "tr"), u"yüzmilyononbirbin" - ) - self.assertEqual( - num2words(100011001, False, "tr"), u"yüzmilyononbirbinbir" - ) - self.assertEqual( - num2words(101011001, False, "tr"), u"yüzbirmilyononbirbinbir" - ) - self.assertEqual( - num2words(101011010, False, "tr"), u"yüzbirmilyononbirbinon" - ) - self.assertEqual( - num2words(1101011010, False, "tr"), - u"birmilyaryüzbirmilyononbirbinon" - ) - self.assertEqual( - num2words(101101011010, False, "tr"), - u"yüzbirmilyaryüzbirmilyononbirbinon" - ) - self.assertEqual( - num2words(1000000000001, False, "tr"), u"birtrilyonbir" - ) - self.assertEqual(num2words(0.01, False, "tr"), u"sıfırvirgülbir") - self.assertEqual(num2words(0.1, False, "tr"), u"sıfırvirgülon") - self.assertEqual(num2words(0.21, False, "tr"), u"sıfırvirgülyirmibir") - self.assertEqual(num2words(1.01, False, "tr"), u"birvirgülbir") - self.assertEqual(num2words(1.1, False, "tr"), u"birvirgülon") - self.assertEqual(num2words(1.21, False, "tr"), u"birvirgülyirmibir") - self.assertEqual( - num2words(101101011010.02, False, "tr"), - u"yüzbirmilyaryüzbirmilyononbirbinonvirgüliki" - ) - self.assertEqual( - num2words(101101011010.2, False, "tr"), - u"yüzbirmilyaryüzbirmilyononbirbinonvirgülyirmi" - ) + for casedata in testcases: + self.assertEqual( + num2words(casedata["test"], + lang=testlang, + to=casedata["to"]), + casedata["expected"]) diff --git a/tests/test_uk.py b/tests/test_uk.py index ff171036..4dcd7cb1 100644 --- a/tests/test_uk.py +++ b/tests/test_uk.py @@ -21,115 +21,3965 @@ from num2words import num2words +TEST_CASES_CARDINAL = ( + (1, "один"), + (2, "два"), + (3, "три"), + (4, "чотири"), + (5, "п'ять"), + (6, "шість"), + (7, "сім"), + (8, "вісім"), + (9, "дев'ять"), + (10, "десять"), + (10.02, "десять кома нуль два"), + (11, "одинадцять"), + (12, "дванадцять"), + (12.40, "дванадцять кома чотири"), + (13, "тринадцять"), + (14, "чотирнадцять"), + (14.13, "чотирнадцять кома тринадцять"), + (15, "п'ятнадцять"), + (16, "шістнадцять"), + (17, "сімнадцять"), + (17.31, "сімнадцять кома тридцять один"), + (18, "вісімнадцять"), + (19, "дев'ятнадцять"), + (20, "двадцять"), + (21, "двадцять один"), + (21.20, "двадцять один кома два"), + (30, "тридцять"), + (32, "тридцять два"), + (40, "сорок"), + (43, "сорок три"), + (43.007, "сорок три кома нуль нуль сім"), + (50, "п'ятдесят"), + (54, "п'ятдесят чотири"), + (60, "шістдесят"), + (60.059, "шістдесят кома нуль п'ятдесят дев'ять"), + (65, "шістдесят п'ять"), + (70, "сімдесят"), + (76, "сімдесят шість"), + (80, "вісімдесят"), + (87, "вісімдесят сім"), + (90, "дев'яносто"), + (98, "дев'яносто вісім"), + (99, "дев'яносто дев'ять"), + (100, "сто"), + (101, "сто один"), + (199, "сто дев'яносто дев'ять"), + (200, "двісті"), + (203, "двісті три"), + (300, "триста"), + (356, "триста п'ятдесят шість"), + (400, "чотириста"), + (434, "чотириста тридцять чотири"), + (500, "п'ятсот"), + (578, "п'ятсот сімдесят вісім"), + (600, "шістсот"), + (689, "шістсот вісімдесят дев'ять"), + (700, "сімсот"), + (729, "сімсот двадцять дев'ять"), + (800, "вісімсот"), + (894, "вісімсот дев'яносто чотири"), + (900, "дев'ятсот"), + (999, "дев'ятсот дев'яносто дев'ять"), + (1000, "одна тисяча"), + (1001, "одна тисяча один"), + (2012, "дві тисячі дванадцять"), + (12519, "дванадцять тисяч п'ятсот дев'ятнадцять"), + (12519.85, "дванадцять тисяч п'ятсот дев'ятнадцять кома вісімдесят п'ять"), + (-260000, "мінус двісті шістдесят тисяч"), + (1000000, "один мільйон"), + (1000000000, "один мільярд"), + (1234567890, "один мільярд двісті тридцять чотири мільйони " + "п'ятсот шістдесят сім тисяч вісімсот дев'яносто"), + (1000000000000, "один трильйон"), + (1000000000000000, "один квадрильйон"), + (1000000000000000000, "один квінтильйон"), + (1000000000000000000000, "один секстильйон"), + (1000000000000000000000000, "один септильйон"), + (1000000000000000000000000000, "один октильйон"), + (1000000000000000000000000000000, "один нонільйон"), + (215461407892039002157189883901676, + "двісті п'ятнадцять нонільйонів чотириста шістдесят один " + "октильйон чотириста сім септильйонів вісімсот дев'яносто " + "два секстильйони тридцять дев'ять квінтильйонів два " + "квадрильйони сто п'ятдесят сім трильйонів сто вісімдесят " + "дев'ять мільярдів вісімсот вісімдесят три мільйони " + "дев'ятсот одна тисяча шістсот сімдесят шість"), + (719094234693663034822824384220291, + "сімсот дев'ятнадцять нонільйонів дев'яносто чотири октильйони " + "двісті тридцять чотири септильйони шістсот дев'яносто три " + "секстильйони шістсот шістдесят три квінтильйони тридцять " + "чотири квадрильйони вісімсот двадцять два трильйони вісімсот " + "двадцять чотири мільярди триста вісімдесят чотири мільйони " + "двісті двадцять тисяч двісті дев'яносто один") +) + +TEST_CASES_CARDINAL_FEMININE = ( + (1, "одна"), + (2, "дві"), + (3, "три"), + (4, "чотири"), + (5, "п'ять"), + (6, "шість"), + (7, "сім"), + (8, "вісім"), + (9, "дев'ять"), + (10, "десять"), + (10.02, "десять кома нуль дві"), + (11, "одинадцять"), + (12, "дванадцять"), + (12.40, "дванадцять кома чотири"), + (13, "тринадцять"), + (14, "чотирнадцять"), + (14.13, "чотирнадцять кома тринадцять"), + (15, "п'ятнадцять"), + (16, "шістнадцять"), + (17, "сімнадцять"), + (17.31, "сімнадцять кома тридцять одна"), + (18, "вісімнадцять"), + (19, "дев'ятнадцять"), + (20, "двадцять"), + (21, "двадцять одна"), + (21.20, "двадцять одна кома дві"), + (30, "тридцять"), + (32, "тридцять дві"), + (40, "сорок"), + (43, "сорок три"), + (43.007, "сорок три кома нуль нуль сім"), + (50, "п'ятдесят"), + (54, "п'ятдесят чотири"), + (60, "шістдесят"), + (60.059, "шістдесят кома нуль п'ятдесят дев'ять"), + (65, "шістдесят п'ять"), + (70, "сімдесят"), + (76, "сімдесят шість"), + (80, "вісімдесят"), + (87, "вісімдесят сім"), + (90, "дев'яносто"), + (98, "дев'яносто вісім"), + (99, "дев'яносто дев'ять"), + (100, "сто"), + (101, "сто одна"), + (199, "сто дев'яносто дев'ять"), + (200, "двісті"), + (203, "двісті три"), + (300, "триста"), + (356, "триста п'ятдесят шість"), + (400, "чотириста"), + (434, "чотириста тридцять чотири"), + (500, "п'ятсот"), + (578, "п'ятсот сімдесят вісім"), + (600, "шістсот"), + (689, "шістсот вісімдесят дев'ять"), + (700, "сімсот"), + (729, "сімсот двадцять дев'ять"), + (800, "вісімсот"), + (894, "вісімсот дев'яносто чотири"), + (900, "дев'ятсот"), + (999, "дев'ятсот дев'яносто дев'ять"), + (1000, "одна тисяча"), + (1001, "одна тисяча одна"), + (2012, "дві тисячі дванадцять"), + (12519, "дванадцять тисяч п'ятсот дев'ятнадцять"), + (12519.85, "дванадцять тисяч п'ятсот дев'ятнадцять кома вісімдесят п'ять"), + (-260000, "мінус двісті шістдесят тисяч"), + (1000000, "один мільйон"), + (1000000000, "один мільярд"), + (1234567890, "один мільярд двісті тридцять чотири мільйони " + "п'ятсот шістдесят сім тисяч вісімсот дев'яносто"), + (1000000000000, "один трильйон"), + (1000000000000000, "один квадрильйон"), + (1000000000000000000, "один квінтильйон"), + (1000000000000000000000, "один секстильйон"), + (1000000000000000000000000, "один септильйон"), + (1000000000000000000000000000, "один октильйон"), + (1000000000000000000000000000000, "один нонільйон"), + (215461407892039002157189883901676, + "двісті п'ятнадцять нонільйонів чотириста шістдесят один " + "октильйон чотириста сім септильйонів вісімсот дев'яносто " + "два секстильйони тридцять дев'ять квінтильйонів два " + "квадрильйони сто п'ятдесят сім трильйонів сто вісімдесят " + "дев'ять мільярдів вісімсот вісімдесят три мільйони " + "дев'ятсот одна тисяча шістсот сімдесят шість"), + (719094234693663034822824384220291, + "сімсот дев'ятнадцять нонільйонів дев'яносто чотири октильйони " + "двісті тридцять чотири септильйони шістсот дев'яносто три " + "секстильйони шістсот шістдесят три квінтильйони тридцять " + "чотири квадрильйони вісімсот двадцять два трильйони вісімсот " + "двадцять чотири мільярди триста вісімдесят чотири мільйони " + "двісті двадцять тисяч двісті дев'яносто одна") +) + +TEST_CASES_CARDINAL_GENITIVE = ( + (1, "одного"), + (2, "двох"), + (3, "трьох"), + (4, "чотирьох"), + (5, "п'яти"), + (6, "шести"), + (7, "семи"), + (8, "восьми"), + (9, "дев'яти"), + (10, "десяти"), + (10.02, "десяти кома нуль двох"), + (11, "одинадцяти"), + (12, "дванадцяти"), + (12.40, "дванадцяти кома чотирьох"), + (13, "тринадцяти"), + (14, "чотирнадцяти"), + (14.13, "чотирнадцяти кома тринадцяти"), + (15, "п'ятнадцяти"), + (16, "шістнадцяти"), + (17, "сімнадцяти"), + (17.31, "сімнадцяти кома тридцяти одного"), + (18, "вісімнадцяти"), + (19, "дев'ятнадцяти"), + (20, "двадцяти"), + (21, "двадцяти одного"), + (21.20, "двадцяти одного кома двох"), + (30, "тридцяти"), + (32, "тридцяти двох"), + (40, "сорока"), + (43, "сорока трьох"), + (43.007, "сорока трьох кома нуль нуль семи"), + (50, "п'ятдесяти"), + (54, "п'ятдесяти чотирьох"), + (60, "шістдесяти"), + (60.059, "шістдесяти кома нуль п'ятдесяти дев'яти"), + (65, "шістдесяти п'яти"), + (70, "сімдесяти"), + (76, "сімдесяти шести"), + (80, "вісімдесяти"), + (87, "вісімдесяти семи"), + (90, "дев'яноста"), + (98, "дев'яноста восьми"), + (99, "дев'яноста дев'яти"), + (100, "ста"), + (101, "ста одного"), + (199, "ста дев'яноста дев'яти"), + (200, "двохста"), + (203, "двохста трьох"), + (300, "трьохста"), + (356, "трьохста п'ятдесяти шести"), + (400, "чотирьохста"), + (434, "чотирьохста тридцяти чотирьох"), + (500, "п'ятиста"), + (578, "п'ятиста сімдесяти восьми"), + (600, "шестиста"), + (689, "шестиста вісімдесяти дев'яти"), + (700, "семиста"), + (729, "семиста двадцяти дев'яти"), + (800, "восьмиста"), + (894, "восьмиста дев'яноста чотирьох"), + (900, "дев'ятиста"), + (999, "дев'ятиста дев'яноста дев'яти"), + (1000, "однієї тисячи"), + (1001, "однієї тисячи одного"), + (2012, "двох тисяч дванадцяти"), + (12519, "дванадцяти тисяч п'ятиста дев'ятнадцяти"), + (12519.85, "дванадцяти тисяч п'ятиста дев'ятнадцяти " + "кома вісімдесяти п'яти"), + (-260000, "мінус двохста шістдесяти тисяч"), + (1000000, "одного мільйона"), + (1000000000, "одного мільярда"), + (1234567890, "одного мільярда двохста тридцяти чотирьох мільйонів " + "п'ятиста шістдесяти семи тисяч восьмиста дев'яноста"), + (1000000000000, "одного трильйона"), + (1000000000000000, "одного квадрильйона"), + (1000000000000000000, "одного квінтильйона"), + (1000000000000000000000, "одного секстильйона"), + (1000000000000000000000000, "одного септильйона"), + (1000000000000000000000000000, "одного октильйона"), + (1000000000000000000000000000000, "одного нонільйона"), + (215461407892039002157189883901676, + "двохста п'ятнадцяти нонільйонів чотирьохста шістдесяти одного " + "октильйона чотирьохста семи септильйонів восьмиста дев'яноста " + "двох секстильйонів тридцяти дев'яти квінтильйонів двох " + "квадрильйонів ста п'ятдесяти семи трильйонів ста вісімдесяти " + "дев'яти мільярдів восьмиста вісімдесяти трьох мільйонів " + "дев'ятиста однієї тисячи шестиста сімдесяти шести"), + (719094234693663034822824384220291, + "семиста дев'ятнадцяти нонільйонів дев'яноста чотирьох октильйонів " + "двохста тридцяти чотирьох септильйонів шестиста дев'яноста трьох " + "секстильйонів шестиста шістдесяти трьох квінтильйонів тридцяти " + "чотирьох квадрильйонів восьмиста двадцяти двох трильйонів восьмиста " + "двадцяти чотирьох мільярдів трьохста вісімдесяти чотирьох мільйонів " + "двохста двадцяти тисяч двохста дев'яноста одного") +) + +TEST_CASES_CARDINAL_DATIVE = ( + (1, "одному"), + (2, "двом"), + (3, "трьом"), + (4, "чотирьом"), + (5, "п'яти"), + (6, "шести"), + (7, "семи"), + (8, "восьми"), + (9, "дев'яти"), + (10, "десяти"), + (10.02, "десяти кома нуль двом"), + (11, "одинадцяти"), + (12, "дванадцяти"), + (12.40, "дванадцяти кома чотирьом"), + (13, "тринадцяти"), + (14, "чотирнадцяти"), + (14.13, "чотирнадцяти кома тринадцяти"), + (15, "п'ятнадцяти"), + (16, "шістнадцяти"), + (17, "сімнадцяти"), + (17.31, "сімнадцяти кома тридцяти одному"), + (18, "вісімнадцяти"), + (19, "дев'ятнадцяти"), + (20, "двадцяти"), + (21, "двадцяти одному"), + (21.20, "двадцяти одному кома двом"), + (30, "тридцяти"), + (32, "тридцяти двом"), + (40, "сорока"), + (43, "сорока трьом"), + (43.007, "сорока трьом кома нуль нуль семи"), + (50, "п'ятдесяти"), + (54, "п'ятдесяти чотирьом"), + (60, "шістдесяти"), + (60.059, "шістдесяти кома нуль п'ятдесяти дев'яти"), + (65, "шістдесяти п'яти"), + (70, "сімдесяти"), + (76, "сімдесяти шести"), + (80, "вісімдесяти"), + (87, "вісімдесяти семи"), + (90, "дев'яноста"), + (98, "дев'яноста восьми"), + (99, "дев'яноста дев'яти"), + (100, "ста"), + (101, "ста одному"), + (199, "ста дев'яноста дев'яти"), + (200, "двомстам"), + (203, "двомстам трьом"), + (300, "трьомстам"), + (356, "трьомстам п'ятдесяти шести"), + (400, "чотирьомстам"), + (434, "чотирьомстам тридцяти чотирьом"), + (500, "п'ятистам"), + (578, "п'ятистам сімдесяти восьми"), + (600, "шестистам"), + (689, "шестистам вісімдесяти дев'яти"), + (700, "семистам"), + (729, "семистам двадцяти дев'яти"), + (800, "восьмистам"), + (894, "восьмистам дев'яноста чотирьом"), + (900, "дев'ятистам"), + (999, "дев'ятистам дев'яноста дев'яти"), + (1000, "одній тисячі"), + (1001, "одній тисячі одному"), + (2012, "двом тисячам дванадцяти"), + (12519, "дванадцяти тисячам п'ятистам дев'ятнадцяти"), + (12519.85, "дванадцяти тисячам п'ятистам дев'ятнадцяти " + "кома вісімдесяти п'яти"), + (-260000, "мінус двомстам шістдесяти тисячам"), + (1000000, "одному мільйону"), + (1000000000, "одному мільярду"), + (1234567890, "одному мільярду двомстам тридцяти чотирьом мільйонам " + "п'ятистам шістдесяти семи тисячам восьмистам дев'яноста"), + (1000000000000, "одному трильйону"), + (1000000000000000, "одному квадрильйону"), + (1000000000000000000, "одному квінтильйону"), + (1000000000000000000000, "одному секстильйону"), + (1000000000000000000000000, "одному септильйону"), + (1000000000000000000000000000, "одному октильйону"), + (1000000000000000000000000000000, "одному нонільйону"), + (215461407892039002157189883901676, + "двомстам п'ятнадцяти нонільйонам чотирьомстам шістдесяти одному " + "октильйону чотирьомстам семи септильйонам восьмистам дев'яноста " + "двом секстильйонам тридцяти дев'яти квінтильйонам двом " + "квадрильйонам ста п'ятдесяти семи трильйонам ста вісімдесяти " + "дев'яти мільярдам восьмистам вісімдесяти трьом мільйонам " + "дев'ятистам одній тисячі шестистам сімдесяти шести"), + (719094234693663034822824384220291, + "семистам дев'ятнадцяти нонільйонам дев'яноста чотирьом октильйонам " + "двомстам тридцяти чотирьом септильйонам шестистам дев'яноста трьом " + "секстильйонам шестистам шістдесяти трьом квінтильйонам тридцяти " + "чотирьом квадрильйонам восьмистам двадцяти двом трильйонам восьмистам " + "двадцяти чотирьом мільярдам трьомстам вісімдесяти чотирьом мільйонам " + "двомстам двадцяти тисячам двомстам дев'яноста одному") +) + +TEST_CASES_CARDINAL_ACCUSATIVE = ( + (1, "один"), + (2, "два"), + (3, "три"), + (4, "чотири"), + (5, "п'ять"), + (6, "шість"), + (7, "сім"), + (8, "вісім"), + (9, "дев'ять"), + (10, "десять"), + (10.02, "десять кома нуль два"), + (11, "одинадцять"), + (12, "дванадцять"), + (12.40, "дванадцять кома чотири"), + (13, "тринадцять"), + (14, "чотирнадцять"), + (14.13, "чотирнадцять кома тринадцять"), + (15, "п'ятнадцять"), + (16, "шістнадцять"), + (17, "сімнадцять"), + (17.31, "сімнадцять кома тридцять один"), + (18, "вісімнадцять"), + (19, "дев'ятнадцять"), + (20, "двадцять"), + (21, "двадцять один"), + (21.20, "двадцять один кома два"), + (30, "тридцять"), + (32, "тридцять два"), + (40, "сорок"), + (43, "сорок три"), + (43.007, "сорок три кома нуль нуль сім"), + (50, "п'ятдесят"), + (54, "п'ятдесят чотири"), + (60, "шістдесят"), + (60.059, "шістдесят кома нуль п'ятдесят дев'ять"), + (65, "шістдесят п'ять"), + (70, "сімдесят"), + (76, "сімдесят шість"), + (80, "вісімдесят"), + (87, "вісімдесят сім"), + (90, "дев'яносто"), + (98, "дев'яносто вісім"), + (99, "дев'яносто дев'ять"), + (100, "сто"), + (101, "сто один"), + (199, "сто дев'яносто дев'ять"), + (200, "двісті"), + (203, "двісті три"), + (300, "триста"), + (356, "триста п'ятдесят шість"), + (400, "чотириста"), + (434, "чотириста тридцять чотири"), + (500, "п'ятсот"), + (578, "п'ятсот сімдесят вісім"), + (600, "шістсот"), + (689, "шістсот вісімдесят дев'ять"), + (700, "сімсот"), + (729, "сімсот двадцять дев'ять"), + (800, "вісімсот"), + (894, "вісімсот дев'яносто чотири"), + (900, "дев'ятсот"), + (999, "дев'ятсот дев'яносто дев'ять"), + (1000, "одну тисячу"), + (1001, "одну тисячу один"), + (2012, "дві тисячі дванадцять"), + (12519, "дванадцять тисяч п'ятсот дев'ятнадцять"), + (12519.85, "дванадцять тисяч п'ятсот дев'ятнадцять кома вісімдесят п'ять"), + (-260000, "мінус двісті шістдесят тисяч"), + (1000000, "один мільйон"), + (1000000000, "один мільярд"), + (1234567890, "один мільярд двісті тридцять чотири мільйони " + "п'ятсот шістдесят сім тисяч вісімсот дев'яносто"), + (1000000000000, "один трильйон"), + (1000000000000000, "один квадрильйон"), + (1000000000000000000, "один квінтильйон"), + (1000000000000000000000, "один секстильйон"), + (1000000000000000000000000, "один септильйон"), + (1000000000000000000000000000, "один октильйон"), + (1000000000000000000000000000000, "один нонільйон"), + (215461407892039002157189883901676, + "двісті п'ятнадцять нонільйонів чотириста шістдесят один " + "октильйон чотириста сім септильйонів вісімсот дев'яносто " + "два секстильйони тридцять дев'ять квінтильйонів два " + "квадрильйони сто п'ятдесят сім трильйонів сто вісімдесят " + "дев'ять мільярдів вісімсот вісімдесят три мільйони " + "дев'ятсот одну тисячу шістсот сімдесят шість"), + (719094234693663034822824384220291, + "сімсот дев'ятнадцять нонільйонів дев'яносто чотири октильйони " + "двісті тридцять чотири септильйони шістсот дев'яносто три " + "секстильйони шістсот шістдесят три квінтильйони тридцять " + "чотири квадрильйони вісімсот двадцять два трильйони вісімсот " + "двадцять чотири мільярди триста вісімдесят чотири мільйони " + "двісті двадцять тисяч двісті дев'яносто один") +) + +TEST_CASES_CARDINAL_INSTRUMENTAL = ( + (1, "одним"), + (2, "двома"), + (3, "трьома"), + (4, "чотирма"), + (5, "п'ятьма"), + (6, "шістьма"), + (7, "сьома"), + (8, "вісьма"), + (9, "дев'ятьма"), + (10, "десятьма"), + (10.02, "десятьма кома нуль двома"), + (11, "одинадцятьма"), + (12, "дванадцятьма"), + (12.40, "дванадцятьма кома чотирма"), + (13, "тринадцятьма"), + (14, "чотирнадцятьма"), + (14.13, "чотирнадцятьма кома тринадцятьма"), + (15, "п'ятнадцятьма"), + (16, "шістнадцятьма"), + (17, "сімнадцятьма"), + (17.31, "сімнадцятьма кома тридцятьма одним"), + (18, "вісімнадцятьма"), + (19, "дев'ятнадцятьма"), + (20, "двадцятьма"), + (21, "двадцятьма одним"), + (21.20, "двадцятьма одним кома двома"), + (30, "тридцятьма"), + (32, "тридцятьма двома"), + (40, "сорока"), + (43, "сорока трьома"), + (43.007, "сорока трьома кома нуль нуль сьома"), + (50, "п'ятдесятьма"), + (54, "п'ятдесятьма чотирма"), + (60, "шістдесятьма"), + (60.059, "шістдесятьма кома нуль п'ятдесятьма дев'ятьма"), + (65, "шістдесятьма п'ятьма"), + (70, "сімдесятьма"), + (76, "сімдесятьма шістьма"), + (80, "вісімдесятьма"), + (87, "вісімдесятьма сьома"), + (90, "дев'яностами"), + (98, "дев'яностами вісьма"), + (99, "дев'яностами дев'ятьма"), + (100, "стами"), + (101, "стами одним"), + (199, "стами дев'яностами дев'ятьма"), + (200, "двомастами"), + (203, "двомастами трьома"), + (300, "трьомастами"), + (356, "трьомастами п'ятдесятьма шістьма"), + (400, "чотирмастами"), + (434, "чотирмастами тридцятьма чотирма"), + (500, "п'ятьмастами"), + (578, "п'ятьмастами сімдесятьма вісьма"), + (600, "шістьмастами"), + (689, "шістьмастами вісімдесятьма дев'ятьма"), + (700, "сьомастами"), + (729, "сьомастами двадцятьма дев'ятьма"), + (800, "восьмастами"), + (894, "восьмастами дев'яностами чотирма"), + (900, "дев'ятьмастами"), + (999, "дев'ятьмастами дев'яностами дев'ятьма"), + (1000, "однією тисячею"), + (1001, "однією тисячею одним"), + (2012, "двома тисячами дванадцятьма"), + (12519, "дванадцятьма тисячами п'ятьмастами дев'ятнадцятьма"), + (12519.85, "дванадцятьма тисячами п'ятьмастами дев'ятнадцятьма " + "кома вісімдесятьма п'ятьма"), + (-260000, "мінус двомастами шістдесятьма тисячами"), + (1000000, "одним мільйоном"), + (1000000000, "одним мільярдом"), + (1234567890, "одним мільярдом двомастами тридцятьма чотирма мільйонами " + "п'ятьмастами шістдесятьма сьома тисячами восьмастами " + "дев'яностами"), + (1000000000000, "одним трильйоном"), + (1000000000000000, "одним квадрильйоном"), + (1000000000000000000, "одним квінтильйоном"), + (1000000000000000000000, "одним секстильйоном"), + (1000000000000000000000000, "одним септильйоном"), + (1000000000000000000000000000, "одним октильйоном"), + (1000000000000000000000000000000, "одним нонільйоном"), + (215461407892039002157189883901676, + "двомастами п'ятнадцятьма нонільйонів чотирмастами шістдесятьма одним " + "октильйоном чотирмастами сьома септильйонів восьмастами дев'яностами " + "двома секстильйонами тридцятьма дев'ятьма квінтильйонів двома " + "квадрильйонами стами п'ятдесятьма сьома трильйонів стами вісімдесятьма " + "дев'ятьма мільярдів восьмастами вісімдесятьма трьома мільйонами " + "дев'ятьмастами однією тисячею шістьмастами сімдесятьма шістьма"), + (719094234693663034822824384220291, + "сьомастами дев'ятнадцятьма нонільйонів дев'яностами чотирма " + "октильйонами двомастами тридцятьма чотирма септильйонами шістьмастами " + "дев'яностами трьома секстильйонами шістьмастами шістдесятьма трьома " + "квінтильйонами тридцятьма чотирма квадрильйонами восьмастами двадцятьма " + "двома трильйонами восьмастами двадцятьма чотирма мільярдами трьомастами " + "вісімдесятьма чотирма мільйонами двомастами двадцятьма тисячами " + "двомастами дев'яностами одним") +) + +TEST_CASES_CARDINAL_LOCATIVE = ( + (1, "одному"), + (2, "двох"), + (3, "трьох"), + (4, "чотирьох"), + (5, "п'яти"), + (6, "шести"), + (7, "семи"), + (8, "восьми"), + (9, "дев'яти"), + (10, "десяти"), + (10.02, "десяти кома нуль двох"), + (11, "одинадцяти"), + (12, "дванадцяти"), + (12.40, "дванадцяти кома чотирьох"), + (13, "тринадцяти"), + (14, "чотирнадцяти"), + (14.13, "чотирнадцяти кома тринадцяти"), + (15, "п'ятнадцяти"), + (16, "шістнадцяти"), + (17, "сімнадцяти"), + (17.31, "сімнадцяти кома тридцяти одному"), + (18, "вісімнадцяти"), + (19, "дев'ятнадцяти"), + (20, "двадцяти"), + (21, "двадцяти одному"), + (21.20, "двадцяти одному кома двох"), + (30, "тридцяти"), + (32, "тридцяти двох"), + (40, "сорока"), + (43, "сорока трьох"), + (43.007, "сорока трьох кома нуль нуль семи"), + (50, "п'ятдесяти"), + (54, "п'ятдесяти чотирьох"), + (60, "шістдесяти"), + (60.059, "шістдесяти кома нуль п'ятдесяти дев'яти"), + (65, "шістдесяти п'яти"), + (70, "сімдесяти"), + (76, "сімдесяти шести"), + (80, "вісімдесяти"), + (87, "вісімдесяти семи"), + (90, "дев'яноста"), + (98, "дев'яноста восьми"), + (99, "дев'яноста дев'яти"), + (100, "стах"), + (101, "стах одному"), + (199, "стах дев'яноста дев'яти"), + (200, "двохстах"), + (203, "двохстах трьох"), + (300, "трьохстах"), + (356, "трьохстах п'ятдесяти шести"), + (400, "чотирьохстах"), + (434, "чотирьохстах тридцяти чотирьох"), + (500, "п'ятистах"), + (578, "п'ятистах сімдесяти восьми"), + (600, "шестистах"), + (689, "шестистах вісімдесяти дев'яти"), + (700, "семистах"), + (729, "семистах двадцяти дев'яти"), + (800, "восьмистах"), + (894, "восьмистах дев'яноста чотирьох"), + (900, "дев'ятистах"), + (999, "дев'ятистах дев'яноста дев'яти"), + (1000, "одній тисячі"), + (1001, "одній тисячі одному"), + (2012, "двох тисячах дванадцяти"), + (12519, "дванадцяти тисячах п'ятистах дев'ятнадцяти"), + (12519.85, "дванадцяти тисячах п'ятистах дев'ятнадцяти " + "кома вісімдесяти п'яти"), + (-260000, "мінус двохстах шістдесяти тисячах"), + (1000000, "одному мільйоні"), + (1000000000, "одному мільярді"), + (1234567890, "одному мільярді двохстах тридцяти чотирьох мільйонах " + "п'ятистах шістдесяти семи тисячах восьмистах дев'яноста"), + (1000000000000, "одному трильйоні"), + (1000000000000000, "одному квадрильйоні"), + (1000000000000000000, "одному квінтильйоні"), + (1000000000000000000000, "одному секстильйоні"), + (1000000000000000000000000, "одному септильйоні"), + (1000000000000000000000000000, "одному октильйоні"), + (1000000000000000000000000000000, "одному нонільйоні"), + (215461407892039002157189883901676, + "двохстах п'ятнадцяти нонільйонах чотирьохстах шістдесяти одному " + "октильйоні чотирьохстах семи септильйонах восьмистах дев'яноста " + "двох секстильйонах тридцяти дев'яти квінтильйонах двох " + "квадрильйонах стах п'ятдесяти семи трильйонах стах вісімдесяти " + "дев'яти мільярдах восьмистах вісімдесяти трьох мільйонах " + "дев'ятистах одній тисячі шестистах сімдесяти шести"), + (719094234693663034822824384220291, + "семистах дев'ятнадцяти нонільйонах дев'яноста чотирьох октильйонах " + "двохстах тридцяти чотирьох септильйонах шестистах дев'яноста трьох " + "секстильйонах шестистах шістдесяти трьох квінтильйонах тридцяти " + "чотирьох квадрильйонах восьмистах двадцяти двох трильйонах восьмистах " + "двадцяти чотирьох мільярдах трьохстах вісімдесяти чотирьох мільйонах " + "двохстах двадцяти тисячах двохстах дев'яноста одному") +) + +TEST_CASES_ORDINAL = ( + (1, "перший"), + (2, "другий"), + (3, "третій"), + (4, "четвертий"), + (5, "п'ятий"), + (6, "шостий"), + (7, "сьомий"), + (8, "восьмий"), + (9, "дев'ятий"), + (10, "десятий"), + (11, "одинадцятий"), + (12, "дванадцятий"), + (13, "тринадцятий"), + (14, "чотирнадцятий"), + (15, "п'ятнадцятий"), + (16, "шістнадцятий"), + (17, "сімнадцятий"), + (18, "вісімнадцятий"), + (19, "дев'ятнадцятий"), + (20, "двадцятий"), + (21, "двадцять перший"), + (30, "тридцятий"), + (32, "тридцять другий"), + (40, "сороковий"), + (43, "сорок третій"), + (50, "п'ятдесятий"), + (54, "п'ятдесят четвертий"), + (60, "шістдесятий"), + (65, "шістдесят п'ятий"), + (70, "сімдесятий"), + (76, "сімдесят шостий"), + (80, "вісімдесятий"), + (87, "вісімдесят сьомий"), + (90, "дев'яностий"), + (98, "дев'яносто восьмий"), + (100, "сотий"), + (101, "сто перший"), + (199, "сто дев'яносто дев'ятий"), + (200, "двохсотий"), + (203, "двісті третій"), + (300, "трьохсотий"), + (356, "триста п'ятдесят шостий"), + (400, "чотирьохсотий"), + (434, "чотириста тридцять четвертий"), + (500, "п'ятисотий"), + (578, "п'ятсот сімдесят восьмий"), + (600, "шестисотий"), + (690, "шістсот дев'яностий"), + (700, "семисотий"), + (729, "сімсот двадцять дев'ятий"), + (800, "восьмисотий"), + (894, "вісімсот дев'яносто четвертий"), + (900, "дев'ятисотий"), + (999, "дев'ятсот дев'яносто дев'ятий"), + (1000, "тисячний"), + (1001, "одна тисяча перший"), + (2000, "двохтисячний"), + (2312, "дві тисячі триста дванадцятий"), + (12000, "дванадцятитисячний"), + (25000, "двадцятип'ятитисячний"), + (213000, "двохсоттринадцятитисячний"), + (256000, "двохсотп'ятдесятишеститисячний"), + (260000, "двохсотшістдесятитисячний"), + (1000000, "мільйонний"), + (589000000, "п'ятсотвісімдесятидев'ятимільйонний"), + (1000000000, "мільярдний"), + (1234567890, "один мільярд двісті тридцять чотири мільйони " + "п'ятсот шістдесят сім тисяч вісімсот дев'яностий"), + (1000000000000, "трильйонний"), + (1000000000000000, "квадрильйонний"), + (1000000000000000000, "квінтильйонний"), + (1000000000000000000000, "секстильйонний"), + (1000000000000000000000000, "септильйонний"), + (1000000000000000000000000000, "октильйонний"), + (1000000000000000000000000000000, "нонільйонний"), + (956000000000000000000000000000000, + "дев'ятсотп'ятдесятишестинонільйонний"), +) + +TEST_CASES_TO_CURRENCY_AED = ( + (0.00, "нуль дирхамів, нуль філсів"), + (1.00, "один дирхам, нуль філсів"), + (2.00, "два дирхами, нуль філсів"), + (5.00, "п'ять дирхамів, нуль філсів"), + (11.00, "одинадцять дирхамів, нуль філсів"), + (16.01, "шістнадцять дирхамів, один філс"), + (21.00, "двадцять один дирхам, нуль філсів"), + (37.73, "тридцять сім дирхамів, сімдесят три філси"), + (81.25, "вісімдесят один дирхам, двадцять п'ять філсів"), + (100.00, "сто дирхамів, нуль філсів"), + (101.11, "сто один дирхам, одинадцять філсів"), + (10222, "сто два дирхами, двадцять два філси"), + +) + +TEST_CASES_TO_CURRENCY_AFN = ( + (0.00, "нуль афгані, нуль пулів"), + (1.00, "один афгані, нуль пулів"), + (2.00, "два афгані, нуль пулів"), + (5.00, "п'ять афгані, нуль пулів"), + (11.00, "одинадцять афгані, нуль пулів"), + (16.01, "шістнадцять афгані, один пул"), + (21.00, "двадцять один афгані, нуль пулів"), + (37.73, "тридцять сім афгані, сімдесят три пули"), + (81.25, "вісімдесят один афгані, двадцять п'ять пулів"), + (100.00, "сто афгані, нуль пулів"), + (101.11, "сто один афгані, одинадцять пулів"), + (10222, "сто два афгані, двадцять два пули"), +) + +TEST_CASES_TO_CURRENCY_ALL = ( + (0.00, "нуль леків, нуль кіндарок"), + (1.00, "один лек, нуль кіндарок"), + (2.00, "два леки, нуль кіндарок"), + (5.00, "п'ять леків, нуль кіндарок"), + (11.00, "одинадцять леків, нуль кіндарок"), + (16.01, "шістнадцять леків, одна кіндарка"), + (21.00, "двадцять один лек, нуль кіндарок"), + (37.73, "тридцять сім леків, сімдесят три кіндарки"), + (81.25, "вісімдесят один лек, двадцять п'ять кіндарок"), + (100.00, "сто леків, нуль кіндарок"), + (101.11, "сто один лек, одинадцять кіндарок"), + (10222, "сто два леки, двадцять дві кіндарки"), +) + +TEST_CASES_TO_CURRENCY_AMD = ( + (0.00, "нуль драмів, нуль лум"), + (1.00, "один драм, нуль лум"), + (2.00, "два драми, нуль лум"), + (5.00, "п'ять драмів, нуль лум"), + (11.00, "одинадцять драмів, нуль лум"), + (16.01, "шістнадцять драмів, один лум"), + (21.00, "двадцять один драм, нуль лум"), + (37.73, "тридцять сім драмів, сімдесят три лум"), + (81.25, "вісімдесят один драм, двадцять п'ять лум"), + (100.00, "сто драмів, нуль лум"), + (101.11, "сто один драм, одинадцять лум"), + (10222, "сто два драми, двадцять два лум"), +) + +TEST_CASES_TO_CURRENCY_ANG = ( + (0.00, "нуль гульденів, нуль центів"), + (1.00, "один гульден, нуль центів"), + (2.00, "два гульдени, нуль центів"), + (5.00, "п'ять гульденів, нуль центів"), + (11.00, "одинадцять гульденів, нуль центів"), + (16.01, "шістнадцять гульденів, один цент"), + (21.00, "двадцять один гульден, нуль центів"), + (37.73, "тридцять сім гульденів, сімдесят три центи"), + (81.25, "вісімдесят один гульден, двадцять п'ять центів"), + (100.00, "сто гульденів, нуль центів"), + (101.11, "сто один гульден, одинадцять центів"), + (10222, "сто два гульдени, двадцять два центи"), +) +# +TEST_CASES_TO_CURRENCY_AOA = ( + (0.00, "нуль кванз, нуль сентимо"), + (1.00, "одна кванза, нуль сентимо"), + (2.00, "дві кванзи, нуль сентимо"), + (5.00, "п'ять кванз, нуль сентимо"), + (11.00, "одинадцять кванз, нуль сентимо"), + (16.01, "шістнадцять кванз, один сентимо"), + (21.00, "двадцять одна кванза, нуль сентимо"), + (37.73, "тридцять сім кванз, сімдесят три сентимо"), + (81.25, "вісімдесят одна кванза, двадцять п'ять сентимо"), + (100.00, "сто кванз, нуль сентимо"), + (101.11, "сто одна кванза, одинадцять сентимо"), + (10222, "сто дві кванзи, двадцять два сентимо"), +) +# +TEST_CASES_TO_CURRENCY_ARS = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) +# +TEST_CASES_TO_CURRENCY_AUD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) +# +TEST_CASES_TO_CURRENCY_AWG = ( + (0.00, "нуль флоринів, нуль центів"), + (1.00, "один флорин, нуль центів"), + (2.00, "два флорини, нуль центів"), + (5.00, "п'ять флоринів, нуль центів"), + (11.00, "одинадцять флоринів, нуль центів"), + (16.01, "шістнадцять флоринів, один цент"), + (21.00, "двадцять один флорин, нуль центів"), + (37.73, "тридцять сім флоринів, сімдесят три центи"), + (81.25, "вісімдесят один флорин, двадцять п'ять центів"), + (100.00, "сто флоринів, нуль центів"), + (101.11, "сто один флорин, одинадцять центів"), + (10222, "сто два флорини, двадцять два центи"), +) +# +TEST_CASES_TO_CURRENCY_AZN = ( + (0.00, "нуль манатів, нуль гяпіків"), + (1.00, "один манат, нуль гяпіків"), + (2.00, "два манати, нуль гяпіків"), + (5.00, "п'ять манатів, нуль гяпіків"), + (11.00, "одинадцять манатів, нуль гяпіків"), + (16.01, "шістнадцять манатів, один гяпік"), + (21.00, "двадцять один манат, нуль гяпіків"), + (37.73, "тридцять сім манатів, сімдесят три гяпіки"), + (81.25, "вісімдесят один манат, двадцять п'ять гяпіків"), + (100.00, "сто манатів, нуль гяпіків"), + (101.11, "сто один манат, одинадцять гяпіків"), + (10222, "сто два манати, двадцять два гяпіки"), +) +# +TEST_CASES_TO_CURRENCY_BAM = ( + (0.00, "нуль марок, нуль фенінгів"), + (1.00, "одна марка, нуль фенінгів"), + (2.00, "дві марки, нуль фенінгів"), + (5.00, "п'ять марок, нуль фенінгів"), + (11.00, "одинадцять марок, нуль фенінгів"), + (16.01, "шістнадцять марок, один фенінг"), + (21.00, "двадцять одна марка, нуль фенінгів"), + (37.73, "тридцять сім марок, сімдесят три фенінги"), + (81.25, "вісімдесят одна марка, двадцять п'ять фенінгів"), + (100.00, "сто марок, нуль фенінгів"), + (101.11, "сто одна марка, одинадцять фенінгів"), + (10222, "сто дві марки, двадцять два фенінги"), +) +# +TEST_CASES_TO_CURRENCY_BBD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_BDT = ( + (0.00, "нуль так, нуль пойш"), + (1.00, "одна така, нуль пойш"), + (2.00, "дві таки, нуль пойш"), + (5.00, "п'ять так, нуль пойш"), + (11.00, "одинадцять так, нуль пойш"), + (16.01, "шістнадцять так, одна пойша"), + (21.00, "двадцять одна така, нуль пойш"), + (37.73, "тридцять сім так, сімдесят три пойші"), + (81.25, "вісімдесят одна така, двадцять п'ять пойш"), + (100.00, "сто так, нуль пойш"), + (101.11, "сто одна така, одинадцять пойш"), + (10222, "сто дві таки, двадцять дві пойші"), +) + +TEST_CASES_TO_CURRENCY_BGN = ( + (0.00, "нуль левів, нуль стотинок"), + (1.00, "один лев, нуль стотинок"), + (2.00, "два леви, нуль стотинок"), + (5.00, "п'ять левів, нуль стотинок"), + (11.00, "одинадцять левів, нуль стотинок"), + (16.01, "шістнадцять левів, одна стотинка"), + (21.00, "двадцять один лев, нуль стотинок"), + (37.73, "тридцять сім левів, сімдесят три стотинки"), + (81.25, "вісімдесят один лев, двадцять п'ять стотинок"), + (100.00, "сто левів, нуль стотинок"), + (101.11, "сто один лев, одинадцять стотинок"), + (10222, "сто два леви, двадцять дві стотинки"), +) + +TEST_CASES_TO_CURRENCY_BHD = ( + (0.00, "нуль динарів, нуль філсів"), + (1.00, "один динар, нуль філсів"), + (2.00, "два динари, нуль філсів"), + (5.00, "п'ять динарів, нуль філсів"), + (11.00, "одинадцять динарів, нуль філсів"), + (16.01, "шістнадцять динарів, один філс"), + (21.00, "двадцять один динар, нуль філсів"), + (37.73, "тридцять сім динарів, сімдесят три філси"), + (81.25, "вісімдесят один динар, двадцять п'ять філсів"), + (100.00, "сто динарів, нуль філсів"), + (101.11, "сто один динар, одинадцять філсів"), + (10222, "сто два динари, двадцять два філси"), +) + +TEST_CASES_TO_CURRENCY_BIF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_BMD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_BND = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_BOB = ( + (0.00, "нуль болівіано, нуль сентаво"), + (1.00, "один болівіано, нуль сентаво"), + (2.00, "два болівіано, нуль сентаво"), + (5.00, "п'ять болівіано, нуль сентаво"), + (11.00, "одинадцять болівіано, нуль сентаво"), + (16.01, "шістнадцять болівіано, один сентаво"), + (21.00, "двадцять один болівіано, нуль сентаво"), + (37.73, "тридцять сім болівіано, сімдесят три сентаво"), + (81.25, "вісімдесят один болівіано, двадцять п'ять сентаво"), + (100.00, "сто болівіано, нуль сентаво"), + (101.11, "сто один болівіано, одинадцять сентаво"), + (10222, "сто два болівіано, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_BRL = ( + (0.00, "нуль реалів, нуль сентаво"), + (1.00, "один реал, нуль сентаво"), + (2.00, "два реали, нуль сентаво"), + (5.00, "п'ять реалів, нуль сентаво"), + (11.00, "одинадцять реалів, нуль сентаво"), + (16.01, "шістнадцять реалів, один сентаво"), + (21.00, "двадцять один реал, нуль сентаво"), + (37.73, "тридцять сім реалів, сімдесят три сентаво"), + (81.25, "вісімдесят один реал, двадцять п'ять сентаво"), + (100.00, "сто реалів, нуль сентаво"), + (101.11, "сто один реал, одинадцять сентаво"), + (10222, "сто два реали, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_BSD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_BTN = ( + (0.00, "нуль нгултрумів, нуль четрумів"), + (1.00, "один нгултрум, нуль четрумів"), + (2.00, "два нгултруми, нуль четрумів"), + (5.00, "п'ять нгултрумів, нуль четрумів"), + (11.00, "одинадцять нгултрумів, нуль четрумів"), + (16.01, "шістнадцять нгултрумів, один четрум"), + (21.00, "двадцять один нгултрум, нуль четрумів"), + (37.73, "тридцять сім нгултрумів, сімдесят три четруми"), + (81.25, "вісімдесят один нгултрум, двадцять п'ять четрумів"), + (100.00, "сто нгултрумів, нуль четрумів"), + (101.11, "сто один нгултрум, одинадцять четрумів"), + (10222, "сто два нгултруми, двадцять два четруми"), +) + +TEST_CASES_TO_CURRENCY_BWP = ( + (0.00, "нуль пул, нуль тхебе"), + (1.00, "одна пула, нуль тхебе"), + (2.00, "дві пули, нуль тхебе"), + (5.00, "п'ять пул, нуль тхебе"), + (11.00, "одинадцять пул, нуль тхебе"), + (16.01, "шістнадцять пул, один тхебе"), + (21.00, "двадцять одна пула, нуль тхебе"), + (37.73, "тридцять сім пул, сімдесят три тхебе"), + (81.25, "вісімдесят одна пула, двадцять п'ять тхебе"), + (100.00, "сто пул, нуль тхебе"), + (101.11, "сто одна пула, одинадцять тхебе"), + (10222, "сто дві пули, двадцять два тхебе"), +) + +TEST_CASES_TO_CURRENCY_BYN = ( + (0.00, "нуль рублів, нуль копійок"), + (1.00, "один рубель, нуль копійок"), + (2.00, "два рублі, нуль копійок"), + (5.00, "п'ять рублів, нуль копійок"), + (11.00, "одинадцять рублів, нуль копійок"), + (16.01, "шістнадцять рублів, одна копійка"), + (21.00, "двадцять один рубель, нуль копійок"), + (37.73, "тридцять сім рублів, сімдесят три копійки"), + (81.25, "вісімдесят один рубель, двадцять п'ять копійок"), + (100.00, "сто рублів, нуль копійок"), + (101.11, "сто один рубель, одинадцять копійок"), + (10222, "сто два рублі, двадцять дві копійки"), +) + +TEST_CASES_TO_CURRENCY_BZD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_CAD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_CDF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_CHF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_CLP = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_CNY = ( + (0.00, "нуль юанів, нуль финів"), + (1.00, "один юань, нуль финів"), + (2.00, "два юані, нуль финів"), + (5.00, "п'ять юанів, нуль финів"), + (11.00, "одинадцять юанів, нуль финів"), + (16.01, "шістнадцять юанів, один финь"), + (21.00, "двадцять один юань, нуль финів"), + (37.73, "тридцять сім юанів, сімдесят три фині"), + (81.25, "вісімдесят один юань, двадцять п'ять финів"), + (100.00, "сто юанів, нуль финів"), + (101.11, "сто один юань, одинадцять финів"), + (10222, "сто два юані, двадцять два фині"), +) + +TEST_CASES_TO_CURRENCY_COP = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_CRC = ( + (0.00, "нуль колонів, нуль сентімо"), + (1.00, "один колон, нуль сентімо"), + (2.00, "два колони, нуль сентімо"), + (5.00, "п'ять колонів, нуль сентімо"), + (11.00, "одинадцять колонів, нуль сентімо"), + (16.01, "шістнадцять колонів, один сентімо"), + (21.00, "двадцять один колон, нуль сентімо"), + (37.73, "тридцять сім колонів, сімдесят три сентімо"), + (81.25, "вісімдесят один колон, двадцять п'ять сентімо"), + (100.00, "сто колонів, нуль сентімо"), + (101.11, "сто один колон, одинадцять сентімо"), + (10222, "сто два колони, двадцять два сентімо"), +) + +TEST_CASES_TO_CURRENCY_CUC = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_CUP = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_CVE = ( + (0.00, "нуль ескудо, нуль сентаво"), + (1.00, "один ескудо, нуль сентаво"), + (2.00, "два ескудо, нуль сентаво"), + (5.00, "п'ять ескудо, нуль сентаво"), + (11.00, "одинадцять ескудо, нуль сентаво"), + (16.01, "шістнадцять ескудо, один сентаво"), + (21.00, "двадцять один ескудо, нуль сентаво"), + (37.73, "тридцять сім ескудо, сімдесят три сентаво"), + (81.25, "вісімдесят один ескудо, двадцять п'ять сентаво"), + (100.00, "сто ескудо, нуль сентаво"), + (101.11, "сто один ескудо, одинадцять сентаво"), + (10222, "сто два ескудо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_CZK = ( + (0.00, "нуль крон, нуль гелерів"), + (1.00, "одна крона, нуль гелерів"), + (2.00, "дві крони, нуль гелерів"), + (5.00, "п'ять крон, нуль гелерів"), + (11.00, "одинадцять крон, нуль гелерів"), + (16.01, "шістнадцять крон, один гелер"), + (21.00, "двадцять одна крона, нуль гелерів"), + (37.73, "тридцять сім крон, сімдесят три гелери"), + (81.25, "вісімдесят одна крона, двадцять п'ять гелерів"), + (100.00, "сто крон, нуль гелерів"), + (101.11, "сто одна крона, одинадцять гелерів"), + (10222, "сто дві крони, двадцять два гелери"), +) + +TEST_CASES_TO_CURRENCY_DJF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_DKK = ( + (0.00, "нуль крон, нуль ере"), + (1.00, "одна крона, нуль ере"), + (2.00, "дві крони, нуль ере"), + (5.00, "п'ять крон, нуль ере"), + (11.00, "одинадцять крон, нуль ере"), + (16.01, "шістнадцять крон, один ере"), + (21.00, "двадцять одна крона, нуль ере"), + (37.73, "тридцять сім крон, сімдесят три ере"), + (81.25, "вісімдесят одна крона, двадцять п'ять ере"), + (100.00, "сто крон, нуль ере"), + (101.11, "сто одна крона, одинадцять ере"), + (10222, "сто дві крони, двадцять два ере"), +) + +TEST_CASES_TO_CURRENCY_DOP = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_DZD = ( + (0.00, "нуль динарів, нуль сантимів"), + (1.00, "один динар, нуль сантимів"), + (2.00, "два динари, нуль сантимів"), + (5.00, "п'ять динарів, нуль сантимів"), + (11.00, "одинадцять динарів, нуль сантимів"), + (16.01, "шістнадцять динарів, один сантим"), + (21.00, "двадцять один динар, нуль сантимів"), + (37.73, "тридцять сім динарів, сімдесят три сантими"), + (81.25, "вісімдесят один динар, двадцять п'ять сантимів"), + (100.00, "сто динарів, нуль сантимів"), + (101.11, "сто один динар, одинадцять сантимів"), + (10222, "сто два динари, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_EGP = ( + (0.00, "нуль фунтів, нуль піастрів"), + (1.00, "один фунт, нуль піастрів"), + (2.00, "два фунти, нуль піастрів"), + (5.00, "п'ять фунтів, нуль піастрів"), + (11.00, "одинадцять фунтів, нуль піастрів"), + (16.01, "шістнадцять фунтів, один піастр"), + (21.00, "двадцять один фунт, нуль піастрів"), + (37.73, "тридцять сім фунтів, сімдесят три піастри"), + (81.25, "вісімдесят один фунт, двадцять п'ять піастрів"), + (100.00, "сто фунтів, нуль піастрів"), + (101.11, "сто один фунт, одинадцять піастрів"), + (10222, "сто два фунти, двадцять два піастри"), +) + +TEST_CASES_TO_CURRENCY_ERN = ( + (0.00, "нуль накф, нуль центів"), + (1.00, "одна накфа, нуль центів"), + (2.00, "дві накфи, нуль центів"), + (5.00, "п'ять накф, нуль центів"), + (11.00, "одинадцять накф, нуль центів"), + (16.01, "шістнадцять накф, один цент"), + (21.00, "двадцять одна накфа, нуль центів"), + (37.73, "тридцять сім накф, сімдесят три центи"), + (81.25, "вісімдесят одна накфа, двадцять п'ять центів"), + (100.00, "сто накф, нуль центів"), + (101.11, "сто одна накфа, одинадцять центів"), + (10222, "сто дві накфи, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_ETB = ( + (0.00, "нуль бирів, нуль центів"), + (1.00, "один бир, нуль центів"), + (2.00, "два бири, нуль центів"), + (5.00, "п'ять бирів, нуль центів"), + (11.00, "одинадцять бирів, нуль центів"), + (16.01, "шістнадцять бирів, один цент"), + (21.00, "двадцять один бир, нуль центів"), + (37.73, "тридцять сім бирів, сімдесят три центи"), + (81.25, "вісімдесят один бир, двадцять п'ять центів"), + (100.00, "сто бирів, нуль центів"), + (101.11, "сто один бир, одинадцять центів"), + (10222, "сто два бири, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_EUR = ( + (0.00, "нуль євро, нуль центів"), + (1.00, "один євро, нуль центів"), + (2.00, "два євро, нуль центів"), + (5.00, "п'ять євро, нуль центів"), + (11.00, "одинадцять євро, нуль центів"), + (16.01, "шістнадцять євро, один цент"), + (21.00, "двадцять один євро, нуль центів"), + (37.73, "тридцять сім євро, сімдесят три центи"), + (81.25, "вісімдесят один євро, двадцять п'ять центів"), + (100.00, "сто євро, нуль центів"), + (101.11, "сто один євро, одинадцять центів"), + (10222, "сто два євро, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_FJD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_FKP = ( + (0.00, "нуль фунтів, нуль пенсів"), + (1.00, "один фунт, нуль пенсів"), + (2.00, "два фунти, нуль пенсів"), + (5.00, "п'ять фунтів, нуль пенсів"), + (11.00, "одинадцять фунтів, нуль пенсів"), + (16.01, "шістнадцять фунтів, один пенс"), + (21.00, "двадцять один фунт, нуль пенсів"), + (37.73, "тридцять сім фунтів, сімдесят три пенси"), + (81.25, "вісімдесят один фунт, двадцять п'ять пенсів"), + (100.00, "сто фунтів, нуль пенсів"), + (101.11, "сто один фунт, одинадцять пенсів"), + (10222, "сто два фунти, двадцять два пенси"), +) + +TEST_CASES_TO_CURRENCY_GBP = ( + (0.00, "нуль фунтів, нуль пенсів"), + (1.00, "один фунт, нуль пенсів"), + (2.00, "два фунти, нуль пенсів"), + (5.00, "п'ять фунтів, нуль пенсів"), + (11.00, "одинадцять фунтів, нуль пенсів"), + (16.01, "шістнадцять фунтів, один пенс"), + (21.00, "двадцять один фунт, нуль пенсів"), + (37.73, "тридцять сім фунтів, сімдесят три пенси"), + (81.25, "вісімдесят один фунт, двадцять п'ять пенсів"), + (100.00, "сто фунтів, нуль пенсів"), + (101.11, "сто один фунт, одинадцять пенсів"), + (10222, "сто два фунти, двадцять два пенси"), +) + +TEST_CASES_TO_CURRENCY_GEL = ( + (0.00, "нуль ларі, нуль тетрі"), + (1.00, "один ларі, нуль тетрі"), + (2.00, "два ларі, нуль тетрі"), + (5.00, "п'ять ларі, нуль тетрі"), + (11.00, "одинадцять ларі, нуль тетрі"), + (16.01, "шістнадцять ларі, один тетрі"), + (21.00, "двадцять один ларі, нуль тетрі"), + (37.73, "тридцять сім ларі, сімдесят три тетрі"), + (81.25, "вісімдесят один ларі, двадцять п'ять тетрі"), + (100.00, "сто ларі, нуль тетрі"), + (101.11, "сто один ларі, одинадцять тетрі"), + (10222, "сто два ларі, двадцять два тетрі"), +) + +TEST_CASES_TO_CURRENCY_GHS = ( + (0.00, "нуль седі, нуль песев"), + (1.00, "один седі, нуль песев"), + (2.00, "два седі, нуль песев"), + (5.00, "п'ять седі, нуль песев"), + (11.00, "одинадцять седі, нуль песев"), + (16.01, "шістнадцять седі, одна песева"), + (21.00, "двадцять один седі, нуль песев"), + (37.73, "тридцять сім седі, сімдесят три песеви"), + (81.25, "вісімдесят один седі, двадцять п'ять песев"), + (100.00, "сто седі, нуль песев"), + (101.11, "сто один седі, одинадцять песев"), + (10222, "сто два седі, двадцять дві песеви"), +) + +TEST_CASES_TO_CURRENCY_GIP = ( + (0.00, "нуль фунтів, нуль пенсів"), + (1.00, "один фунт, нуль пенсів"), + (2.00, "два фунти, нуль пенсів"), + (5.00, "п'ять фунтів, нуль пенсів"), + (11.00, "одинадцять фунтів, нуль пенсів"), + (16.01, "шістнадцять фунтів, один пенс"), + (21.00, "двадцять один фунт, нуль пенсів"), + (37.73, "тридцять сім фунтів, сімдесят три пенси"), + (81.25, "вісімдесят один фунт, двадцять п'ять пенсів"), + (100.00, "сто фунтів, нуль пенсів"), + (101.11, "сто один фунт, одинадцять пенсів"), + (10222, "сто два фунти, двадцять два пенси"), +) + +TEST_CASES_TO_CURRENCY_GMD = ( + (0.00, "нуль даласі, нуль бутутів"), + (1.00, "один даласі, нуль бутутів"), + (2.00, "два даласі, нуль бутутів"), + (5.00, "п'ять даласі, нуль бутутів"), + (11.00, "одинадцять даласі, нуль бутутів"), + (16.01, "шістнадцять даласі, один бутут"), + (21.00, "двадцять один даласі, нуль бутутів"), + (37.73, "тридцять сім даласі, сімдесят три бутути"), + (81.25, "вісімдесят один даласі, двадцять п'ять бутутів"), + (100.00, "сто даласі, нуль бутутів"), + (101.11, "сто один даласі, одинадцять бутутів"), + (10222, "сто два даласі, двадцять два бутути"), +) + +TEST_CASES_TO_CURRENCY_GNF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_GTQ = ( + (0.00, "нуль кетсалів, нуль сентаво"), + (1.00, "один кетсаль, нуль сентаво"), + (2.00, "два кетсалі, нуль сентаво"), + (5.00, "п'ять кетсалів, нуль сентаво"), + (11.00, "одинадцять кетсалів, нуль сентаво"), + (16.01, "шістнадцять кетсалів, один сентаво"), + (21.00, "двадцять один кетсаль, нуль сентаво"), + (37.73, "тридцять сім кетсалів, сімдесят три сентаво"), + (81.25, "вісімдесят один кетсаль, двадцять п'ять сентаво"), + (100.00, "сто кетсалів, нуль сентаво"), + (101.11, "сто один кетсаль, одинадцять сентаво"), + (10222, "сто два кетсалі, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_GYD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_HKD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_HNL = ( + (0.00, "нуль лемпір, нуль сентаво"), + (1.00, "одна лемпіра, нуль сентаво"), + (2.00, "дві лемпіри, нуль сентаво"), + (5.00, "п'ять лемпір, нуль сентаво"), + (11.00, "одинадцять лемпір, нуль сентаво"), + (16.01, "шістнадцять лемпір, один сентаво"), + (21.00, "двадцять одна лемпіра, нуль сентаво"), + (37.73, "тридцять сім лемпір, сімдесят три сентаво"), + (81.25, "вісімдесят одна лемпіра, двадцять п'ять сентаво"), + (100.00, "сто лемпір, нуль сентаво"), + (101.11, "сто одна лемпіра, одинадцять сентаво"), + (10222, "сто дві лемпіри, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_HRK = ( + (0.00, "нуль кун, нуль ліп"), + (1.00, "одна куна, нуль ліп"), + (2.00, "дві куни, нуль ліп"), + (5.00, "п'ять кун, нуль ліп"), + (11.00, "одинадцять кун, нуль ліп"), + (16.01, "шістнадцять кун, одна ліпа"), + (21.00, "двадцять одна куна, нуль ліп"), + (37.73, "тридцять сім кун, сімдесят три ліпи"), + (81.25, "вісімдесят одна куна, двадцять п'ять ліп"), + (100.00, "сто кун, нуль ліп"), + (101.11, "сто одна куна, одинадцять ліп"), + (10222, "сто дві куни, двадцять дві ліпи"), +) + +TEST_CASES_TO_CURRENCY_HTG = ( + (0.00, "нуль гурдів, нуль сантимів"), + (1.00, "один гурд, нуль сантимів"), + (2.00, "два гурди, нуль сантимів"), + (5.00, "п'ять гурдів, нуль сантимів"), + (11.00, "одинадцять гурдів, нуль сантимів"), + (16.01, "шістнадцять гурдів, один сантим"), + (21.00, "двадцять один гурд, нуль сантимів"), + (37.73, "тридцять сім гурдів, сімдесят три сантими"), + (81.25, "вісімдесят один гурд, двадцять п'ять сантимів"), + (100.00, "сто гурдів, нуль сантимів"), + (101.11, "сто один гурд, одинадцять сантимів"), + (10222, "сто два гурди, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_HUF = ( + (0.00, "нуль форинтів, нуль філлерів"), + (1.00, "один форинт, нуль філлерів"), + (2.00, "два форинти, нуль філлерів"), + (5.00, "п'ять форинтів, нуль філлерів"), + (11.00, "одинадцять форинтів, нуль філлерів"), + (16.01, "шістнадцять форинтів, один філлер"), + (21.00, "двадцять один форинт, нуль філлерів"), + (37.73, "тридцять сім форинтів, сімдесят три філлери"), + (81.25, "вісімдесят один форинт, двадцять п'ять філлерів"), + (100.00, "сто форинтів, нуль філлерів"), + (101.11, "сто один форинт, одинадцять філлерів"), + (10222, "сто два форинти, двадцять два філлери"), +) + +TEST_CASES_TO_CURRENCY_IDR = ( + (0.00, "нуль рупій, нуль центів"), + (1.00, "одна рупія, нуль центів"), + (2.00, "дві рупії, нуль центів"), + (5.00, "п'ять рупій, нуль центів"), + (11.00, "одинадцять рупій, нуль центів"), + (16.01, "шістнадцять рупій, один цент"), + (21.00, "двадцять одна рупія, нуль центів"), + (37.73, "тридцять сім рупій, сімдесят три центи"), + (81.25, "вісімдесят одна рупія, двадцять п'ять центів"), + (100.00, "сто рупій, нуль центів"), + (101.11, "сто одна рупія, одинадцять центів"), + (10222, "сто дві рупії, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_ILS = ( + (0.00, "нуль шекелів, нуль агор"), + (1.00, "один шекель, нуль агор"), + (2.00, "два шекелі, нуль агор"), + (5.00, "п'ять шекелів, нуль агор"), + (11.00, "одинадцять шекелів, нуль агор"), + (16.01, "шістнадцять шекелів, одна агора"), + (21.00, "двадцять один шекель, нуль агор"), + (37.73, "тридцять сім шекелів, сімдесят три агори"), + (81.25, "вісімдесят один шекель, двадцять п'ять агор"), + (100.00, "сто шекелів, нуль агор"), + (101.11, "сто один шекель, одинадцять агор"), + (10222, "сто два шекелі, двадцять дві агори"), +) + +TEST_CASES_TO_CURRENCY_INR = ( + (0.00, "нуль рупій, нуль пайс"), + (1.00, "одна рупія, нуль пайс"), + (2.00, "дві рупії, нуль пайс"), + (5.00, "п'ять рупій, нуль пайс"), + (11.00, "одинадцять рупій, нуль пайс"), + (16.01, "шістнадцять рупій, одна пайса"), + (21.00, "двадцять одна рупія, нуль пайс"), + (37.73, "тридцять сім рупій, сімдесят три пайси"), + (81.25, "вісімдесят одна рупія, двадцять п'ять пайс"), + (100.00, "сто рупій, нуль пайс"), + (101.11, "сто одна рупія, одинадцять пайс"), + (10222, "сто дві рупії, двадцять дві пайси"), +) + +TEST_CASES_TO_CURRENCY_IQD = ( + (0.00, "нуль динарів, нуль філсів"), + (1.00, "один динар, нуль філсів"), + (2.00, "два динари, нуль філсів"), + (5.00, "п'ять динарів, нуль філсів"), + (11.00, "одинадцять динарів, нуль філсів"), + (16.01, "шістнадцять динарів, один філс"), + (21.00, "двадцять один динар, нуль філсів"), + (37.73, "тридцять сім динарів, сімдесят три філси"), + (81.25, "вісімдесят один динар, двадцять п'ять філсів"), + (100.00, "сто динарів, нуль філсів"), + (101.11, "сто один динар, одинадцять філсів"), + (10222, "сто два динари, двадцять два філси"), +) + +TEST_CASES_TO_CURRENCY_IRR = ( + (0.00, "нуль ріалів, нуль динарів"), + (1.00, "один ріал, нуль динарів"), + (2.00, "два ріали, нуль динарів"), + (5.00, "п'ять ріалів, нуль динарів"), + (11.00, "одинадцять ріалів, нуль динарів"), + (16.01, "шістнадцять ріалів, один динар"), + (21.00, "двадцять один ріал, нуль динарів"), + (37.73, "тридцять сім ріалів, сімдесят три динари"), + (81.25, "вісімдесят один ріал, двадцять п'ять динарів"), + (100.00, "сто ріалів, нуль динарів"), + (101.11, "сто один ріал, одинадцять динарів"), + (10222, "сто два ріали, двадцять два динари"), +) + +TEST_CASES_TO_CURRENCY_ISK = ( + (0.00, "нуль крон, нуль ейре"), + (1.00, "одна крона, нуль ейре"), + (2.00, "дві крони, нуль ейре"), + (5.00, "п'ять крон, нуль ейре"), + (11.00, "одинадцять крон, нуль ейре"), + (16.01, "шістнадцять крон, один ейре"), + (21.00, "двадцять одна крона, нуль ейре"), + (37.73, "тридцять сім крон, сімдесят три ейре"), + (81.25, "вісімдесят одна крона, двадцять п'ять ейре"), + (100.00, "сто крон, нуль ейре"), + (101.11, "сто одна крона, одинадцять ейре"), + (10222, "сто дві крони, двадцять два ейре"), +) + +TEST_CASES_TO_CURRENCY_JMD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_JOD = ( + (0.00, "нуль динарів, нуль філсів"), + (1.00, "один динар, нуль філсів"), + (2.00, "два динари, нуль філсів"), + (5.00, "п'ять динарів, нуль філсів"), + (11.00, "одинадцять динарів, нуль філсів"), + (16.01, "шістнадцять динарів, один філс"), + (21.00, "двадцять один динар, нуль філсів"), + (37.73, "тридцять сім динарів, сімдесят три філси"), + (81.25, "вісімдесят один динар, двадцять п'ять філсів"), + (100.00, "сто динарів, нуль філсів"), + (101.11, "сто один динар, одинадцять філсів"), + (10222, "сто два динари, двадцять два філси"), +) + +TEST_CASES_TO_CURRENCY_JPY = ( + (0.00, "нуль єн, нуль сен"), + (1.00, "одна єна, нуль сен"), + (2.00, "дві єни, нуль сен"), + (5.00, "п'ять єн, нуль сен"), + (11.00, "одинадцять єн, нуль сен"), + (16.01, "шістнадцять єн, один сен"), + (21.00, "двадцять одна єна, нуль сен"), + (37.73, "тридцять сім єн, сімдесят три сен"), + (81.25, "вісімдесят одна єна, двадцять п'ять сен"), + (100.00, "сто єн, нуль сен"), + (101.11, "сто одна єна, одинадцять сен"), + (10222, "сто дві єни, двадцять два сен"), +) + +TEST_CASES_TO_CURRENCY_KES = ( + (0.00, "нуль шилінгів, нуль центів"), + (1.00, "один шилінг, нуль центів"), + (2.00, "два шилінги, нуль центів"), + (5.00, "п'ять шилінгів, нуль центів"), + (11.00, "одинадцять шилінгів, нуль центів"), + (16.01, "шістнадцять шилінгів, один цент"), + (21.00, "двадцять один шилінг, нуль центів"), + (37.73, "тридцять сім шилінгів, сімдесят три центи"), + (81.25, "вісімдесят один шилінг, двадцять п'ять центів"), + (100.00, "сто шилінгів, нуль центів"), + (101.11, "сто один шилінг, одинадцять центів"), + (10222, "сто два шилінги, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_KGS = ( + (0.00, "нуль сомів, нуль тиїнів"), + (1.00, "один сом, нуль тиїнів"), + (2.00, "два соми, нуль тиїнів"), + (5.00, "п'ять сомів, нуль тиїнів"), + (11.00, "одинадцять сомів, нуль тиїнів"), + (16.01, "шістнадцять сомів, один тиїн"), + (21.00, "двадцять один сом, нуль тиїнів"), + (37.73, "тридцять сім сомів, сімдесят три тиїни"), + (81.25, "вісімдесят один сом, двадцять п'ять тиїнів"), + (100.00, "сто сомів, нуль тиїнів"), + (101.11, "сто один сом, одинадцять тиїнів"), + (10222, "сто два соми, двадцять два тиїни"), +) + +TEST_CASES_TO_CURRENCY_KHR = ( + (0.00, "нуль рієлів, нуль су"), + (1.00, "один рієль, нуль су"), + (2.00, "два рієлі, нуль су"), + (5.00, "п'ять рієлів, нуль су"), + (11.00, "одинадцять рієлів, нуль су"), + (16.01, "шістнадцять рієлів, один су"), + (21.00, "двадцять один рієль, нуль су"), + (37.73, "тридцять сім рієлів, сімдесят три су"), + (81.25, "вісімдесят один рієль, двадцять п'ять су"), + (100.00, "сто рієлів, нуль су"), + (101.11, "сто один рієль, одинадцять су"), + (10222, "сто два рієлі, двадцять два су"), +) + +TEST_CASES_TO_CURRENCY_KMF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_KPW = ( + (0.00, "нуль вон, нуль чонів"), + (1.00, "одна вона, нуль чонів"), + (2.00, "дві вони, нуль чонів"), + (5.00, "п'ять вон, нуль чонів"), + (11.00, "одинадцять вон, нуль чонів"), + (16.01, "шістнадцять вон, один чон"), + (21.00, "двадцять одна вона, нуль чонів"), + (37.73, "тридцять сім вон, сімдесят три чони"), + (81.25, "вісімдесят одна вона, двадцять п'ять чонів"), + (100.00, "сто вон, нуль чонів"), + (101.11, "сто одна вона, одинадцять чонів"), + (10222, "сто дві вони, двадцять два чони"), +) + +TEST_CASES_TO_CURRENCY_KRW = ( + (0.00, "нуль вон, нуль джеонів"), + (1.00, "одна вона, нуль джеонів"), + (2.00, "дві вони, нуль джеонів"), + (5.00, "п'ять вон, нуль джеонів"), + (11.00, "одинадцять вон, нуль джеонів"), + (16.01, "шістнадцять вон, один джеон"), + (21.00, "двадцять одна вона, нуль джеонів"), + (37.73, "тридцять сім вон, сімдесят три джеони"), + (81.25, "вісімдесят одна вона, двадцять п'ять джеонів"), + (100.00, "сто вон, нуль джеонів"), + (101.11, "сто одна вона, одинадцять джеонів"), + (10222, "сто дві вони, двадцять два джеони"), +) + +TEST_CASES_TO_CURRENCY_KWD = ( + (0.00, "нуль динарів, нуль філсів"), + (1.00, "один динар, нуль філсів"), + (2.00, "два динари, нуль філсів"), + (5.00, "п'ять динарів, нуль філсів"), + (11.00, "одинадцять динарів, нуль філсів"), + (16.01, "шістнадцять динарів, один філс"), + (21.00, "двадцять один динар, нуль філсів"), + (37.73, "тридцять сім динарів, сімдесят три філси"), + (81.25, "вісімдесят один динар, двадцять п'ять філсів"), + (100.00, "сто динарів, нуль філсів"), + (101.11, "сто один динар, одинадцять філсів"), + (10222, "сто два динари, двадцять два філси"), +) + +TEST_CASES_TO_CURRENCY_KYD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_KZT = ( + (0.00, "нуль теньге, нуль тиїнів"), + (1.00, "один теньге, нуль тиїнів"), + (2.00, "два теньге, нуль тиїнів"), + (5.00, "п'ять теньге, нуль тиїнів"), + (11.00, "одинадцять теньге, нуль тиїнів"), + (16.01, "шістнадцять теньге, один тиїн"), + (21.00, "двадцять один теньге, нуль тиїнів"), + (37.73, "тридцять сім теньге, сімдесят три тиїни"), + (81.25, "вісімдесят один теньге, двадцять п'ять тиїнів"), + (100.00, "сто теньге, нуль тиїнів"), + (101.11, "сто один теньге, одинадцять тиїнів"), + (10222, "сто два теньге, двадцять два тиїни"), +) + +TEST_CASES_TO_CURRENCY_LAK = ( + (0.00, "нуль кіпів, нуль атів"), + (1.00, "один кіп, нуль атів"), + (2.00, "два кіпи, нуль атів"), + (5.00, "п'ять кіпів, нуль атів"), + (11.00, "одинадцять кіпів, нуль атів"), + (16.01, "шістнадцять кіпів, один ат"), + (21.00, "двадцять один кіп, нуль атів"), + (37.73, "тридцять сім кіпів, сімдесят три ати"), + (81.25, "вісімдесят один кіп, двадцять п'ять атів"), + (100.00, "сто кіпів, нуль атів"), + (101.11, "сто один кіп, одинадцять атів"), + (10222, "сто два кіпи, двадцять два ати"), +) + +TEST_CASES_TO_CURRENCY_LBP = ( + (0.00, "нуль фунтів, нуль піастрів"), + (1.00, "один фунт, нуль піастрів"), + (2.00, "два фунти, нуль піастрів"), + (5.00, "п'ять фунтів, нуль піастрів"), + (11.00, "одинадцять фунтів, нуль піастрів"), + (16.01, "шістнадцять фунтів, один піастр"), + (21.00, "двадцять один фунт, нуль піастрів"), + (37.73, "тридцять сім фунтів, сімдесят три піастри"), + (81.25, "вісімдесят один фунт, двадцять п'ять піастрів"), + (100.00, "сто фунтів, нуль піастрів"), + (101.11, "сто один фунт, одинадцять піастрів"), + (10222, "сто два фунти, двадцять два піастри"), +) + +TEST_CASES_TO_CURRENCY_LKR = ( + (0.00, "нуль рупій, нуль центів"), + (1.00, "одна рупія, нуль центів"), + (2.00, "дві рупії, нуль центів"), + (5.00, "п'ять рупій, нуль центів"), + (11.00, "одинадцять рупій, нуль центів"), + (16.01, "шістнадцять рупій, один цент"), + (21.00, "двадцять одна рупія, нуль центів"), + (37.73, "тридцять сім рупій, сімдесят три центи"), + (81.25, "вісімдесят одна рупія, двадцять п'ять центів"), + (100.00, "сто рупій, нуль центів"), + (101.11, "сто одна рупія, одинадцять центів"), + (10222, "сто дві рупії, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_LRD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_LSL = ( + (0.00, "нуль малоті, нуль лісенте"), + (1.00, "один лоті, нуль лісенте"), + (2.00, "два малоті, нуль лісенте"), + (5.00, "п'ять малоті, нуль лісенте"), + (11.00, "одинадцять малоті, нуль лісенте"), + (16.01, "шістнадцять малоті, один сенте"), + (21.00, "двадцять один лоті, нуль лісенте"), + (37.73, "тридцять сім малоті, сімдесят три лісенте"), + (81.25, "вісімдесят один лоті, двадцять п'ять лісенте"), + (100.00, "сто малоті, нуль лісенте"), + (101.11, "сто один лоті, одинадцять лісенте"), + (10222, "сто два малоті, двадцять два лісенте"), +) + +TEST_CASES_TO_CURRENCY_LYD = ( + (0.00, "нуль динарів, нуль дирхамів"), + (1.00, "один динар, нуль дирхамів"), + (2.00, "два динари, нуль дирхамів"), + (5.00, "п'ять динарів, нуль дирхамів"), + (11.00, "одинадцять динарів, нуль дирхамів"), + (16.01, "шістнадцять динарів, один дирхам"), + (21.00, "двадцять один динар, нуль дирхамів"), + (37.73, "тридцять сім динарів, сімдесят три дирхами"), + (81.25, "вісімдесят один динар, двадцять п'ять дирхамів"), + (100.00, "сто динарів, нуль дирхамів"), + (101.11, "сто один динар, одинадцять дирхамів"), + (10222, "сто два динари, двадцять два дирхами"), +) + +TEST_CASES_TO_CURRENCY_MAD = ( + (0.00, "нуль дирхамів, нуль сантимів"), + (1.00, "один дирхам, нуль сантимів"), + (2.00, "два дирхами, нуль сантимів"), + (5.00, "п'ять дирхамів, нуль сантимів"), + (11.00, "одинадцять дирхамів, нуль сантимів"), + (16.01, "шістнадцять дирхамів, один сантим"), + (21.00, "двадцять один дирхам, нуль сантимів"), + (37.73, "тридцять сім дирхамів, сімдесят три сантими"), + (81.25, "вісімдесят один дирхам, двадцять п'ять сантимів"), + (100.00, "сто дирхамів, нуль сантимів"), + (101.11, "сто один дирхам, одинадцять сантимів"), + (10222, "сто два дирхами, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_MDL = ( + (0.00, "нуль леї, нуль бані"), + (1.00, "один лей, нуль бані"), + (2.00, "два леї, нуль бані"), + (5.00, "п'ять леї, нуль бані"), + (11.00, "одинадцять леї, нуль бані"), + (16.01, "шістнадцять леї, один бан"), + (21.00, "двадцять один лей, нуль бані"), + (37.73, "тридцять сім леї, сімдесят три бані"), + (81.25, "вісімдесят один лей, двадцять п'ять бані"), + (100.00, "сто леї, нуль бані"), + (101.11, "сто один лей, одинадцять бані"), + (10222, "сто два леї, двадцять два бані"), +) + +TEST_CASES_TO_CURRENCY_MGA = ( + (0.00, "нуль аріарі, нуль іраймбіланья"), + (1.00, "один аріарі, нуль іраймбіланья"), + (2.00, "два аріарі, нуль іраймбіланья"), + (5.00, "п'ять аріарі, нуль іраймбіланья"), + (11.00, "одинадцять аріарі, нуль іраймбіланья"), + (16.01, "шістнадцять аріарі, один іраймбіланья"), + (21.00, "двадцять один аріарі, нуль іраймбіланья"), + (37.73, "тридцять сім аріарі, сімдесят три іраймбіланья"), + (81.25, "вісімдесят один аріарі, двадцять п'ять іраймбіланья"), + (100.00, "сто аріарі, нуль іраймбіланья"), + (101.11, "сто один аріарі, одинадцять іраймбіланья"), + (10222, "сто два аріарі, двадцять два іраймбіланья"), +) + +TEST_CASES_TO_CURRENCY_MKD = ( + (0.00, "нуль денарів, нуль дені"), + (1.00, "один денар, нуль дені"), + (2.00, "два денари, нуль дені"), + (5.00, "п'ять денарів, нуль дені"), + (11.00, "одинадцять денарів, нуль дені"), + (16.01, "шістнадцять денарів, один дені"), + (21.00, "двадцять один денар, нуль дені"), + (37.73, "тридцять сім денарів, сімдесят три дені"), + (81.25, "вісімдесят один денар, двадцять п'ять дені"), + (100.00, "сто денарів, нуль дені"), + (101.11, "сто один денар, одинадцять дені"), + (10222, "сто два денари, двадцять два дені"), +) + +TEST_CASES_TO_CURRENCY_MMK = ( + (0.00, "нуль к'ят, нуль п'я"), + (1.00, "один к'ят, нуль п'я"), + (2.00, "два к'ят, нуль п'я"), + (5.00, "п'ять к'ят, нуль п'я"), + (11.00, "одинадцять к'ят, нуль п'я"), + (16.01, "шістнадцять к'ят, один п'я"), + (21.00, "двадцять один к'ят, нуль п'я"), + (37.73, "тридцять сім к'ят, сімдесят три п'я"), + (81.25, "вісімдесят один к'ят, двадцять п'ять п'я"), + (100.00, "сто к'ят, нуль п'я"), + (101.11, "сто один к'ят, одинадцять п'я"), + (10222, "сто два к'ят, двадцять два п'я"), +) + +TEST_CASES_TO_CURRENCY_MNT = ( + (0.00, "нуль тугриків, нуль мунгу"), + (1.00, "один тугрик, нуль мунгу"), + (2.00, "два тугрики, нуль мунгу"), + (5.00, "п'ять тугриків, нуль мунгу"), + (11.00, "одинадцять тугриків, нуль мунгу"), + (16.01, "шістнадцять тугриків, один мунгу"), + (21.00, "двадцять один тугрик, нуль мунгу"), + (37.73, "тридцять сім тугриків, сімдесят три мунгу"), + (81.25, "вісімдесят один тугрик, двадцять п'ять мунгу"), + (100.00, "сто тугриків, нуль мунгу"), + (101.11, "сто один тугрик, одинадцять мунгу"), + (10222, "сто два тугрики, двадцять два мунгу"), +) + +TEST_CASES_TO_CURRENCY_MOP = ( + (0.00, "нуль патак, нуль аво"), + (1.00, "одна патака, нуль аво"), + (2.00, "дві патакі, нуль аво"), + (5.00, "п'ять патак, нуль аво"), + (11.00, "одинадцять патак, нуль аво"), + (16.01, "шістнадцять патак, один аво"), + (21.00, "двадцять одна патака, нуль аво"), + (37.73, "тридцять сім патак, сімдесят три аво"), + (81.25, "вісімдесят одна патака, двадцять п'ять аво"), + (100.00, "сто патак, нуль аво"), + (101.11, "сто одна патака, одинадцять аво"), + (10222, "сто дві патакі, двадцять два аво"), +) + +TEST_CASES_TO_CURRENCY_MRU = ( + (0.00, "нуль угій, нуль хумс"), + (1.00, "одна угія, нуль хумс"), + (2.00, "дві угії, нуль хумс"), + (5.00, "п'ять угій, нуль хумс"), + (11.00, "одинадцять угій, нуль хумс"), + (16.01, "шістнадцять угій, один хумс"), + (21.00, "двадцять одна угія, нуль хумс"), + (37.73, "тридцять сім угій, сімдесят три хумс"), + (81.25, "вісімдесят одна угія, двадцять п'ять хумс"), + (100.00, "сто угій, нуль хумс"), + (101.11, "сто одна угія, одинадцять хумс"), + (10222, "сто дві угії, двадцять два хумс"), +) + +TEST_CASES_TO_CURRENCY_MUR = ( + (0.00, "нуль рупій, нуль центів"), + (1.00, "одна рупія, нуль центів"), + (2.00, "дві рупії, нуль центів"), + (5.00, "п'ять рупій, нуль центів"), + (11.00, "одинадцять рупій, нуль центів"), + (16.01, "шістнадцять рупій, один цент"), + (21.00, "двадцять одна рупія, нуль центів"), + (37.73, "тридцять сім рупій, сімдесят три центи"), + (81.25, "вісімдесят одна рупія, двадцять п'ять центів"), + (100.00, "сто рупій, нуль центів"), + (101.11, "сто одна рупія, одинадцять центів"), + (10222, "сто дві рупії, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_MVR = ( + (0.00, "нуль руфій, нуль ларі"), + (1.00, "одна руфія, нуль ларі"), + (2.00, "дві руфії, нуль ларі"), + (5.00, "п'ять руфій, нуль ларі"), + (11.00, "одинадцять руфій, нуль ларі"), + (16.01, "шістнадцять руфій, один ларі"), + (21.00, "двадцять одна руфія, нуль ларі"), + (37.73, "тридцять сім руфій, сімдесят три ларі"), + (81.25, "вісімдесят одна руфія, двадцять п'ять ларі"), + (100.00, "сто руфій, нуль ларі"), + (101.11, "сто одна руфія, одинадцять ларі"), + (10222, "сто дві руфії, двадцять два ларі"), +) + +TEST_CASES_TO_CURRENCY_MWK = ( + (0.00, "нуль квач, нуль тамбала"), + (1.00, "одна квача, нуль тамбала"), + (2.00, "дві квачі, нуль тамбала"), + (5.00, "п'ять квач, нуль тамбала"), + (11.00, "одинадцять квач, нуль тамбала"), + (16.01, "шістнадцять квач, один тамбала"), + (21.00, "двадцять одна квача, нуль тамбала"), + (37.73, "тридцять сім квач, сімдесят три тамбала"), + (81.25, "вісімдесят одна квача, двадцять п'ять тамбала"), + (100.00, "сто квач, нуль тамбала"), + (101.11, "сто одна квача, одинадцять тамбала"), + (10222, "сто дві квачі, двадцять два тамбала"), +) + +TEST_CASES_TO_CURRENCY_MXN = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_MYR = ( + (0.00, "нуль рингітів, нуль центів"), + (1.00, "один рингіт, нуль центів"), + (2.00, "два рингіти, нуль центів"), + (5.00, "п'ять рингітів, нуль центів"), + (11.00, "одинадцять рингітів, нуль центів"), + (16.01, "шістнадцять рингітів, один цент"), + (21.00, "двадцять один рингіт, нуль центів"), + (37.73, "тридцять сім рингітів, сімдесят три центи"), + (81.25, "вісімдесят один рингіт, двадцять п'ять центів"), + (100.00, "сто рингітів, нуль центів"), + (101.11, "сто один рингіт, одинадцять центів"), + (10222, "сто два рингіти, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_MZN = ( + (0.00, "нуль метікалів, нуль сентаво"), + (1.00, "один метікал, нуль сентаво"), + (2.00, "два метікали, нуль сентаво"), + (5.00, "п'ять метікалів, нуль сентаво"), + (11.00, "одинадцять метікалів, нуль сентаво"), + (16.01, "шістнадцять метікалів, один сентаво"), + (21.00, "двадцять один метікал, нуль сентаво"), + (37.73, "тридцять сім метікалів, сімдесят три сентаво"), + (81.25, "вісімдесят один метікал, двадцять п'ять сентаво"), + (100.00, "сто метікалів, нуль сентаво"), + (101.11, "сто один метікал, одинадцять сентаво"), + (10222, "сто два метікали, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_NAD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_NGN = ( + (0.00, "нуль найр, нуль кобо"), + (1.00, "одна найра, нуль кобо"), + (2.00, "дві найри, нуль кобо"), + (5.00, "п'ять найр, нуль кобо"), + (11.00, "одинадцять найр, нуль кобо"), + (16.01, "шістнадцять найр, один кобо"), + (21.00, "двадцять одна найра, нуль кобо"), + (37.73, "тридцять сім найр, сімдесят три кобо"), + (81.25, "вісімдесят одна найра, двадцять п'ять кобо"), + (100.00, "сто найр, нуль кобо"), + (101.11, "сто одна найра, одинадцять кобо"), + (10222, "сто дві найри, двадцять два кобо"), +) + +TEST_CASES_TO_CURRENCY_NIO = ( + (0.00, "нуль кордоб, нуль сентаво"), + (1.00, "одна кордоба, нуль сентаво"), + (2.00, "дві кордоби, нуль сентаво"), + (5.00, "п'ять кордоб, нуль сентаво"), + (11.00, "одинадцять кордоб, нуль сентаво"), + (16.01, "шістнадцять кордоб, один сентаво"), + (21.00, "двадцять одна кордоба, нуль сентаво"), + (37.73, "тридцять сім кордоб, сімдесят три сентаво"), + (81.25, "вісімдесят одна кордоба, двадцять п'ять сентаво"), + (100.00, "сто кордоб, нуль сентаво"), + (101.11, "сто одна кордоба, одинадцять сентаво"), + (10222, "сто дві кордоби, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_NOK = ( + (0.00, "нуль крон, нуль ере"), + (1.00, "одна крона, нуль ере"), + (2.00, "дві крони, нуль ере"), + (5.00, "п'ять крон, нуль ере"), + (11.00, "одинадцять крон, нуль ере"), + (16.01, "шістнадцять крон, один ере"), + (21.00, "двадцять одна крона, нуль ере"), + (37.73, "тридцять сім крон, сімдесят три ере"), + (81.25, "вісімдесят одна крона, двадцять п'ять ере"), + (100.00, "сто крон, нуль ере"), + (101.11, "сто одна крона, одинадцять ере"), + (10222, "сто дві крони, двадцять два ере"), +) + +TEST_CASES_TO_CURRENCY_NPR = ( + (0.00, "нуль рупій, нуль пайс"), + (1.00, "одна рупія, нуль пайс"), + (2.00, "дві рупії, нуль пайс"), + (5.00, "п'ять рупій, нуль пайс"), + (11.00, "одинадцять рупій, нуль пайс"), + (16.01, "шістнадцять рупій, одна пайса"), + (21.00, "двадцять одна рупія, нуль пайс"), + (37.73, "тридцять сім рупій, сімдесят три пайси"), + (81.25, "вісімдесят одна рупія, двадцять п'ять пайс"), + (100.00, "сто рупій, нуль пайс"), + (101.11, "сто одна рупія, одинадцять пайс"), + (10222, "сто дві рупії, двадцять дві пайси"), +) + +TEST_CASES_TO_CURRENCY_NZD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_OMR = ( + (0.00, "нуль ріалів, нуль байз"), + (1.00, "один ріал, нуль байз"), + (2.00, "два ріали, нуль байз"), + (5.00, "п'ять ріалів, нуль байз"), + (11.00, "одинадцять ріалів, нуль байз"), + (16.01, "шістнадцять ріалів, одна байза"), + (21.00, "двадцять один ріал, нуль байз"), + (37.73, "тридцять сім ріалів, сімдесят три байзи"), + (81.25, "вісімдесят один ріал, двадцять п'ять байз"), + (100.00, "сто ріалів, нуль байз"), + (101.11, "сто один ріал, одинадцять байз"), + (10222, "сто два ріали, двадцять дві байзи"), +) + +TEST_CASES_TO_CURRENCY_PAB = ( + (0.00, "нуль бальбоа, нуль сентесімо"), + (1.00, "один бальбоа, нуль сентесімо"), + (2.00, "два бальбоа, нуль сентесімо"), + (5.00, "п'ять бальбоа, нуль сентесімо"), + (11.00, "одинадцять бальбоа, нуль сентесімо"), + (16.01, "шістнадцять бальбоа, один сентесімо"), + (21.00, "двадцять один бальбоа, нуль сентесімо"), + (37.73, "тридцять сім бальбоа, сімдесят три сентесімо"), + (81.25, "вісімдесят один бальбоа, двадцять п'ять сентесімо"), + (100.00, "сто бальбоа, нуль сентесімо"), + (101.11, "сто один бальбоа, одинадцять сентесімо"), + (10222, "сто два бальбоа, двадцять два сентесімо"), +) + +TEST_CASES_TO_CURRENCY_PEN = ( + (0.00, "нуль соль, нуль сентімо"), + (1.00, "один соль, нуль сентімо"), + (2.00, "два соль, нуль сентімо"), + (5.00, "п'ять соль, нуль сентімо"), + (11.00, "одинадцять соль, нуль сентімо"), + (16.01, "шістнадцять соль, один сентімо"), + (21.00, "двадцять один соль, нуль сентімо"), + (37.73, "тридцять сім соль, сімдесят три сентімо"), + (81.25, "вісімдесят один соль, двадцять п'ять сентімо"), + (100.00, "сто соль, нуль сентімо"), + (101.11, "сто один соль, одинадцять сентімо"), + (10222, "сто два соль, двадцять два сентімо"), +) + +TEST_CASES_TO_CURRENCY_PGK = ( + (0.00, "нуль кіна, нуль тойя"), + (1.00, "один кіна, нуль тойя"), + (2.00, "два кіна, нуль тойя"), + (5.00, "п'ять кіна, нуль тойя"), + (11.00, "одинадцять кіна, нуль тойя"), + (16.01, "шістнадцять кіна, один тойя"), + (21.00, "двадцять один кіна, нуль тойя"), + (37.73, "тридцять сім кіна, сімдесят три тойя"), + (81.25, "вісімдесят один кіна, двадцять п'ять тойя"), + (100.00, "сто кіна, нуль тойя"), + (101.11, "сто один кіна, одинадцять тойя"), + (10222, "сто два кіна, двадцять два тойя"), +) + +TEST_CASES_TO_CURRENCY_PHP = ( + (0.00, "нуль песо, нуль сентаво"), + (1.00, "один песо, нуль сентаво"), + (2.00, "два песо, нуль сентаво"), + (5.00, "п'ять песо, нуль сентаво"), + (11.00, "одинадцять песо, нуль сентаво"), + (16.01, "шістнадцять песо, один сентаво"), + (21.00, "двадцять один песо, нуль сентаво"), + (37.73, "тридцять сім песо, сімдесят три сентаво"), + (81.25, "вісімдесят один песо, двадцять п'ять сентаво"), + (100.00, "сто песо, нуль сентаво"), + (101.11, "сто один песо, одинадцять сентаво"), + (10222, "сто два песо, двадцять два сентаво"), +) + +TEST_CASES_TO_CURRENCY_PKR = ( + (0.00, "нуль рупій, нуль пайс"), + (1.00, "одна рупія, нуль пайс"), + (2.00, "дві рупії, нуль пайс"), + (5.00, "п'ять рупій, нуль пайс"), + (11.00, "одинадцять рупій, нуль пайс"), + (16.01, "шістнадцять рупій, одна пайса"), + (21.00, "двадцять одна рупія, нуль пайс"), + (37.73, "тридцять сім рупій, сімдесят три пайси"), + (81.25, "вісімдесят одна рупія, двадцять п'ять пайс"), + (100.00, "сто рупій, нуль пайс"), + (101.11, "сто одна рупія, одинадцять пайс"), + (10222, "сто дві рупії, двадцять дві пайси"), +) + +TEST_CASES_TO_CURRENCY_PLN = ( + (0.00, "нуль злотих, нуль грошів"), + (1.00, "один злотий, нуль грошів"), + (2.00, "два злоті, нуль грошів"), + (5.00, "п'ять злотих, нуль грошів"), + (11.00, "одинадцять злотих, нуль грошів"), + (16.01, "шістнадцять злотих, один грош"), + (21.00, "двадцять один злотий, нуль грошів"), + (37.73, "тридцять сім злотих, сімдесят три гроші"), + (81.25, "вісімдесят один злотий, двадцять п'ять грошів"), + (100.00, "сто злотих, нуль грошів"), + (101.11, "сто один злотий, одинадцять грошів"), + (10222, "сто два злоті, двадцять два гроші"), +) + +TEST_CASES_TO_CURRENCY_PYG = ( + (0.00, "нуль гуарані, нуль сентімо"), + (1.00, "один гуарані, нуль сентімо"), + (2.00, "два гуарані, нуль сентімо"), + (5.00, "п'ять гуарані, нуль сентімо"), + (11.00, "одинадцять гуарані, нуль сентімо"), + (16.01, "шістнадцять гуарані, один сентімо"), + (21.00, "двадцять один гуарані, нуль сентімо"), + (37.73, "тридцять сім гуарані, сімдесят три сентімо"), + (81.25, "вісімдесят один гуарані, двадцять п'ять сентімо"), + (100.00, "сто гуарані, нуль сентімо"), + (101.11, "сто один гуарані, одинадцять сентімо"), + (10222, "сто два гуарані, двадцять два сентімо"), +) + +TEST_CASES_TO_CURRENCY_QAR = ( + (0.00, "нуль ріалів, нуль дирхамів"), + (1.00, "один ріал, нуль дирхамів"), + (2.00, "два ріали, нуль дирхамів"), + (5.00, "п'ять ріалів, нуль дирхамів"), + (11.00, "одинадцять ріалів, нуль дирхамів"), + (16.01, "шістнадцять ріалів, один дирхам"), + (21.00, "двадцять один ріал, нуль дирхамів"), + (37.73, "тридцять сім ріалів, сімдесят три дирхами"), + (81.25, "вісімдесят один ріал, двадцять п'ять дирхамів"), + (100.00, "сто ріалів, нуль дирхамів"), + (101.11, "сто один ріал, одинадцять дирхамів"), + (10222, "сто два ріали, двадцять два дирхами"), +) + +TEST_CASES_TO_CURRENCY_RON = ( + (0.00, "нуль леї, нуль бані"), + (1.00, "один лей, нуль бані"), + (2.00, "два леї, нуль бані"), + (5.00, "п'ять леї, нуль бані"), + (11.00, "одинадцять леї, нуль бані"), + (16.01, "шістнадцять леї, один бан"), + (21.00, "двадцять один лей, нуль бані"), + (37.73, "тридцять сім леї, сімдесят три бані"), + (81.25, "вісімдесят один лей, двадцять п'ять бані"), + (100.00, "сто леї, нуль бані"), + (101.11, "сто один лей, одинадцять бані"), + (10222, "сто два леї, двадцять два бані"), +) + +TEST_CASES_TO_CURRENCY_RSD = ( + (0.00, "нуль динарів, нуль пар"), + (1.00, "один динар, нуль пар"), + (2.00, "два динари, нуль пар"), + (5.00, "п'ять динарів, нуль пар"), + (11.00, "одинадцять динарів, нуль пар"), + (16.01, "шістнадцять динарів, одна пара"), + (21.00, "двадцять один динар, нуль пар"), + (37.73, "тридцять сім динарів, сімдесят три пари"), + (81.25, "вісімдесят один динар, двадцять п'ять пар"), + (100.00, "сто динарів, нуль пар"), + (101.11, "сто один динар, одинадцять пар"), + (10222, "сто два динари, двадцять дві пари"), +) + +TEST_CASES_TO_CURRENCY_RUB = ( + (0.00, "нуль рублів, нуль копійок"), + (1.00, "один рубль, нуль копійок"), + (2.00, "два рублі, нуль копійок"), + (5.00, "п'ять рублів, нуль копійок"), + (11.00, "одинадцять рублів, нуль копійок"), + (16.01, "шістнадцять рублів, одна копійка"), + (21.00, "двадцять один рубль, нуль копійок"), + (37.73, "тридцять сім рублів, сімдесят три копійки"), + (81.25, "вісімдесят один рубль, двадцять п'ять копійок"), + (100.00, "сто рублів, нуль копійок"), + (101.11, "сто один рубль, одинадцять копійок"), +) + +TEST_CASES_TO_CURRENCY_RWF = ( + (0.00, "нуль франків, нуль сантимів"), + (1.00, "один франк, нуль сантимів"), + (2.00, "два франки, нуль сантимів"), + (5.00, "п'ять франків, нуль сантимів"), + (11.00, "одинадцять франків, нуль сантимів"), + (16.01, "шістнадцять франків, один сантим"), + (21.00, "двадцять один франк, нуль сантимів"), + (37.73, "тридцять сім франків, сімдесят три сантими"), + (81.25, "вісімдесят один франк, двадцять п'ять сантимів"), + (100.00, "сто франків, нуль сантимів"), + (101.11, "сто один франк, одинадцять сантимів"), + (10222, "сто два франки, двадцять два сантими"), +) + +TEST_CASES_TO_CURRENCY_SAR = ( + (0.00, "нуль ріалів, нуль халалів"), + (1.00, "один ріал, нуль халалів"), + (2.00, "два ріали, нуль халалів"), + (5.00, "п'ять ріалів, нуль халалів"), + (11.00, "одинадцять ріалів, нуль халалів"), + (16.01, "шістнадцять ріалів, один халал"), + (21.00, "двадцять один ріал, нуль халалів"), + (37.73, "тридцять сім ріалів, сімдесят три халали"), + (81.25, "вісімдесят один ріал, двадцять п'ять халалів"), + (100.00, "сто ріалів, нуль халалів"), + (101.11, "сто один ріал, одинадцять халалів"), + (10222, "сто два ріали, двадцять два халали"), +) + +TEST_CASES_TO_CURRENCY_SBD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_SCR = ( + (0.00, "нуль рупій, нуль центів"), + (1.00, "одна рупія, нуль центів"), + (2.00, "дві рупії, нуль центів"), + (5.00, "п'ять рупій, нуль центів"), + (11.00, "одинадцять рупій, нуль центів"), + (16.01, "шістнадцять рупій, один цент"), + (21.00, "двадцять одна рупія, нуль центів"), + (37.73, "тридцять сім рупій, сімдесят три центи"), + (81.25, "вісімдесят одна рупія, двадцять п'ять центів"), + (100.00, "сто рупій, нуль центів"), + (101.11, "сто одна рупія, одинадцять центів"), + (10222, "сто дві рупії, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_SDG = ( + (0.00, "нуль фунтів, нуль піастрів"), + (1.00, "один фунт, нуль піастрів"), + (2.00, "два фунти, нуль піастрів"), + (5.00, "п'ять фунтів, нуль піастрів"), + (11.00, "одинадцять фунтів, нуль піастрів"), + (16.01, "шістнадцять фунтів, один піастр"), + (21.00, "двадцять один фунт, нуль піастрів"), + (37.73, "тридцять сім фунтів, сімдесят три піастри"), + (81.25, "вісімдесят один фунт, двадцять п'ять піастрів"), + (100.00, "сто фунтів, нуль піастрів"), + (101.11, "сто один фунт, одинадцять піастрів"), + (10222, "сто два фунти, двадцять два піастри"), +) + +TEST_CASES_TO_CURRENCY_SEK = ( + (0.00, "нуль крон, нуль ере"), + (1.00, "одна крона, нуль ере"), + (2.00, "дві крони, нуль ере"), + (5.00, "п'ять крон, нуль ере"), + (11.00, "одинадцять крон, нуль ере"), + (16.01, "шістнадцять крон, один ере"), + (21.00, "двадцять одна крона, нуль ере"), + (37.73, "тридцять сім крон, сімдесят три ере"), + (81.25, "вісімдесят одна крона, двадцять п'ять ере"), + (100.00, "сто крон, нуль ере"), + (101.11, "сто одна крона, одинадцять ере"), + (10222, "сто дві крони, двадцять два ере"), +) + +TEST_CASES_TO_CURRENCY_SGD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_SHP = ( + (0.00, "нуль фунтів, нуль пенсів"), + (1.00, "один фунт, нуль пенсів"), + (2.00, "два фунти, нуль пенсів"), + (5.00, "п'ять фунтів, нуль пенсів"), + (11.00, "одинадцять фунтів, нуль пенсів"), + (16.01, "шістнадцять фунтів, один пенс"), + (21.00, "двадцять один фунт, нуль пенсів"), + (37.73, "тридцять сім фунтів, сімдесят три пенси"), + (81.25, "вісімдесят один фунт, двадцять п'ять пенсів"), + (100.00, "сто фунтів, нуль пенсів"), + (101.11, "сто один фунт, одинадцять пенсів"), + (10222, "сто два фунти, двадцять два пенси"), +) + +TEST_CASES_TO_CURRENCY_SLL = ( + (0.00, "нуль леоне, нуль центів"), + (1.00, "один леоне, нуль центів"), + (2.00, "два леоне, нуль центів"), + (5.00, "п'ять леоне, нуль центів"), + (11.00, "одинадцять леоне, нуль центів"), + (16.01, "шістнадцять леоне, один цент"), + (21.00, "двадцять один леоне, нуль центів"), + (37.73, "тридцять сім леоне, сімдесят три центи"), + (81.25, "вісімдесят один леоне, двадцять п'ять центів"), + (100.00, "сто леоне, нуль центів"), + (101.11, "сто один леоне, одинадцять центів"), + (10222, "сто два леоне, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_SOS = ( + (0.00, "нуль шилінгів, нуль центів"), + (1.00, "один шилінг, нуль центів"), + (2.00, "два шилінги, нуль центів"), + (5.00, "п'ять шилінгів, нуль центів"), + (11.00, "одинадцять шилінгів, нуль центів"), + (16.01, "шістнадцять шилінгів, один цент"), + (21.00, "двадцять один шилінг, нуль центів"), + (37.73, "тридцять сім шилінгів, сімдесят три центи"), + (81.25, "вісімдесят один шилінг, двадцять п'ять центів"), + (100.00, "сто шилінгів, нуль центів"), + (101.11, "сто один шилінг, одинадцять центів"), + (10222, "сто два шилінги, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_SRD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_SSP = ( + (0.00, "нуль фунтів, нуль піастрів"), + (1.00, "один фунт, нуль піастрів"), + (2.00, "два фунти, нуль піастрів"), + (5.00, "п'ять фунтів, нуль піастрів"), + (11.00, "одинадцять фунтів, нуль піастрів"), + (16.01, "шістнадцять фунтів, один піастр"), + (21.00, "двадцять один фунт, нуль піастрів"), + (37.73, "тридцять сім фунтів, сімдесят три піастри"), + (81.25, "вісімдесят один фунт, двадцять п'ять піастрів"), + (100.00, "сто фунтів, нуль піастрів"), + (101.11, "сто один фунт, одинадцять піастрів"), + (10222, "сто два фунти, двадцять два піастри"), +) + +TEST_CASES_TO_CURRENCY_STN = ( + (0.00, "нуль добр, нуль сентімо"), + (1.00, "одна добра, нуль сентімо"), + (2.00, "дві добри, нуль сентімо"), + (5.00, "п'ять добр, нуль сентімо"), + (11.00, "одинадцять добр, нуль сентімо"), + (16.01, "шістнадцять добр, один сентімо"), + (21.00, "двадцять одна добра, нуль сентімо"), + (37.73, "тридцять сім добр, сімдесят три сентімо"), + (81.25, "вісімдесят одна добра, двадцять п'ять сентімо"), + (100.00, "сто добр, нуль сентімо"), + (101.11, "сто одна добра, одинадцять сентімо"), + (10222, "сто дві добри, двадцять два сентімо"), +) + +TEST_CASES_TO_CURRENCY_SYP = ( + (0.00, "нуль фунтів, нуль піастрів"), + (1.00, "один фунт, нуль піастрів"), + (2.00, "два фунти, нуль піастрів"), + (5.00, "п'ять фунтів, нуль піастрів"), + (11.00, "одинадцять фунтів, нуль піастрів"), + (16.01, "шістнадцять фунтів, один піастр"), + (21.00, "двадцять один фунт, нуль піастрів"), + (37.73, "тридцять сім фунтів, сімдесят три піастри"), + (81.25, "вісімдесят один фунт, двадцять п'ять піастрів"), + (100.00, "сто фунтів, нуль піастрів"), + (101.11, "сто один фунт, одинадцять піастрів"), + (10222, "сто два фунти, двадцять два піастри"), +) + +TEST_CASES_TO_CURRENCY_SZL = ( + (0.00, "нуль ліланґені, нуль центів"), + (1.00, "один ліланґені, нуль центів"), + (2.00, "два ліланґені, нуль центів"), + (5.00, "п'ять ліланґені, нуль центів"), + (11.00, "одинадцять ліланґені, нуль центів"), + (16.01, "шістнадцять ліланґені, один цент"), + (21.00, "двадцять один ліланґені, нуль центів"), + (37.73, "тридцять сім ліланґені, сімдесят три центи"), + (81.25, "вісімдесят один ліланґені, двадцять п'ять центів"), + (100.00, "сто ліланґені, нуль центів"), + (101.11, "сто один ліланґені, одинадцять центів"), + (10222, "сто два ліланґені, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_THB = ( + (0.00, "нуль батів, нуль сатангів"), + (1.00, "один бат, нуль сатангів"), + (2.00, "два бати, нуль сатангів"), + (5.00, "п'ять батів, нуль сатангів"), + (11.00, "одинадцять батів, нуль сатангів"), + (16.01, "шістнадцять батів, один сатанг"), + (21.00, "двадцять один бат, нуль сатангів"), + (37.73, "тридцять сім батів, сімдесят три сатанги"), + (81.25, "вісімдесят один бат, двадцять п'ять сатангів"), + (100.00, "сто батів, нуль сатангів"), + (101.11, "сто один бат, одинадцять сатангів"), + (10222, "сто два бати, двадцять два сатанги"), +) + +TEST_CASES_TO_CURRENCY_TJS = ( + (0.00, "нуль сомоні, нуль дірамів"), + (1.00, "один сомоні, нуль дірамів"), + (2.00, "два сомоні, нуль дірамів"), + (5.00, "п'ять сомоні, нуль дірамів"), + (11.00, "одинадцять сомоні, нуль дірамів"), + (16.01, "шістнадцять сомоні, один дірам"), + (21.00, "двадцять один сомоні, нуль дірамів"), + (37.73, "тридцять сім сомоні, сімдесят три дірами"), + (81.25, "вісімдесят один сомоні, двадцять п'ять дірамів"), + (100.00, "сто сомоні, нуль дірамів"), + (101.11, "сто один сомоні, одинадцять дірамів"), + (10222, "сто два сомоні, двадцять два дірами"), +) + +TEST_CASES_TO_CURRENCY_TMT = ( + (0.00, "нуль манатів, нуль тенге"), + (1.00, "один манат, нуль тенге"), + (2.00, "два манати, нуль тенге"), + (5.00, "п'ять манатів, нуль тенге"), + (11.00, "одинадцять манатів, нуль тенге"), + (16.01, "шістнадцять манатів, один тенге"), + (21.00, "двадцять один манат, нуль тенге"), + (37.73, "тридцять сім манатів, сімдесят три тенге"), + (81.25, "вісімдесят один манат, двадцять п'ять тенге"), + (100.00, "сто манатів, нуль тенге"), + (101.11, "сто один манат, одинадцять тенге"), + (10222, "сто два манати, двадцять два тенге"), +) + +TEST_CASES_TO_CURRENCY_TND = ( + (0.00, "нуль динарів, нуль міллімів"), + (1.00, "один динар, нуль міллімів"), + (2.00, "два динари, нуль міллімів"), + (5.00, "п'ять динарів, нуль міллімів"), + (11.00, "одинадцять динарів, нуль міллімів"), + (16.01, "шістнадцять динарів, один міллім"), + (21.00, "двадцять один динар, нуль міллімів"), + (37.73, "тридцять сім динарів, сімдесят три мілліми"), + (81.25, "вісімдесят один динар, двадцять п'ять міллімів"), + (100.00, "сто динарів, нуль міллімів"), + (101.11, "сто один динар, одинадцять міллімів"), + (10222, "сто два динари, двадцять два мілліми"), +) + +TEST_CASES_TO_CURRENCY_TOP = ( + (0.00, "нуль паанга, нуль сеніті"), + (1.00, "один паанга, нуль сеніті"), + (2.00, "два паанга, нуль сеніті"), + (5.00, "п'ять паанга, нуль сеніті"), + (11.00, "одинадцять паанга, нуль сеніті"), + (16.01, "шістнадцять паанга, один сеніті"), + (21.00, "двадцять один паанга, нуль сеніті"), + (37.73, "тридцять сім паанга, сімдесят три сеніті"), + (81.25, "вісімдесят один паанга, двадцять п'ять сеніті"), + (100.00, "сто паанга, нуль сеніті"), + (101.11, "сто один паанга, одинадцять сеніті"), + (10222, "сто два паанга, двадцять два сеніті"), +) + +TEST_CASES_TO_CURRENCY_TRY = ( + (0.00, "нуль лір, нуль курушів"), + (1.00, "одна ліра, нуль курушів"), + (2.00, "дві ліри, нуль курушів"), + (5.00, "п'ять лір, нуль курушів"), + (11.00, "одинадцять лір, нуль курушів"), + (16.01, "шістнадцять лір, один куруш"), + (21.00, "двадцять одна ліра, нуль курушів"), + (37.73, "тридцять сім лір, сімдесят три куруші"), + (81.25, "вісімдесят одна ліра, двадцять п'ять курушів"), + (100.00, "сто лір, нуль курушів"), + (101.11, "сто одна ліра, одинадцять курушів"), + (10222, "сто дві ліри, двадцять два куруші"), +) + +TEST_CASES_TO_CURRENCY_TTD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_TWD = ( + (0.00, "нуль нових доларів, нуль центів"), + (1.00, "один новий долар, нуль центів"), + (2.00, "два нові долари, нуль центів"), + (5.00, "п'ять нових доларів, нуль центів"), + (11.00, "одинадцять нових доларів, нуль центів"), + (16.01, "шістнадцять нових доларів, один цент"), + (21.00, "двадцять один новий долар, нуль центів"), + (37.73, "тридцять сім нових доларів, сімдесят три центи"), + (81.25, "вісімдесят один новий долар, двадцять п'ять центів"), + (100.00, "сто нових доларів, нуль центів"), + (101.11, "сто один новий долар, одинадцять центів"), + (10222, "сто два нові долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_TZS = ( + (0.00, "нуль шилінгів, нуль центів"), + (1.00, "один шилінг, нуль центів"), + (2.00, "два шилінги, нуль центів"), + (5.00, "п'ять шилінгів, нуль центів"), + (11.00, "одинадцять шилінгів, нуль центів"), + (16.01, "шістнадцять шилінгів, один цент"), + (21.00, "двадцять один шилінг, нуль центів"), + (37.73, "тридцять сім шилінгів, сімдесят три центи"), + (81.25, "вісімдесят один шилінг, двадцять п'ять центів"), + (100.00, "сто шилінгів, нуль центів"), + (101.11, "сто один шилінг, одинадцять центів"), + (10222, "сто два шилінги, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_UAH = ( + (0.00, "нуль гривень, нуль копійок"), + (1.00, "одна гривня, нуль копійок"), + (2.00, "дві гривні, нуль копійок"), + (5.00, "п'ять гривень, нуль копійок"), + (11.00, "одинадцять гривень, нуль копійок"), + (16.01, "шістнадцять гривень, одна копійка"), + (21.00, "двадцять одна гривня, нуль копійок"), + (37.73, "тридцять сім гривень, сімдесят три копійки"), + (81.25, "вісімдесят одна гривня, двадцять п'ять копійок"), + (100.00, "сто гривень, нуль копійок"), + (101.11, "сто одна гривня, одинадцять копійок"), + (10222, "сто дві гривні, двадцять дві копійки"), +) + +TEST_CASES_TO_CURRENCY_UGX = ( + (0.00, "нуль шилінгів, нуль центів"), + (1.00, "один шилінг, нуль центів"), + (2.00, "два шилінги, нуль центів"), + (5.00, "п'ять шилінгів, нуль центів"), + (11.00, "одинадцять шилінгів, нуль центів"), + (16.01, "шістнадцять шилінгів, один цент"), + (21.00, "двадцять один шилінг, нуль центів"), + (37.73, "тридцять сім шилінгів, сімдесят три центи"), + (81.25, "вісімдесят один шилінг, двадцять п'ять центів"), + (100.00, "сто шилінгів, нуль центів"), + (101.11, "сто один шилінг, одинадцять центів"), + (10222, "сто два шилінги, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_USD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_UYU = ( + (0.00, "нуль песо, нуль сентесімо"), + (1.00, "один песо, нуль сентесімо"), + (2.00, "два песо, нуль сентесімо"), + (5.00, "п'ять песо, нуль сентесімо"), + (11.00, "одинадцять песо, нуль сентесімо"), + (16.01, "шістнадцять песо, один сентесімо"), + (21.00, "двадцять один песо, нуль сентесімо"), + (37.73, "тридцять сім песо, сімдесят три сентесімо"), + (81.25, "вісімдесят один песо, двадцять п'ять сентесімо"), + (100.00, "сто песо, нуль сентесімо"), + (101.11, "сто один песо, одинадцять сентесімо"), + (10222, "сто два песо, двадцять два сентесімо"), +) + +TEST_CASES_TO_CURRENCY_UZS = ( + (0.00, "нуль сумів, нуль тиїнів"), + (1.00, "один сум, нуль тиїнів"), + (2.00, "два суми, нуль тиїнів"), + (5.00, "п'ять сумів, нуль тиїнів"), + (11.00, "одинадцять сумів, нуль тиїнів"), + (16.01, "шістнадцять сумів, один тиїн"), + (21.00, "двадцять один сум, нуль тиїнів"), + (37.73, "тридцять сім сумів, сімдесят три тиїни"), + (81.25, "вісімдесят один сум, двадцять п'ять тиїнів"), + (100.00, "сто сумів, нуль тиїнів"), + (101.11, "сто один сум, одинадцять тиїнів"), + (10222, "сто два суми, двадцять два тиїни"), +) + +TEST_CASES_TO_CURRENCY_VND = ( + (0.00, "нуль донгів, нуль су"), + (1.00, "один донг, нуль су"), + (2.00, "два донги, нуль су"), + (5.00, "п'ять донгів, нуль су"), + (11.00, "одинадцять донгів, нуль су"), + (16.01, "шістнадцять донгів, один су"), + (21.00, "двадцять один донг, нуль су"), + (37.73, "тридцять сім донгів, сімдесят три су"), + (81.25, "вісімдесят один донг, двадцять п'ять су"), + (100.00, "сто донгів, нуль су"), + (101.11, "сто один донг, одинадцять су"), + (10222, "сто два донги, двадцять два су"), +) + +TEST_CASES_TO_CURRENCY_WST = ( + (0.00, "нуль тал, нуль сене"), + (1.00, "одна тала, нуль сене"), + (2.00, "дві тали, нуль сене"), + (5.00, "п'ять тал, нуль сене"), + (11.00, "одинадцять тал, нуль сене"), + (16.01, "шістнадцять тал, один сене"), + (21.00, "двадцять одна тала, нуль сене"), + (37.73, "тридцять сім тал, сімдесят три сене"), + (81.25, "вісімдесят одна тала, двадцять п'ять сене"), + (100.00, "сто тал, нуль сене"), + (101.11, "сто одна тала, одинадцять сене"), + (10222, "сто дві тали, двадцять два сене"), +) + +TEST_CASES_TO_CURRENCY_XCD = ( + (0.00, "нуль доларів, нуль центів"), + (1.00, "один долар, нуль центів"), + (2.00, "два долари, нуль центів"), + (5.00, "п'ять доларів, нуль центів"), + (11.00, "одинадцять доларів, нуль центів"), + (16.01, "шістнадцять доларів, один цент"), + (21.00, "двадцять один долар, нуль центів"), + (37.73, "тридцять сім доларів, сімдесят три центи"), + (81.25, "вісімдесят один долар, двадцять п'ять центів"), + (100.00, "сто доларів, нуль центів"), + (101.11, "сто один долар, одинадцять центів"), + (10222, "сто два долари, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_YER = ( + (0.00, "нуль ріалів, нуль філсів"), + (1.00, "один ріал, нуль філсів"), + (2.00, "два ріали, нуль філсів"), + (5.00, "п'ять ріалів, нуль філсів"), + (11.00, "одинадцять ріалів, нуль філсів"), + (16.01, "шістнадцять ріалів, один філс"), + (21.00, "двадцять один ріал, нуль філсів"), + (37.73, "тридцять сім ріалів, сімдесят три філси"), + (81.25, "вісімдесят один ріал, двадцять п'ять філсів"), + (100.00, "сто ріалів, нуль філсів"), + (101.11, "сто один ріал, одинадцять філсів"), + (10222, "сто два ріали, двадцять два філси"), +) + +TEST_CASES_TO_CURRENCY_ZAR = ( + (0.00, "нуль рандів, нуль центів"), + (1.00, "один ранд, нуль центів"), + (2.00, "два ранди, нуль центів"), + (5.00, "п'ять рандів, нуль центів"), + (11.00, "одинадцять рандів, нуль центів"), + (16.01, "шістнадцять рандів, один цент"), + (21.00, "двадцять один ранд, нуль центів"), + (37.73, "тридцять сім рандів, сімдесят три центи"), + (81.25, "вісімдесят один ранд, двадцять п'ять центів"), + (100.00, "сто рандів, нуль центів"), + (101.11, "сто один ранд, одинадцять центів"), + (10222, "сто два ранди, двадцять два центи"), +) + +TEST_CASES_TO_CURRENCY_ZMW = ( + (0.00, "нуль квач, нуль нгве"), + (1.00, "одна квача, нуль нгве"), + (2.00, "дві квачі, нуль нгве"), + (5.00, "п'ять квач, нуль нгве"), + (11.00, "одинадцять квач, нуль нгве"), + (16.01, "шістнадцять квач, один нгве"), + (21.00, "двадцять одна квача, нуль нгве"), + (37.73, "тридцять сім квач, сімдесят три нгве"), + (81.25, "вісімдесят одна квача, двадцять п'ять нгве"), + (100.00, "сто квач, нуль нгве"), + (101.11, "сто одна квача, одинадцять нгве"), + (10222, "сто дві квачі, двадцять два нгве"), +) + class Num2WordsUKTest(TestCase): + def test_to_cardinal(self): + for test in TEST_CASES_CARDINAL: + self.assertEqual(num2words(test[0], lang='uk'), test[1]) + + def test_to_cardinal_feminine(self): + for test in TEST_CASES_CARDINAL_FEMININE: + word = num2words(test[0], lang='uk', gender='feminine') + self.assertEqual(word, test[1]) + + def test_to_cardinal_nominative(self): + for test in TEST_CASES_CARDINAL: + word = num2words(test[0], lang='uk', case='nominative') + self.assertEqual(word, test[1]) + + def test_to_cardinal_genitive(self): + for test in TEST_CASES_CARDINAL_GENITIVE: + word = num2words(test[0], lang='uk', case='genitive') + self.assertEqual(word, test[1]) + + def test_to_cardinal_dative(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_DATIVE: + word = num2words(test[0], lang='uk', case='dative') + self.assertEqual(word, test[1]) + + def test_to_cardinal_accusative(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_ACCUSATIVE: + word = num2words(test[0], lang='uk', case='accusative') + self.assertEqual(word, test[1]) + + def test_to_cardinal_instrumental(self): + self.maxDiff = None + for test in TEST_CASES_CARDINAL_INSTRUMENTAL: + word = num2words(test[0], lang='uk', case='instrumental') + self.assertEqual(word, test[1]) + + def test_to_cardinal_locative(self): self.maxDiff = None - self.assertEqual(num2words(100, lang='uk'), 'сто') - # self.assertEqual(num2words(101, lang='uk'), 'сто один') - self.assertEqual(num2words(110, lang='uk'), 'сто десять') - self.assertEqual(num2words(115, lang='uk'), "сто п'ятнадцять") - self.assertEqual(num2words(123, lang='uk'), 'сто двадцять три') - self.assertEqual(num2words(1000, lang='uk'), 'одна тисяча') - # self.assertEqual(num2words(1001, lang='uk'), 'одна тисяча один') - self.assertEqual(num2words(2012, lang='uk'), 'двi тисячi дванадцять') - self.assertEqual( - num2words(12519.85, lang='uk'), - "дванадцять тисяч п'ятсот дев'ятнадцять кома вiсiмдесят п'ять") - # self.assertEqual( - # num2words(1234567890, lang='uk'), - # "мiльярд двiстi тридцать чотири мiльйона п'ятсот шiстдесят сiмь " - # "тисяч вiсiмсот дев'яносто") - # self.assertEqual( - # num2words(215461407892039002157189883901676, lang='uk'), - # "двiстi п'ятнадцять нонiльйонiв чотириста шiстдесят один " - # "октильйон чотириста сiм септильйонiв вiсiмсот дев'яносто " - # "два секстильйони тридцять дев'ять квiнтильйонiв два " - # "квадрильйони сто п'ятдесят сiм трильйонiв сто вiсiмдесят " - # "дев'ять мiльярдiв вiсiмсот вiсiмдесят три мiльйона " - # "дев'ятсот одна тисяча шiстсот " - # "сiмдесят шiсть") - # self.assertEqual( - # num2words(719094234693663034822824384220291, lang='uk'), - # "сiмсот дев'ятнадцять нонiльйонiв дев'яносто чотири октильйони " - # "двiстi тридцять чотири септильйони шiстсот дев'яносто три " - # "секстильйони шiстсот шiстдесят три квiнтильйони тридцять " - # "чотири квадрильйони вiсiмсот двадцять два трильйони вiсiмсот " - # "двадцять чотири мiльярди триста вiсiмдесят чотири мiльйона " - # "двiстi двадцять тисяч двiстi дев'яносто один") - - def test_and_join_199(self): - self.assertEqual(num2words(187, lang='uk'), "сто вiсiмдесят сiм") - - def test_cardinal_for_float_number(self): - self.assertEqual( - num2words(12.40, lang='uk'), "дванадцять кома чотири" - ) - self.assertEqual( - num2words(17.31, lang='uk'), "сiмнадцять кома тридцять одна" - ) - self.assertEqual( - num2words(14.13, lang='uk'), "чотирнадцять кома тринадцять" - ) - self.assertEqual( - num2words(12.31, lang='uk'), "дванадцять кома тридцять одна" - ) + for test in TEST_CASES_CARDINAL_LOCATIVE: + word = num2words(test[0], lang='uk', case='locative') + self.assertEqual(word, test[1]) def test_to_ordinal(self): - # @TODO: implement to_ordinal - with self.assertRaises(NotImplementedError): - num2words(1, lang='uk', to='ordinal') + for test in TEST_CASES_ORDINAL: + self.assertEqual( + num2words(test[0], lang='uk', to='ordinal'), + test[1] + ) def test_to_currency(self): - # self.assertEqual( - # num2words(1.0, lang='uk', to='currency', currency='EUR'), - # "один євро, нуль центiв" - # ) - self.assertEqual( - num2words(1.0, lang='uk', to='currency', currency='UAH'), - "одна гривня, нуль копiйок" - ) - self.assertEqual( - num2words(1234.56, lang='uk', to='currency', currency='EUR'), - "одна тисяча двiстi тридцять чотири євро, п'ятдесят шiсть центiв" - ) - self.assertEqual( - num2words(1234.56, lang='uk', to='currency', currency='UAH'), - "одна тисяча двiстi тридцять чотири гривнi, п'ятдесят шiсть " - "копiйок" - ) - # self.assertEqual( - # num2words(10111, lang='uk', to='currency', currency='EUR', - # seperator=u' та'), - # "сто один євро та одинадцять центiв" - # ) - self.assertEqual( - num2words(10121, lang='uk', to='currency', currency='UAH', - seperator=u' та'), - "сто одна гривня та двадцять одна копiйка" - ) - self.assertEqual( - num2words(10121, lang='uk', to='currency', currency='UAH', - seperator=u' та'), - "сто одна гривня та двадцять одна копiйка" - ) - self.assertEqual( - num2words(10122, lang='uk', to='currency', currency='UAH', - seperator=u' та'), - "сто одна гривня та двадцять двi копiйки" - ) - # self.assertEqual( - # num2words(10121, lang='uk', to='currency', currency='EUR', - # seperator=u' та'), - # "сто один євро та двадцять один цент" - # ) - self.assertEqual( - num2words(-1251985, lang='uk', to='currency', currency='EUR', - cents=False), - "мiнус дванадцять тисяч п'ятсот дев'ятнадцять євро, 85 центiв" - ) - self.assertEqual( - num2words('38.4', lang='uk', to='currency', seperator=' и', - cents=False, currency='EUR'), - "тридцять вiсiм євро и 40 центiв" - ) + for test in TEST_CASES_TO_CURRENCY_AED: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AED"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_AFN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AFN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ALL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ALL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_AMD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AMD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ANG: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ANG"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_AOA: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AOA"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ARS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ARS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_AUD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AUD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_AWG: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AWG"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_AZN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="AZN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BAM: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BAM"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BBD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BBD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BDT: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BDT"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BGN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BGN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BHD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BHD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BIF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BIF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BMD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BMD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BND: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BND"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BOB: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BOB"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BRL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BRL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BSD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BSD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BTN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BTN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BWP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BWP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BYN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BYN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_BZD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="BZD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CAD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CAD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CDF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CDF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CHF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CHF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CLP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CLP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CNY: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CNY"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_COP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="COP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CRC: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CRC"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CUC: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CUC"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CUP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CUP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CVE: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CVE"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_CZK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="CZK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_DJF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="DJF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_DKK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="DKK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_DOP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="DOP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_DZD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="DZD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_EGP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="EGP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ERN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ERN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ETB: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ETB"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_EUR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="EUR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_FJD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="FJD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_FKP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="FKP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GBP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GBP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GEL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GEL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GHS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GHS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GIP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GIP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GMD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GMD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GNF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GNF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GTQ: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GTQ"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_GYD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="GYD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_HKD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="HKD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_HNL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="HNL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_HRK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="HRK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_HTG: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="HTG"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_HUF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="HUF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_IDR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="IDR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ILS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ILS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_INR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="INR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_IQD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="IQD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_IRR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="IRR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ISK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ISK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_JMD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="JMD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_JOD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="JOD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_JPY: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="JPY"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KES: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KES"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KGS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KGS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KHR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KHR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KMF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KMF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KPW: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KPW"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KRW: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KRW"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KWD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KWD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KYD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KYD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_KZT: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="KZT"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_LAK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="LAK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_LBP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="LBP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_LKR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="LKR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_LRD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="LRD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_LSL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="LSL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_LYD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="LYD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MAD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MAD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MDL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MDL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MGA: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MGA"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MKD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MKD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MMK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MMK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MNT: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MNT"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MOP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MOP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MRU: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MRU"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MUR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MUR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MVR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MVR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MWK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MWK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MXN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MXN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MYR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MYR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_MZN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="MZN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_NAD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="NAD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_NGN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="NGN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_NIO: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="NIO"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_NOK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="NOK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_NPR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="NPR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_NZD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="NZD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_OMR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="OMR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PAB: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PAB"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PEN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PEN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PGK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PGK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PHP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PHP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PKR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PKR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PLN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PLN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_PYG: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="PYG"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_QAR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="QAR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_RON: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="RON"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_RSD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="RSD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_RUB: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="RUB"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_RWF: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="RWF"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SAR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SAR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SBD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SBD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SCR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SCR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SDG: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SDG"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SEK: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SEK"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SGD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SGD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SHP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SHP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SLL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SLL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SOS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SOS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SRD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SRD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SSP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SSP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_STN: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="STN"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SYP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SYP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_SZL: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="SZL"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_THB: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="THB"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TJS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TJS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TMT: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TMT"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TND: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TND"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TOP: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TOP"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TRY: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TRY"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TTD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TTD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TWD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TWD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_TZS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="TZS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_UAH: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="UAH"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_UGX: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="UGX"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_USD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="USD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_UYU: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="UYU"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_UZS: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="UZS"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_VND: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="VND"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_WST: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="WST"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_XCD: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="XCD"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_YER: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="YER"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ZAR: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ZAR"), + test[1] + ) + for test in TEST_CASES_TO_CURRENCY_ZMW: + self.assertEqual( + num2words(test[0], lang='uk', to='currency', + currency="ZMW"), + test[1] + ) diff --git a/tox.ini b/tox.ini index 34ff065f..63e88f3a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,18 @@ [tox] -envlist = flake8,isort,py27,py34,py35,py36,py37 +envlist = py37,py38,py39,py310,py311,py312,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 + [testenv] -passenv = TRAVIS TRAVIS_* +passenv = GITHUB_* deps = coverage delegator.py @@ -14,7 +24,7 @@ commands = [testenv:flake8] changedir = {toxinidir} deps = - flake8 + flake8==5.0.4 flake8-copyright commands = flake8 @@ -25,4 +35,4 @@ deps = isort delegator.py commands = - isort --check-only --recursive --diff num2words tests + isort --check-only --float-to-top --diff num2words tests